// ------------------------------- // // -------- 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: 08/22/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 test program is used to store multiple B-trees in a single index file. */ // ----------------------------------------------------------- // #include <iostream.h> #include "gxdstats.h" #include "gxbtree.h" const BtreeNodeOrder_t MyKeyClassOrder = 7; const __WORD__ MyKeyNameSize = 64; 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) { strncpy(key_name, name, MyKeyNameSize); key_name[ MyKeyNameSize-1] = 0; // Ensure null termination } void MyKeyClass::operator=(const char *name) { strncpy(key_name, name, MyKeyNameSize); key_name[ MyKeyNameSize-1] = 0; // Ensure null termination } 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); } const int NKEYS = 26; const char *keys1[NKEYS] = { "DOG", "CAT", "FISH", "MOUSE", "BIRD", "PIG", "HORSE", "LION", "SNAKE", "COW", "ARMADILLO", "GROUPER", "RAT", "MONKEY", "ZEBRA", "STARFISH", "LIZARD", "CRAB", "SNAIL", "GORILLA", "LOBSTER", "TURKEY", "BEETLE", "SHARK", "CLAM", "OYSTER" }; const char *keys2[NKEYS] = { "FLEA", "BUTTERFLY", "SPARROW", "GOLDFISH", "TIGER", "BEAR", "TROUTE", "MOOSE", "DEAR", "SALMON", "TUNA", "GAZELLE", "SLOTH", "SPIDER", "LEAPORD", "GIRAFFE", "MUSTANG", "CONDOR", "KANGAROO", "SKUNK", "FOX", "PANTER", "CHEETAH", "TOUCAN", "PARROT", "BUFFALO" }; const char *keys3[NKEYS] = { "KOALA", "HORSEFLY", "ANACONDA", "CROCODILE", "RACCOON", "ALLIGATOR", "RABBIT", "WHALE", "ANT", "CRANE", "LONGHORN", "CANARY", "WOMBAT", "WOLFHOUND", "COUGAR", "BAT", "OWL", "SHRIMP", "SCALLOP", "SQUID", "PYTHON", "SARDINE", "TAPIR", "ELEPHANT", "EEL", "RHINOCEROS" }; const char *keys4[NKEYS] = { "LAMB", "BISON", "GRASSHOPPER", "MACKEREL", "FERRET", "WASP", "CATERPILLAR", "MILLIPEDE", "CENTIPEDE", "MOSQUITO", "POSSUM", "DUCK", "WEASEL", "CARIBOU", "ANTELOPE", "SALAMANDER", "NEWT", "CHICKEN", "BULL", "COBRA", "CHIMPANZEE", "URCHIN", "CROW", "WOLF", "SPONGE", "JELLYFISH" }; void PausePrg() { cout << endl; cout << "Press enter to continue..." << endl; cin.get(); } void BtreeStatus(gxBtree &btx) { cout << endl; cout << "Root address = " << btx.Root() << endl; cout << "Number of entries = " << btx.NumKeys() << endl; cout << "Number of nodes = " << btx.NumNodes() << endl; cout << "Btree order = " << btx.NodeOrder() << endl; cout << "Btree height = " << btx.BtreeHeight() << endl; PausePrg(); } void BuildTree(gxBtree &btx, const char *keys[NKEYS]) { MyKeyClass key; MyKeyClass compare_key; int i, rv; const int INSERTIONS = NKEYS; // Inserting the keys for(i = 0; i < INSERTIONS; i++) { key = keys[i]; rv = btx.Insert(key, compare_key); if(rv != 1) { cout << endl << "Problem adding " << keys[i] << " - " << i << endl; return; } } // "Verifying the insertions for(i = 0; i < INSERTIONS; i++) { key = keys[i]; rv = btx.Find(key, compare_key); if(rv != 1) { cout << "Error finding key " << keys[i] << " - " << i << endl; return; } } // "Deleting all the entries for(i = 0; i < INSERTIONS; i++) { key = keys[i]; rv = btx.Delete(key, compare_key); if(rv != 1) { cout << "Error deleting key " << keys[i] << " - " << i << endl; return; } // Verify the remaining key locations for(int j = INSERTIONS-1; j != i; j--) { key = keys[j]; rv = btx.Find(key, compare_key); if(rv != 1) { cout << "Error finding key " << keys[j] << " - " << j << endl; cout << "After deleting key " << keys[i] << " - " << i << endl; return; } } } // Re-inserting all the keys for(i = 0; i < INSERTIONS; i++) { key = keys[i]; rv = btx.Insert(key, compare_key); if(rv != 1) { cout << endl << "Problem adding " << keys[i] << " - " << i << endl; return; } } BtreeStatus(btx); } int main() { const char *fname = "testfile.btx"; int num_trees = 4; MyKeyClass key, compare_key; gxBtree btx1(key, MyKeyClassOrder); gxBtree btx2(key, MyKeyClassOrder); gxBtree btx3(key, MyKeyClassOrder); gxBtree btx4(key, MyKeyClassOrder); // Create a new Btree index file with room for multiple Btrees gxDatabase *index_file = new gxDatabase; FAU static_size = \ (FAU)(index_file->FileHeaderSize() * num_trees); index_file->Create(fname, static_size); if(CheckError(index_file) != 0) return 1; btx1.InitBtree(index_file, 1, (FAU)index_file->FileHeaderSize()); btx2.InitBtree(index_file, 1, (FAU)(index_file->FileHeaderSize() * 2)); btx3.InitBtree(index_file, 1, (FAU)(index_file->FileHeaderSize() * 3)); btx4.InitBtree(index_file, 1, (FAU)(index_file->FileHeaderSize() * 4)); cout << "Building the tree number 1..." << endl; BuildTree(btx1, keys1); cout << "Building the tree number 2..." << endl; BuildTree(btx2, keys2); cout << "Building the tree number 3..." << endl; BuildTree(btx3, keys3); cout << "Building the tree number 4..." << endl; BuildTree(btx4, keys4); cout << "Walking through the tree number 1 in sort order" << endl; PausePrg(); // Walk through the tree starting at the first node if(btx1.FindFirst(key)) { cout << key.key_name << ' '; while(btx1.FindNext(key, compare_key)) cout << key.key_name << ' '; } cout << endl << endl; cout << "Walking through the tree number 2 in sort order" << endl; PausePrg(); // Walk through the tree starting at the first node if(btx2.FindFirst(key)) { cout << key.key_name << ' '; while(btx2.FindNext(key, compare_key)) cout << key.key_name << ' '; } cout << endl << endl; cout << "Walking through the tree number 3 in sort order" << endl; PausePrg(); // Walk through the tree starting at the first node if(btx3.FindFirst(key)) { cout << key.key_name << ' '; while(btx3.FindNext(key, compare_key)) cout << key.key_name << ' '; } cout << endl << endl; cout << "Walking through the tree number 4 in sort order" << endl; PausePrg(); // Walk through the tree starting at the first node if(btx4.FindFirst(key)) { cout << key.key_name << ' '; while(btx4.FindNext(key, compare_key)) cout << key.key_name << ' '; } // Relase all references to the open file pointer. NOTE: If the file // pointer is not released, with more then one object referencing it, // the gxBtree destructor will automatically delete the file pointer // before any other object or entity referencing it has complete its // cleanup operations. btx1.Release(); btx2.Release(); btx3.Release(); btx4.Release(); // Delete the open file pointer delete index_file; // Database engine closed by destructor call cout << endl << endl; cout << "Exiting..." << endl; return 0; } // ----------------------------------------------------------- // // ------------------------------- // // --------- End of File --------- // // ------------------------------- //