9.2 例

この例では、文字列と、誕生日を表わす RWDate へのオフセットを、キーと値のペアとして格納します。名前を指定すると、ディスクから誕生日を読み出すことができます。

#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;
}

次に、コードの説明を行ごとに示します。

//1
B ツリーを生成します。デフォルトのコンストラクタが使用され、キーの長さが 16
文字に設定されます。
//2
標準入力から名前を読み取ります。このループは EOF に到達すると終了します。
//3
対応する誕生日を読み取ります。
//4
RWFileManager から誕生日を格納するために十分な領域を割り当てます。binaryStoreSize() 関数は、ほとんどの Rogue Wave クラスでメンバ関数になっています。RWFile にオブジェクトを格納するために必要なバイト数を返します。RWCollection 全体を格納する場合、かメソッド recursiveSaveOn() または operator<<(RWFile&, RWCollectable) のいずれかを使用する場合は、代わりに必ず recursiveStoreSize() を使用してください。
//5
RWDate を格納する場所を見つけます。
//6
ほとんどの Rogue Wave クラスには、多重定義されたバージョンの左右シフト演算子
(<< および >>) があります。
//7
キーとB ツリーのオブジェクトへのオフセットを挿入します。

次に、ファイルに名前と誕生日を格納したあと、それを読み出す方法を示します。

#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;
}

次にプログラムの説明を示します。

//1
このプログラムはEOF に到達するまで名前を要求します。
//2
名前を RWBTreeOnDisk へのキーとして使用し、それに関連付けられている値、つまりファイルでのオフセットを返します。
//3
名前が見つかったかどうかを調べます。
//4
名前が有効な場合は、// 2 で得られた値を使って、関連付けられている誕生日が格納されている位置を見つけます。
//5
ファイルから誕生日を読み取ります。
//6
それを表示します。

わずかの変更で、同じファイルで複数の B
ツリーをアクティブにすることができます。これにより、複数のキーでインデックスを保持することができます。次に、同じファイルで
B ツリーを 3 つ作成する方法を示します。

#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;
}

次に、3 つの B ツリーを開く方法を示します。

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

main(){
    RWoffset rootArray[3];           // ツリールートの場所
    RWBTreeOnDisk* treeArray[3]; // RWBTreeOnDisks へのポインタ

   RWFileManager fm("index.dat");
   fm.SeekTo(fm.start());      // ルートノードの位置を読み取る
   fm.Read(rootArray, 3);

   for (int itree=0; itree<3; itree++)
   {
      // 3 つのツリーを初期化する:
      treeArray[itree] = new RWBTreeOnDisk(fm,
                       10,          // キャッシュする最大ノード数
        RWBTreeOnDisk::autoCreate,  // 古いツリーを読み取る
                       16,          // キーの長さ
                       FALSE,       // ヌルを無視しない
                       rootArray[itree] // ルートの位置
                                           );
   }

   .
   .
   .
   for (itree=0; itree<3; itree++)  // 空きヒープメモリ
      delete treeArray[itree];

   return 0; }

この記事の投稿者: επιστημη