// ------------------------------- // // -------- Start of File -------- // // ------------------------------- // // ----------------------------------------------------------- // // C++ Source Code File Name: testprog.cpp // Compiler Used: MSVC, BCC32, GCC, HPUX aCC, SOLARIS CC // Produced By: DataReel Software Development Team // File Creation Date: 08/22/2000 // Date Last Modified: 06/17/2016 // Copyright (c) 2001-2024 DataReel Software Development // ----------------------------------------------------------- // // ------------- 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 B-tree node class. */ // ----------------------------------------------------------- // #include "gxdlcode.h" #if defined (__USE_ANSI_CPP__) // Use the ANSI Standard C++ library #include <iostream> using namespace std; // Use unqualified names for Standard C++ library #else // Use the old iostream library by default #include <iostream.h> #endif // __USE_ANSI_CPP__ #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; // NOTE: This comparison function is only used if the // __USE_SINGLE_COMPARE__ preprocessor directive is // defined when the program is compiled. int CompareKey(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); } int MyKeyClass::CompareKey(const DatabaseKeyB& key) const // NOTE: This comparison function is only used if the // __USE_SINGLE_COMPARE__ preprocessor directive is // defined when the program is compiled. { const MyKeyClass *kptr = (const MyKeyClass *)(&key); return strcmp(key_name, (char *)kptr->db_key); } 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 << ' ' << (long)kbuf.right_child << ' '; // NOTE: The right child FAU is cast to a long for compilers // with native 64-bit int ostream overloads } cout << "\n"; cout << "Key count = " << n.key_count << "\n"; cout << "Left child = " << (long)n.left_child << "\n"; // NOTE: The left child FAU is cast to a long for compilers // with native 64-bit int ostream overloads } void PausePrg() // Pause the program. { cout << "\n"; cout << "Press enter to continue..." << "\n"; cin.get(); } gxDatabaseError WriteNode(gxDatabase *f, const BtreeNode &n, FAU_t 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_t 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 B-tree Node Statistics ---------" << "\n"; cout << "Key name size = " << key.KeySize() << "\n"; cout << "Database key size = " << key.SizeOfDatabaseKey() << "\n"; cout << "Key entry size = " << (key.SizeOfDatabaseKey() * (MyKeyClassOrder-1)) << "\n"; BtreeNode n(key.SizeOfDatabaseKey(), MyKeyClassOrder); cout << "B-tree order = " << n.node_order << "\n"; cout << "B-tree node size = " << n.SizeOfBtreeNode() << "\n"; 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" << "\n"; 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" << "\n"; PrintNode(n); PausePrg(); cout << "Testing database read/write operations" << "\n"; gxDatabase *f = new gxDatabase(); f->Create("testfile.gxd"); FAU_t 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" << "\n"; n.DeleteDatabaseKey((BtreeKeyLocation_t)0); PrintNode(n); PausePrg(); cout << "Testing the split fucntion" << "\n"; BtreeNode r(key.SizeOfDatabaseKey(), MyKeyClassOrder); n.SplitNode(r, n.node_order/2); PrintNode(n); cout << "\n"; PrintNode(r); cout << "\n"; cout << "Exiting..." << "\n"; return 0; } // ----------------------------------------------------------- // // ------------------------------- // // --------- End of File --------- // // ------------------------------- //