Rogue Wave banner
Previous fileTop of documentContentsIndexNext file

9.2 Example

In this example, key-value pairs of character strings and offsets to RWDates representing birthdays are stored. Given a name, you can retrieve a birthdate from disk.

#include <rw/disktree.h>
#include <rw/filemgr.h>
#include <rw/cstring.h>
#include <rw/rwdate.h>
#include <rw/rstream.h>

main(){
   RWCString name;
   RWDate birthday;

   RWFileManager fm("birthday.dat");
   RWBTreeOnDisk btree(fm);                                  // 1

   while (cin >> name)                                       // 2
   {
     cin >> birthday;                                        // 3
     RWoffset loc =  fm.allocate(birthday.binaryStoreSize());// 4
     fm.SeekTo(loc);                                         // 5
     fm << birthday;                                         // 6
     btree.insertKeyAndValue(name, loc);                     // 7
   }
   return 0;
}

Here's the line-by-line description:

//1Construct a B-tree. The default constructor is used, resulting in a key length of 16 characters.
//2Read the name from standard input. This loop will exit when EOF is reached.
//3Read the corresponding birthday.
//4Allocate enough space from the RWFileManager to store the birthday. Function binaryStoreSize() is a member function in most Rogue Wave classes. It returns the number of bytes necessary to store an object in an RWFile. If you are storing an entire RWCollection, or using one of the methods recursiveSaveOn() or operator<<(RWFile&, RWCollectable), be sure to use recursiveStoreSize() instead.
//5Seek to the location where the RWDate will be stored.
//6Store the date at that location. Most Rogue Wave classes have an overloaded version of the streaming operators << and >>.
//7Insert the key and offset to the object in the B-tree.

Having stored the names and birthdates on a file, here's how you might retrieve them:

#include <rw/disktree.h>
#include <rw/filemgr.h>
#include <rw/cstring.h>
#include <rw/rwdate.h>
#include <rw/rstream.h>

main(){
   RWCString name;
   RWDate birthday;

   RWFileManager fm("birthday.dat");
   RWBTreeOnDisk btree(fm);

   while(1)
   {
     cout << "Give name: ";
     if (!( cin >> name)) break;                             // 1
     RWoffset loc = btree.findValue(name);                   // 2
     if (loc==RWNIL)                                         // 3
       cerr << "Not found.\n";
     else
     {
       fm.SeekTo(loc);                                       // 4
       fm >> birthday;                                       // 5
       cout << "Birthday is " << birthday << endl;           // 6
     }
   }
   return 0;
}

Here is a description of the program:

//1The program accepts names until encountering an EOF.
//2The name is used as a key to RWBTreeOnDisk, which returns the associated value, an offset, into the file.
//3Check to see whether the name was found.
//4If the name is valid, use the value to seek to the spot where the associated birthdate is stored.
//5Read the birthdate from the file.
//6Print it out.

With a little effort, you can easily have more than one B-tree active in the same file. This allows you to maintain indexes on more than one key. Here's how you would create three B-trees in the same file:

#include <rw/disktree.h>
#include <rw/filemgr.h>

main(){
   RWoffset rootArray[3];

   RWFileManager fm("index.dat");
   RWoffset rootArrayOffset =     fm.allocate(sizeof(rootArray));

   for (int itree=0; itree<3; itree++)
   {
     RWBTreeOnDisk btree(fm, 10, RWBTreeOnDisk::create);
     rootArray[itree] = btree.baseLocation();
   }
   fm.SeekTo(fm.start());
   fm.Write(rootArray, 3);
   return 0;
}

And here is how you could open the three B-trees:

#include <rw/disktree.h>
#include <rw/filemgr.h>

main(){
   RWoffset rootArray[3];           // Location of the tree roots
   RWBTreeOnDisk* treeArray[3]; // Pointers to the RWBTreeOnDisks

   RWFileManager fm("index.dat");
   fm.SeekTo(fm.start());      // Recover locations of root nodes
   fm.Read(rootArray, 3);
   
   for (int itree=0; itree<3; itree++)
   {
     // Initialize the three trees:
     treeArray[itree] = new RWBTreeOnDisk(fm,
                      10,          // Max. nodes cached
       RWBTreeOnDisk::autoCreate,  // Will read old tree
                      16,          // Key length
                      FALSE,       // Do not ignore nulls
                      rootArray[itree] // Location of root
                                          );
   }

   .
   .
   .
   for (itree=0; itree<3; itree++)  // Free heap memory
      delete treeArray[itree];

   return 0;
}



Previous fileTop of documentContentsIndexNext file
©Copyright 1999, Rogue Wave Software, Inc.
Send mail to report errors or comment on the documentation.