// ------------------------------- //
// -------- Start of File -------- //
// ------------------------------- //
// ----------------------------------------------------------- //
// C++ Source Code File Name: testprog.cpp
// Compiler Used: MSVC, BCC32, GCC, HPUX aCC, SOLARIS CC
// Produced By: glNET Software
// File Creation Date: 08/22/2000
// Date Last Modified: 05/25/2001
// Copyright (c) 2001 glNET Software
// ----------------------------------------------------------- //
// ------------- Program Description and Details ------------- //
// ----------------------------------------------------------- //
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA
This is a test program for the Btree node class.
*/
// ----------------------------------------------------------- //
#include <iostream.h>
#include "btnode.h"
#include "gxdbase.h"
// Set the node order and maximum key size for this key class
const BtreeNodeOrder_t MyKeyClassOrder = 8;
const __WORD__ MyKeyNameSize = 26;
// Key class for this database
class MyKeyClass : public DatabaseKeyB
{
public:
MyKeyClass();
MyKeyClass(const char *name);
void operator=(const char *name);
~MyKeyClass() { }
public: // Base class interface
size_t KeySize() { return sizeof(key_name); }
int operator==(const DatabaseKeyB& key) const;
int operator>(const DatabaseKeyB& key) const;
public: // Persistent data member
char key_name[MyKeyNameSize];
};
MyKeyClass::MyKeyClass() : DatabaseKeyB((char *)key_name)
{
for(int i = 0; i < MyKeyNameSize; i++) key_name[i] = 0;
}
MyKeyClass::MyKeyClass(const char *name) : DatabaseKeyB((char *)key_name)
{
for(int i = 0; i < MyKeyNameSize; i++) key_name[i] = 0;
strcpy(key_name, name);
}
void MyKeyClass::operator=(const char *name)
{
for(int i = 0; i < MyKeyNameSize; i++) key_name[i] = 0;
strcpy(key_name, name);
}
int MyKeyClass::operator==(const DatabaseKeyB& key) const
{
const MyKeyClass *kptr = (const MyKeyClass *)(&key);
return (strcmp(key_name, (char *)kptr->db_key) == 0);
}
int MyKeyClass::operator>(const DatabaseKeyB& key) const
{
const MyKeyClass *kptr = (const MyKeyClass *)(&key);
return (strcmp(key_name, (char *)kptr->db_key) > 0);
}
void PrintNode(BtreeNode &n)
// Print a Btree node.
{
MyKeyClass kbuf;
BtreeKeyLocation_t key_location = (BtreeKeyLocation_t)0;
for(BtreeKeyCount_t i = (BtreeKeyCount_t)0; i < n.key_count; i++) {
n.LoadKey(kbuf, key_location++);
cout << (char *)kbuf.key_name << ' ' << kbuf.right_child << ' ';
}
cout << endl;
cout << "Key count = " << n.key_count << endl;
cout << "Left child = " << n.left_child << endl;
}
void PausePrg()
// Pause the program.
{
cout << endl;
cout << "Press enter to continue..." << endl;
cin.get();
}
gxDatabaseError WriteNode(gxDatabase *f, const BtreeNode &n, FAU na)
// Function used to write a Btree node to an open database file.
// Returns zero if successful or a non-zero value to indicate a
// failure.
{
gxDatabaseError rv;
rv = f->Write(&n.key_count, sizeof(n.key_count), na);
if(rv != gxDBASE_NO_ERROR) return rv;
rv = f->Write(&n.left_child, sizeof(n.left_child));
if(rv != gxDBASE_NO_ERROR) return rv;
rv = f->Write(n.key_entries, (n.key_size * n.node_order));
if(rv != gxDBASE_NO_ERROR) return rv;
return rv;
}
gxDatabaseError ReadNode(gxDatabase *f, BtreeNode &n, FAU na)
// Function used to read a Btree node from an open database file.
// Returns zero if successful or a non-zero value to indicate a
// failure.
{
gxDatabaseError rv;
rv = f->Read(&n.key_count, sizeof(n.key_count), na);
if(rv != gxDBASE_NO_ERROR) return rv;
rv = f->Read(&n.left_child, sizeof(n.left_child));
if(rv != gxDBASE_NO_ERROR) return rv;
rv = f->Read(n.key_entries, (n.key_size * n.node_order));
if(rv != gxDBASE_NO_ERROR) return rv;
return rv;
}
int main()
{
MyKeyClass key, compare_key;
cout << "--------- Key and Btree Node Statistics ---------" << endl;
cout << "Key name size = " << key.KeySize() << endl;
cout << "Database key size = " << key.SizeOfDatabaseKey() << endl;
cout << "Key entry size = "
<< (key.SizeOfDatabaseKey() * (MyKeyClassOrder-1)) << endl;
BtreeNode n(key.SizeOfDatabaseKey(), MyKeyClassOrder);
cout << "Btree order = " << n.node_order << endl;
cout << "Btree node size = " << n.SizeOfBtreeNode() << endl;
PausePrg();
BtreeKeyLocation_t key_location = (BtreeKeyLocation_t)0;
int i, rv;
const char *strings[7] = { // Array matching the Btree order
"DOG", "CAT", "PIG", "COW", "FISH", "ZEBRA", "HORSE"
};
cout << "Inserting " << n.node_order << " entries into the Btree node"
<< endl;
for(i = 0; i < n.node_order; i++) {
key = strings[i];
rv = n.FindKeyLocation(key, compare_key, key_location);
// Do not insert duplicate keys
if(rv != 0) {
key_location++;
n.InsertDatabaseKey(key, key_location);
}
}
cout << "Reading back the database keys" << endl;
PrintNode(n);
PausePrg();
cout << "Testing database read/write operations" << endl;
gxDatabase *f = new gxDatabase();
f->Create("testfile.gxd");
FAU node_address = f->Alloc(n.SizeOfBtreeNode());
WriteNode(f, n, node_address);
BtreeNode nbuf(key.SizeOfDatabaseKey(), MyKeyClassOrder);
ReadNode(f, nbuf, node_address);
PrintNode(nbuf);
delete f;
PausePrg();
cout << "Testing the delete function" << endl;
n.DeleteDatabaseKey((BtreeKeyLocation_t)0);
PrintNode(n);
PausePrg();
cout << "Testing the split fucntion" << endl;
BtreeNode r(key.SizeOfDatabaseKey(), MyKeyClassOrder);
n.SplitNode(r, n.node_order/2);
PrintNode(n);
cout << endl;
PrintNode(r);
cout << endl;
cout << "Exiting..." << endl;
return 0;
}
// ----------------------------------------------------------- //
// ------------------------------- //
// --------- End of File --------- //
// ------------------------------- //