(57)【要約】【課題】インデックスキーの長さが、予め決められていなくてもよく、長くても記憶領域の利用効率が良いようにする。【解決手段】カップルドノードツリーはルートノードと、隣接した記憶領域に配置されるブランチノードとリーフノードまたはブランチノード同士またはリーフノード同士のノード対からなる。ブランチノードは、ビット列検索を行う検索キーの弁別ビット位置とリンク先のノード対の一方のノードである代表ノードの位置を示す第一の位置情報を含み、リーフノードは、検索対象のビット列からなるインデックスキーを格納した記憶領域の位置を示す第二の位置情報を含む。検索は、ブランチノードにおいて該ブランチノードに含まれる弁別ビット位置の検索キーのビット値に応じてリンク先のノード対の代表ノードかもう一方のノードにリンクすることを順次リーフノードに至るまで繰り返すことにより行われる。【選択図】図１
2008269503.tif 000002
【特許請求の範囲】
【請求項１】
ルートノードと、隣接した記憶領域に配置されるブランチノードとリーフノードまたはブランチノード同士またはリーフノード同士のノード対、からなるビット列検索に用いるツリーであって、
前記ルートノードは、ツリーの始点を表すノードであって、該ツリーのノードが１つのときは前記リーフノード、ツリーのノードが２つ以上のときは前記ブランチノードであり、
前記ブランチノードは、ビット列検索を行う検索キーの弁別ビット位置とリンク先のノード対の一方のノードである代表ノードの位置を示す第一の位置情報を含み、前記リーフノードは、検索対象のビット列からなるインデックスキーを格納した記憶領域の位置を示す第二の位置情報を含むカップルドノードツリーを用いたビット列検索方法において、
前記カップルドノードツリーの任意のノードを検索開始ノードとして、前記ブランチノードにおいて該ブランチノードに含まれる弁別ビット位置の検索キーのビット値に応じてリンク先のノード対の代表ノードかあるいはそれと隣接した記憶領域に配置されたノードにリンクすることを順次前記リーフノードに至るまで繰り返すことにより、前記リーフノードに含まれる前記第二の位置情報が示す記憶領域に格納されたインデックスキーを、前記検索開始ノードをルートノードとする前記カップルドノードツリーの任意の部分木の前記検索キーによる検索結果である検索結果キーとすることを特徴とするビット列検索方法。
【請求項２】
前記カップルドノードツリーは配列に記憶され、前記第一の位置情報は、該第一の位置情報に対応する前記代表ノードが格納された前記配列の配列要素の配列番号であることを特徴とする請求項１記載のビット列検索方法。
【請求項３】
前記検索開始ノードの格納された配列要素の配列番号及び前記検索開始ノードから前記リーフノードに至るリンク先のノードの格納された配列要素の配列番号が、順次スタックに保持されていくことを特徴とする請求項２記載のビット列検索方法。
【請求項４】
ルートノードと、隣接した記憶領域に配置されるブランチノードとリーフノードまたはブランチノード同士またはリーフノード同士のノード対、からなるビット列検索に用いるツリーであって、
前記ルートノードは、ツリーの始点を表すノードであって、該ツリーのノードが１つのときは前記リーフノード、ツリーのノードが２つ以上のときは前記ブランチノードであり、
前記ブランチノードは、ビット列検索を行う検索キーの弁別ビット位置とリンク先のノード対の一方のノードである代表ノードの位置を示す第一の位置情報を含み、前記リーフノードは、検索対象のビット列からなるインデックスキーを格納した記憶領域の位置を示す第二の位置情報を含むカップルドノードツリーに、挿入キーとして指定された所望するビット列からなるインデックスキーを格納する記憶領域の位置を示す情報を含むリーフノードを挿入する、インデックスキー挿入方法において、
前記挿入キーを検索キーとして、前記ブランチノードにおいて該ブランチノードに含まれる弁別ビット位置の検索キーのビット値に応じてリンク先のノード対の代表ノードかあるいは該代表ノードと隣接した記憶領域に配置されたノードにリンクすることを、前記ルートノードから順次前記リーフノードに至るまで経路を記憶しながら繰り返し、
前記検索キーと前記リーフノードに含まれる前記第二の位置情報が示す記憶領域に格納されたインデックスキーの間で大小比較とビット列比較を行い、
ビット列比較で異なるビット値となる先頭のビット位置と、前記経路上のブランチノードの弁別ビット位置との相対的位置関係により、挿入される前記リーフノードともう一方のノードからなるノード対の挿入位置を決定し、
前記大小関係により挿入される前記リーフノードを挿入される前記ノード対のどちらのノードとするかを決定し、
前記挿入キーを格納する記憶領域の位置を示す情報を前記第二の位置情報として前記リーフノードに格納する、
ことを特徴とする挿入方法。
【請求項５】
前記カップルドノードツリーは配列に記憶され、前記第一の位置情報は、該第一の位置情報に対応する前記代表ノードが格納された前記配列の配列要素の配列番号であることを特徴とする請求項４記載の挿入方法。
【請求項６】
前記ルートノードの格納された配列要素の配列番号及び前記ルートノードから前記リーフノードに至るリンク先のノードの格納された配列要素の配列番号が、順次スタックに保持されていくことを特徴とする請求項５記載の挿入方法。
【請求項７】
ルートノードと、隣接した記憶領域に配置されるブランチノードとリーフノードまたはブランチノード同士またはリーフノード同士のノード対、からなるビット列検索に用いるツリーであって、
前記ルートノードは、ツリーの始点を表すノードであって、該ツリーのノードが１つのときは前記リーフノード、ツリーのノードが２つ以上のときは前記ブランチノードであり、
前記ブランチノードは、ビット列検索を行う検索キーの弁別ビット位置とリンク先のノード対の一方のノードである代表ノードの位置を示す第一の位置情報を含み、前記リーフノードは、検索対象のビット列からなるインデックスキーを格納した記憶領域の位置を示す第二の位置情報を含むカップルドノードツリーから、削除キーとして指定された所望するビット列からなるインデックスキーを格納する記憶領域の位置を示す情報を含むリーフノードを削除する、インデックスキー削除方法において、
前記削除キーを検索キーとして、前記ブランチノードにおいて該ブランチノードに含まれる弁別ビット位置の検索キーのビット値に応じてリンク先のノード対の代表ノードかあるいは該代表ノードと隣接した記憶領域に配置されたノードにリンクすることを前記ルートノードから順次前記リーフノードに至るまで繰り返し、
前記リーフノードと対をなすもう一方のノードを、当該ノード対のリンク元のブランチノードに格納する、
ことを特徴とする削除方法。
【請求項８】
前記カップルドノードツリーは配列に記憶され、前記第一の位置情報は、該第一の位置情報に対応する前記代表ノードが格納された前記配列の配列要素の配列番号であることを特徴とする請求項７記載の削除方法。
【請求項９】
前記ルートノードの格納された配列要素の配列番号及び前記ルートノードから前記リーフノードに至るリンク先のノードの格納された配列要素の配列番号が、順次スタックに保持されていくことを特徴とする請求項８記載の削除方法。
【請求項１０】
請求項１〜９いずれか１項に記載の方法をコンピュータに実行させるためのプログラム。
【請求項１１】
ビット列検索に用いるツリー状のデータ構造であって、
ルートノードと、隣接した記憶領域に配置されるブランチノードとリーフノードまたはブランチノード同士またはリーフノード同士のノード対、からなり、
前記ルートノードは、ツリーの始点を表すノードであって、該ツリーのノードが１つのときは前記リーフノード、ツリーのノードが２つ以上のときは前記ブランチノードであり
、
前記ブランチノードは、ビット列検索を行う検索キーの弁別ビット位置とリンク先のノード対の一方のノードである代表ノードの位置を示す第一の位置情報を含み、
前記リーフノードは、検索対象のビット列からなるインデックスキーを格納した記憶領域の位置を示す第二の位置情報を含み、
任意のノードを検索開始ノードとして、前記ブランチノードにおいて該ブランチノードに含まれる弁別ビット位置の検索キーのビット値に応じてリンク先のノード対の代表ノードかあるいは該代表ノードと隣接した記憶領域に配置されたノードにリンクすることを順次前記リーフノードに至るまで繰り返すことにより、前記検索キーによる検索の実行を可能とすることを特徴とするデータ構造。
【請求項１２】
前記データ構造は配列に記憶され、前記第一の位置情報は、該第一の位置情報に対応する前記代表ノードが格納された前記配列の配列要素の配列番号であることを特徴とする請求項１１記載のデータ構造。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明はビット列の集合から所望のビット列を検索する技術に関するものであり、特にビット列を記憶するデータ構造に工夫をして、検索速度等の向上を図る技術分野のものである。
【背景技術】
【０００２】
近年、社会の情報化が進展し、大規模なデータベースが各所で利用されるようになってきている。このような大規模なデータベースからレコードを検索するには、各レコードの記憶されたアドレスと対応づけられたレコード内の項目をインデックスキーとして検索をし、所望のレコードを探し出すことが通例である。また、全文検索における文字列も、文書のインデックスキーと見なすことができる。
【０００３】
そして、それらのインデックスキーはビット列で表現されることから、データベースの検索はビット列の検索に帰着されるということができる。
上記ビット列の検索を高速に行うために、ビット列を記憶するデータ構造を種々に工夫することが従来から行われている。このようなものの一つとして、パトリシアツリーという木構造が知られている。
【０００４】
図１３は、上述の従来の検索処理に用いられているパトリシアツリーの一例を示すものである。パトリシアツリーのノードは、インデックスキー、検索キーの検査ビット位置、左右のリンクポインタを含んで構成される。明示はされていないが、ノードにはインデックスキーに対応するレコードにアクセスするための情報が含まれていることは勿論である。
【０００５】
図１３の例では、インデックスキー“１０００１０”を保持するノード１７５０ａがルートノードとなっており、その検査ビット位置１７３０ａは０である。ノード１７５０ａの左リンク１７４０ａにはノード１７５０ｂが接続され、右リンク１７４１ａにはノード１７５０ｆが接続されている。
【０００６】
ノード１７５０ｂの保持するインデックスキーは“０１００１１”であり、検査ビット位置１７３０ｂは１である。ノード１７５０ｂの左リンク１７４０ｂにはノード１７５０ｃが、右リンク１７４１ｂにはノード１７５０ｄが接続されている。ノード１７５０ｃが保持するインデックスキーは“０００１１１”、検査ビット位置１７３０ｃは３である。ノード１７５０ｄが保持するインデックスキーは“０１１０１０”、検査ビット位置１７３０ｄは２である。
【０００７】
ノード１７５０ｃから実線で接続された部分はノード１７５０ｃの左右のリンクポインタを示すものであり、点線の接続されていない左ポインタ１７４０ｃは、その欄が空欄であることを示している。点線の接続された右ポインタ１７４１ｃの点線の接続先は、ポインタの示すアドレスを表しており、今の場合ノード１７５０ｃを右ポインタ１７４１ｃが指定していることを表している。
【０００８】
ノード１７５０ｄの右ポインタ１７４１ｄはノード１７５０ｄ自身を指しており、左リンク１７４０ｄにはノード１７５０ｅが接続されている。１７５０ｅの保持するインデックスキーは“０１００１０”、検査ビット位置１７３０ｅは５である。ノード１７５０ｅの左ポインタ１７４０ｅはノード１７５０ｂを、右ポインタ１７４１ｅはノード１７５０ｅを指している。
【０００９】
また、ノード１７５０ｆの保持するインデックスキーは“１０１０１１”であり、検査ビット位置１７３０ｆは２である。ノード１７５０ｆの左リンク１７４０ｆにはノード１７５０ｇが、右リンク１７４１ｆにはノード１７５０ｈが接続されている。
【００１０】
ノード１７５０ｇの保持するインデックスキーは“１０００１１”であり、検査ビット位置１７３０ｇは５である。ノード１７５０ｇの左ポインタ１７４０ｇはノード１７５０ａを、右ポインタ１７４１ｇはノード１７５０ｇを指している。
【００１１】
ノード１７５０ｈの保持するインデックスキーは“１０１１００”であり、検査ビット位置１７３０ｈは３である。ノード１７５０ｈの左ポインタ１７４０ｈはノード１７５０ｆを、右ポインタ１７４１ｈはノード１７５０ｈを指している。
【００１２】
図１３の例では、ルートノード１７５０ａからツリーを降りるにしたがって、各ノードの検査ビット位置が大きくなるように構成されている。
ある検索キーで検索を行うとき、ルートノードから順次各ノードに保持される検索キーの検査ビット位置を検査していき、検査ビット位置のビット値が１であるか０であるか判定を行い、１であれば右リンクをたどり、０であれば左リンクをたどる。そして、リンク先のノードの検査ビット位置がリンク元のノードの検査ビット位置より大きくなければ、すなわち、リンク先が下方でなく上方に戻れば（図１３において点線で示されたこの逆戻りのリンクをバックリンクという）、リンク先のノードのインデックスキーと検索キーの比較を行う。比較の結果、等しければ検索成功であり、等しくなければ検索失敗であることが保証されている。
【００１３】
上記のように、パトリシアツリーを用いた検索処理では、必要なビットの検査だけで検索できること、キー全体の比較は１回ですむことなどのメリットがあるが、各ノードからの２つのリンクが必ずあることにより記憶容量が増大することや、バックリンクの存在による判定処理の複雑化、バックリンクにより戻ることで初めてインデックスキーと比較することによる検索処理の遅延及び追加削除等データメンテナンスの困難性などの欠点がある。
【００１４】
これらのパトリシアツリーの欠点を解消しようとするものとして、例えば下記特許文献１に開示された技術がある。下記特許文献１に記載されたパトリシアツリーにおいては、下位の左右のノードは連続した領域に記憶することによりポインタの記憶容量を削減するとともに、次のリンクがバックリンクであるか否かを示すビットを各ノードに設けることにより、バックリンクの判定処理を軽減している。
【００１５】
しかしながら、下記特許文献１に開示されたものにおいても、１つのノードは必ずインデックスキーの領域とポインタの領域を占めること、下位の左右のノードを連続した領域に記憶するようにしてポインタを１つとしたため、例えば図１３に示したパトリシアツリーの最下段の部分である左ポインタ１７４０ｃ、右ポインタ１７４１ｈ等の部分にもノードと同じ容量の記憶領域を割り当てる必要があるなど、記憶容量の削減効果はあまり大きいものではない。また、バックリンクによる検索処理の遅延の問題や追加削除等の処理が困難であることも改善されていない。
【００１６】
上述の従来の検索手法における問題点を解決するものとして、本出願人は、特願２００６−１８７８２７（以下「先の出願」と呼ぶ）において、ルートノードと、隣接した記憶領域に配置されるブランチノードとリーフノードまたはブランチノード同士またはリーフノード同士のノード対からなるビット列検索に用いるツリーであって、ルートノードはツリーの始点を表すノードであって、該ツリーのノードが１つのときはリーフノード、ツリ
ーのノードが２つ以上のときは前記ブランチノードであり、前記ブランチノードは、ビット列検索を行う検索キーの弁別ビット位置とリンク先のノード対の一方のノードである代表ノードの位置を示す位置情報を含み、前記リーフノードは検索対象のビット列からなるインデックスキーを含むカップルドノードツリーを用いたビット列検索を提案した。また、上記先の出願には、与えられたインデックスキーを含むリーフノードの挿入を繰り返すことにより与えられたインデックスキーの集合からカップルドノードツリーを生成する方法と、指定された削除キーをインデックスキーとするノードをカップルドノードツリーから削除する方法も示されている。
【００１７】
このカップルドノードツリーには、必要な記憶容量がパトリシアツリーに比べて少なく、高速な検索を可能とする構造であり、ノードの挿入や削除が低コストで実行可能であるという特徴がある。また、上記先の出願には、それぞれ同じ容量の記憶領域が割り当てられた配列要素からなる配列を利用して、カップルドノードツリーの個々のノードを配列要素に記憶し、位置情報として配列番号を利用することにより、位置情報に要するビット数を削減する実施形態が示されている。
【特許文献１】特開２００１−３５７０７０号公報
【発明の開示】
【発明が解決しようとする課題】
【００１８】
上記のようなカップルドノードツリーに対して、配列要素の容量を定めた後でその容量の記憶領域に格納しきれない長いインデックスキーを利用しようとした場合に、そのインデックスキーに対応するリーフノードをカップルドノードツリーに効率よく挿入することが望まれる。また、インデックスキーが長い場合に、ブランチノードには過剰な記憶領域を割り当てないようにして記憶領域を有効利用することも望まれる。
【００１９】
そこで本発明の目的は、インデックスキーの長さが予め決められている必要がなく、長いインデックスキーを利用する場合にも有効に記憶領域を利用することが可能なように、カップルドノードツリーの構造を改良することである。また、そのように改良されたカップルドノードツリーを検索する方法、指定されたインデックスキーに対応するノードを該カップルドノードツリーに挿入する方法、及び指定されたインデックスキーに対応するノードを該カップルドノードツリーから削除する方法を提供することも、本発明の目的である。
【課題を解決するための手段】
【００２０】
本発明によれば、以下のデータ構造を持つカップルドノードツリーが提供され、そのカップルドノードツリーを用いてインデックスキーの検索が行われる。また、本発明によれば、指定されたインデックスキーに対応するリーフノードの挿入や削除をそのカップルドノードツリーに対して行う方法が提供される。
【００２１】
本発明のカップルドノードツリーは、ルートノードと、隣接した記憶領域に配置されるブランチノードとリーフノードまたはブランチノード同士またはリーフノード同士のノード対、からなる。
【００２２】
前記ルートノードは、ツリーの始点を表すノードであって、該ツリーのノードが１つのときは前記リーフノード、ツリーのノードが２つ以上のときは前記ブランチノードである。前記ブランチノードは、ビット列検索を行う検索キーの弁別ビット位置とリンク先のノード対の一方のノードである代表ノードの位置を示す第一の位置情報を含む。前記リーフノードは、検索対象のビット列からなるインデックスキーを格納した記憶領域の位置を示す第二の位置情報を含む。
【００２３】
前記カップルドノードツリーの任意のノードを検索開始ノードとすることにより、前記検索開始ノードをルートノードとする前記カップルドノードツリーの任意の部分木を検索対象として、前記検索キーによる検索を実行することができる。その検索は、前記ブランチノードにおいて該ブランチノードに含まれる弁別ビット位置の検索キーのビット値に応じてリンク先のノード対の代表ノードかあるいはそれと隣接した記憶領域に配置されたノードにリンクすることを順次前記リーフノードに至るまで繰り返すことにより行われ、前記リーフノードに含まれる前記第二の位置情報が示す記憶領域に格納されたインデックスキーが、検索結果キーとして得られる。
【００２４】
挿入キーとして指定された新たなビット列からなるインデックスキーを格納する記憶領域の位置を示す情報を含むリーフノードを前記カップルドノードツリーに挿入するには、まず、前記ルートノードを前記検索開始ノードとし、前記挿入キーを前記検索キーとして、前記ルートノードから前記検索結果キーに対応する前記リーフノードに至る経路を記憶しながら上記の検索を実行する。そして、前記挿入キーと前記検索結果キーの間で大小比較とビット列比較を行う。ビット列比較で異なるビット値となる先頭のビット位置と、前記経路上のブランチノードの弁別ビット位置との相対的位置関係により、挿入される前記リーフノードともう一方のノードからなるノード対の挿入位置を決定する。また、前記大小関係により挿入される前記リーフノードを挿入される前記ノード対のどちらのノードとするかを決定する。さらに、前記挿入キーを格納する記憶領域の位置を示す情報を前記第二の位置情報として前記リーフノードに格納する。
【００２５】
削除キーとして指定されたビット列からなるインデックスキーを格納する記憶領域の位置を示す情報を含むリーフノードを前記カップルドノードツリーから削除するには、まず、前記ルートノードを前記検索開始ノードとし、前記削除キーを前記検索キーとして、上記の検索を実行する。そして、前記検索結果キーに対応する前記リーフノードと対をなすもう一方のノードを、当該ノード対のリンク元のブランチノードに格納する。
【発明の効果】
【００２６】
本発明によるカップルドノードツリーは、高速な検索を可能とする構造を有し、ノードの挿入や削除が低コストで実行可能であるという、先の出願のカップルドノードツリーの特徴を引き継いでいる。また、前記先の出願のカップルドノードツリーは必要な記憶容量が少ないという特徴を有するが、本発明によるカップルドノードツリーは記憶領域をさらに有効に利用することが可能なように、構造が改良されている。
【００２７】
本発明によれば、インデックスキーの記憶領域がノードの記憶領域から分離されている。よって、予めノードの記憶容量が定められても、利用可能なインデックスキーの長さがその記憶容量により直接制限されるわけではない。また、長いインデックスキーを利用する場合でも各ノードに必要な記憶容量がそれに比例して増えることはないので、各ノードに同じ大きさの記憶領域を割り当てる態様においても、記憶領域が無駄に使われることはない。
【発明を実施するための最良の形態】
【００２８】
以下、本発明を実施するための最良の形態として、カップルドノードツリーを配列に格納する例について説明する。ブランチノードが保持するリンク先の位置を示すデータとして、記憶装置のアドレス情報とすることもできるが、ブランチノードあるいはリーフノードのうち占有する領域の記憶容量の大きい方を格納可能な配列要素からなる配列を用いることにより、ノードの位置を配列番号で表すことができ、代表ノードの位置を示す第一の位置情報の情報量を削減することができる。
【００２９】
図１は、配列に格納されたカップルドノードツリーの構成例を説明する図である。
図１を参照すると、ノード１０１が配列１００の配列番号１０の配列要素に配置されている。ノード１０１はノード種別１０２、弁別ビット位置１０３及び代表ノード番号１０４で構成されている。ノード種別１０２の値は０であり、ノード１０１がブランチノードであることを示している。弁別ビット位置１０３には１が格納されている。代表ノード番号１０４にはリンク先のノード対の代表ノードの配列番号２０が格納されている。配列番号は上記第一の位置情報の具体例である。なお、以下では表記の簡略化のため、代表ノード番号に格納された配列番号を代表ノード番号ということもある。また、代表ノード番号に格納された配列番号をそのノードに付した符号あるいはノード対に付した符号で表すこともある。
【００３０】
配列番号２０の配列要素には、ノード対１１１の代表ノードであるノード［０］１１２が格納されている。そして隣接する次の配列要素（配列番号２０＋１）に代表ノードと対になるノード［１］１１３が格納されている。ノード［０］１１２はノード１０１と同様にブランチノードである。ノード［０］１１２のノード種別１１４には０が、弁別ビット位置１１５には３が、代表ノード番号１１６には３０が格納されている。またノード［１］１１３は、ノード種別１１７と参照ポインタ１１８ａで構成されている。ノード種別１１７には１が格納されており、ノード［１］１１３がリーフノードであることを示している。参照ポインタ１１８ａには、インデックスキーの記憶領域を参照するポインタが格納されている。参照ポインタ１１８ａに格納されたデータは、上記の第二の位置情報の具体例である。以下では表記の簡略化のため、参照ポインタに格納されたデータのことも参照ポインタという。
【００３１】
パトリシアツリーについて先に述べたと同様に、インデックスキーと対応するレコードにアクセスするためのアクセス先情報も当然必要である。インデックスキーとアクセス先情報との対応づけは、例えば、インデックスキーを記憶している記憶領域に隣接する記憶領域に、当該インデックスキーに対応するアクセス先情報を記憶することによって行ってもよい。以下ではアクセス先情報については省略して説明する。
【００３２】
ここで、弁別ビット位置を表すのに必要なビット長は、最長のインデックスキーのビット長の影響を受けるが、前者は後者の対数なので、非常に長いインデックスキーを利用する場合でも弁別ビット位置を表すのに必要なビット数はそれほど多くない。また、例えばメモリアドレス又は所定のメモリアドレスからのオフセットを参照ポインタとして利用する場合には、参照ポインタのビット長はインデックスキーのビット長とは無関係である。よって、インデックスキーのかわりに参照ポインタを含むようにリーフノードを構成することにより、事実上、カップルドノードツリーのノードに必要な記憶容量を、インデックスキーの長さに関わらず比較的小さな定数値とすることが可能となる。一般に、大規模なデータベースでは多くのレコードを区別する必要から長いインデックスキーが必要となり、そのようなデータベースにおけるインデックスキーのビット長は、配列１００の各配列要素に必要なビット長よりも長いことが多い。
【００３３】
また、配列１００とは別の不図示の配列の各配列要素にインデックスキーを格納し、その別の配列の配列番号を参照ポインタとして利用することも可能である。例えば、長さがｎビットのビット列からなるインデックスキーのうちの限られた一部しか使われないことが予め分かっている場合、配列番号を表すのに必要なビット数ｍはｎより小さいので、リーフノードがインデックスキーのかわりに参照ポインタを含むことにより、リーフノードに必要な記憶容量が削減される。
【００３４】
なお、代表ノードをノード［０］で表し、それと対になるノードをノード［１］で表すことがある。また、ある配列番号の配列要素に格納されたノードを、その配列番号のノードということがあり、ノードの格納された配列要素の配列番号を、ノードの配列番号とい
うこともある。さらに、あるリーフノードと、そのリーフノードの参照ポインタが示す記憶領域に格納されたインデックスキーとの関係を示すのに、リーフノードに対応するインデックスキーということもあり、インデックスキーに対応するリーフノードということもある。
【００３５】
配列番号３０及び３１の配列要素に格納されたノード１２２とノード１２３からなるノード対１２１の内容は省略されている。
ノード［０］１１２、ノード［１］１１３、ノード１２２、及びノード１２３の格納された配列要素にそれぞれ付された０あるいは１は、検索キーで検索を行う場合にノード対のどちらのノードにリンクするかを示すものである。前段のブランチノードの弁別ビット位置にある検索キーのビット値である０か１を代表ノード番号に加えた配列番号のノードにリンクする。
【００３６】
したがって、前段のブランチノードの代表ノード番号に、検索キーの弁別ビット位置のビット値を加えることにより、リンク先のノードが格納された配列要素の配列番号を求めることができる。
【００３７】
なお、上記の例では代表ノード番号をノード対の配置された配列番号のうち小さい方を採用しているが、大きいほうを採用することも可能であることは明らかである。
図２は、カップルドノードツリーのツリー構造を概念的に示す図である。
【００３８】
符号２１０ａで示すのがルートノードである。図示の例では、ルートノード２１０ａは配列番号２２０に配置されたノード対２０１ａの代表ノードとしている。
ツリー構造としては、ルートノード２１０ａの下にノード対２０１ｂが、その下層にノード対２０１ｃとノード対２０１ｆが配置され、ノード対２０１ｆの下層にはノード対２０１ｈとノード対２０１ｇが配置されている。ノード対２０１ｃの下にはノード対２０１ｄが、さらにその下にはノード対２０１ｅが配置されている。
【００３９】
各ノードの前に付された０あるいは１の符号は、図１において説明した配列要素の前に付された符号と同じである。検索キーの弁別ビット位置のビット値に応じてツリーをたどり、検索対象のインデックスキーに対応するリーフノードを見つけることになる。
【００４０】
図示された例では、ルートノード２１０ａのノード種別２６０ａは０でブランチノードであることを示し、弁別ビット位置２３０ａは０を示している。代表ノード番号は２２０ａであり、それはノード対２０１ｂの代表ノード２１０ｂの格納された配列要素の配列番号である。
【００４１】
ノード対２０１ｂはノード２１０ｂと２１１ｂで構成され、それらのノード種別２６０ｂ、２６１ｂはともに０であり、ブランチノードであることを示している。ノード２１０ｂの弁別ビット位置２３０ｂには１が格納され、リンク先の代表ノード番号にはノード対２０１ｃの代表ノード２１０ｃの格納された配列要素の配列番号２２０ｂが格納されている。
【００４２】
ノード２１０ｃのノード種別２６０ｃには１が格納されているので、このノードはリーフノードであり、したがって、参照ポインタ２５０ｃを含んでいる。参照ポインタ２５０ｃには、インデックスキー２９０ｃが格納されている記憶領域を参照するポインタを格納する。参照ポインタ２５０ｃに格納されたデータのことも参照ポインタといい、符号２８０ｃにより表す。他のリーフノードでも同様に、参照ポインタと参照ポインタに格納されたデータを同じ参照ポインタという語で表す。
【００４３】
図２には、複数のインデックスキーの記憶領域が連続して設けられる例を示し、それら連続した記憶領域全体をインデックスキーの記憶領域３１１として示したが、インデックスキーは連続した領域に格納されなくてもよい。また、リーフノード同士のツリー構造上での関係と、インデックスキーの記憶領域３１１におけるインデックスキーの配置順は無関係であってもよい。参照ポインタ２８０ｃは、“０００１１１ＸＸＸＸＸＸＸＸ”というインデックスキー２９０ｃが格納された記憶領域を示している。
【００４４】
ここで、“ＸＸＸＸＸＸＸＸ”の部分は０ビット以上の長さの、ある特定のビット列である。よって、図２のカップルドノードツリーに係るインデックスキーの中に、０〜５ビット目までの範囲が“０００１１１”のものは１つしか存在しない。したがって、詳しい理由は後述するが、“ＸＸＸＸＸＸＸＸ”の部分のビット列のパターンによらず、カップルドノードツリーの構造は変わらない。他のインデックスキーでも同様に、図２のカップルドノードツリー全体で最下位の弁別ビット位置である５よりも下位の６ビット目以降のビットは、カップルドノードツリーの構造に影響しないので“Ｘ”と表している。“Ｘ”で示されたビットが存在するか否か、そのビットが存在する場合にその値が“０”か“１”かということに関わらず、図２のカップルドノードツリーのツリー構造は変わらない。
【００４５】
ノード対２０１ｃに戻ると、もう一方のノード２１１ｃのノード種別２６１ｃは０、弁別ビット位置２３１ｃは２であり、代表ノード番号にはノード対２０１ｄの代表ノード２１０ｄの格納された配列要素の配列番号２２１ｃが格納されている。
【００４６】
ノード２１０ｄのノード種別２６０ｄは０、弁別ビット位置２３０ｄは５であり、代表ノード番号にはノード対２０１ｅの代表ノード２１０ｅの格納された配列要素の配列番号２２０ｄが格納されている。ノード２１０ｄと対になるノード２１１ｄのノード種別２６１ｄは１であり、参照ポインタ２５１ｄには、“０１１０１０ＸＸＸＸＸＸＸＸ”というインデックスキー２９１ｄを格納した記憶領域を示す参照ポインタ２８１ｄが格納されている。
【００４７】
ノード対２０１ｅのノード２１０ｅ、２１１ｅのノード種別２６０ｅ、２６１ｅはともに１であり双方ともリーフノードであることを示す。ノード２１０ｅ、２１１ｅの参照ポインタ２５０ｅ、２５１ｅにはそれぞれ、“０１００１０ＸＸＸＸＸＸＸＸ”というインデックスキー２９０ｅと、“０１００１１ＸＸＸＸＸＸＸＸ”というインデックスキー２９１ｅを格納した記憶領域への参照ポインタ２８０ｅ、２８１ｅが格納されている。
【００４８】
ノード対２０１ｂのもう一方のノードであるノード２１１ｂの弁別ビット位置２３１ｂには２が格納され、リンク先の代表ノード番号にはノード対２０１ｆの代表ノード２１０ｆの格納された配列要素の配列番号２２１ｂが格納されている。
【００４９】
ノード対２０１ｆのノード２１０ｆ、２１１ｆのノード種別２６０ｆ、２６１ｆはともに０であり双方ともブランチノードである。それぞれの弁別ビット位置２３０ｆ、２３１ｆには５、３が格納されている。ノード２１０ｆの代表ノード番号にはノード対２０１ｇの代表ノード２１０ｇの格納された配列要素の配列番号２２０ｆが格納され、ノード２１１ｆの代表ノード番号にはノード対２０１ｈの代表ノードであるノード［０］２１０ｈの格納された配列要素の配列番号２２１ｆが格納されている。
【００５０】
ノード対２０１ｇのノード２１０ｇ、２１１ｇのノード種別２６０ｇ、２６１ｇはともに１であり双方ともリーフノードであることを示す。ノード２１０ｇ、２１１ｇのそれぞれの参照ポインタ２５０ｇ、２５１ｇには“１０００１０ＸＸＸＸＸＸＸＸ”と“１０００１１ＸＸＸＸＸＸＸＸ”というインデックスキー２９０ｇ、２９１ｇを格納した記憶領域への参照ポインタ２８０ｇ、２８１ｇが格納されている。
【００５１】
また同じくノード対２０１ｈの代表ノードであるノード［０］２１０ｈとそれと対をなすノード［１］２１１ｈのノード種別２６０ｈ、２６１ｈはともに１であり双方ともリーフノードであることを示す。ノード２１０ｈ、２１１ｈのそれぞれの参照ポインタ２５０ｈ、２５１ｈには“１０１０１１ＸＸＸＸＸＸＸＸ”と“１０１１００ＸＸＸＸＸＸＸＸ”というインデックスキー２９０ｈ、２９１ｈを格納した記憶領域への参照ポインタ２８０ｈ、２８１ｈが格納されている。
【００５２】
以下、上述のツリーからインデックスキー“１０００１０”を検索する処理の流れを簡単に説明する。弁別ビット位置は、左から０、１、２、・・・とする。
まず、ビット列“１０００１０”を検索キーとしてルートノード２１０ａから処理をスタートする。ルートノード２１０ａの弁別ビット位置２３０ａは０であるので、検索キー“１０００１０”の弁別ビット位置が０のビット値をみると１である。そこで代表ノード番号の格納された配列番号２２０ａに１を加えた配列番号の配列要素に格納されたノード２１１ｂにリンクする。ノード２１１ｂの弁別ビット位置２３１ｂには２が格納されているので、検索キー“１０００１０”の弁別ビット位置が２のビット値をみると０であるから、代表ノード番号の格納された配列番号２２１ｂの配列要素に格納されたノード２１０ｆにリンクする。
【００５３】
ノード２１０ｆの弁別ビット位置２３０ｆには５が格納されているので、検索キー“１０００１０”の弁別ビット位置が５のビット値をみると０であるから、代表ノード番号の格納された配列番号２２０ｆの配列要素に格納されたノード２１０ｇにリンクする。
【００５４】
ノード２１０ｇのノード種別２６０ｇは１でありリーフノードであることを示しているので、参照ポインタ２８０ｇにより示される記憶領域を参照し、そこに格納されたインデックスキー２９０ｇを読み出して検索キーと比較する。例えば、“Ｘ”と書かれたビットが存在しない場合は、インデックスキー２９０ｇと検索キーの両方とも値が“１０００１０”であって一致している。このようにしてカップルドノードツリーを用いた検索が行われる。
【００５５】
次に、図２を参照してカップルドノードツリーの構成の意味について説明する。
カップルドノードツリーの構成はインデックスキーの集合により規定される。図２の例で、ルートノード２１０ａの弁別ビット位置２３０ａが０であるのは、図２に例示されたインデックスキーに０ビット目が０のものと１のものがあるからである。０ビット目が０のインデックスキーのグループはノード２１０ｂの下に分類され、０ビット目が１のインデックスキーのグループはノード２１１ｂの下に分類されている。
【００５６】
ノード２１１ｂの弁別ビット位置２３１ｂが２であるのは、ノード２１１ｈ、２１０ｈ、２１１ｇ、２１０ｇに対応する０ビット目が１のインデックスキーの１ビット目がすべて０で等しく、２ビット目で初めて異なるものがあるという、インデックスキーの集合の性質を反映している。
【００５７】
以下０ビット目の場合と同様に、２ビット目が１であるものはノード２１１ｆ側に分類され、２ビット目が０であるものはノード２１０ｆ側に分類される。
そして２ビット目が１であるインデックスキーは３ビット目の異なるものがあるのでノード２１１ｆの弁別ビット位置２３１ｆには３が格納され、２ビット目が０であるインデックスキーでは３ビット目も４ビット目も等しく５ビット目で異なるのでノード２１０ｆの弁別ビット位置２３０ｆには５が格納される。
【００５８】
ノード２１１ｆのリンク先においては、３ビット目が１のものと０のものがそれぞれ１
つしかないことから、ノード２１０ｈ、２１１ｈはリーフノードとなり、参照ポインタ２５０ｈと２５１ｈには、“１０１０１１ＸＸＸＸＸＸＸＸ”、“１０１１００ＸＸＸＸＸＸＸＸ”というインデックスキー２９０ｈ、２９１ｈを格納した記憶領域を指す参照ポインタ２８０ｈ、２８１ｈがそれぞれ格納されている。
【００５９】
仮にインデックスキーの集合に“１０１１００ＸＸＸＸＸＸＸＸ”の代わりに“１０１１０１ＸＸＸＸＸＸＸＸ”か“１０１１１０ＸＸＸＸＸＸＸＸ”が含まれていたとしても、３ビット目までは“１０１１００ＸＸＸＸＸＸＸＸ”と等しいので、ノード２１１ｈの参照ポインタ２８１ｈにより示される記憶領域に格納されるインデックスキーの値が変わるだけで、ツリー構造自体は変わることはない。しかし、“１０１１００ＸＸＸＸＸＸＸＸ”に加えて“１０１１０１ＸＸＸＸＸＸＸＸ”が含まれていると、ノード２１１ｈはブランチノードとなり、その弁別ビット位置は５になる。追加されるインデックスキーが“１０１１１０ＸＸＸＸＸＸＸＸ”であれば、弁別ビット位置は４となる。
【００６０】
以上説明したように、カップルドノードツリーの構造は、インデックスキーの集合に含まれる各インデックスキーの各ビット位置のビット値により決定される。
そしてさらにいえば、異なるビット値となるビット位置ごとにビット値が“１”のノードとビット値が“０”のノードとに分岐していることから、ノード［１］側とツリーの深さ方向を優先させてリーフノードをたどると、それらに格納されたインデックスキーは、ノード２１１ｈに対応するインデックスキー２９１ｈの“１０１１００ＸＸＸＸＸＸＸＸ”、ノード２１０ｈに対応するインデックスキー２９０ｈの“１０１０１１ＸＸＸＸＸＸＸＸ”、・・・、ノード２１０ｃに対応するインデックスキー２９０ｃの“０００１１１ＸＸＸＸＸＸＸＸ”となり降順にソートされている。
【００６１】
すなわち、カップルドノードツリーにおいては、インデックスキーはソートされてツリー上に配置されている。
検索キーで検索するときはインデックスキーがカップルドノードツリー上に配置されたルートをたどることになり、例えば検索キーが“１０１１００”であればノード２１１ｈに到達することができる。また、上記説明からも想像がつくように、“１０１１０１”か“１０１１１０”を検索キーとした場合でもノード２１１ｈにたどり着き、参照ポインタ２８１ｈにより示される記憶領域に格納されたインデックスキー２９１ｈと比較することにより、検索が失敗したことが分かる。
【００６２】
また、例えば“１００１００”で検索した場合でも、ノード２１０ａ、２１１ｂ、２１０ｆのリンク経路では検索キーの３ビット目と４ビット目は使われることがなく、“１００１００”の５ビット目が０なので、“１０００１０”で検索した場合と同様にノード２１０ｇに到達することになる。このように、カップルドノードツリーに格納されたインデックスキーのビット構成に応じた弁別ビット位置を用いて分岐が行われる。
【００６３】
図３は、本発明を実施するためのハードウェア構成例を説明する図である。
本発明の検索装置による検索処理及びデータメンテナンスは中央処理装置３０２及びキャッシュメモリ３０３を少なくとも備えたデータ処理装置３０１によりデータ格納装置３０８を用いて実施される。カップルドノードツリーが配置される配列３０９と検索中にたどるノードが格納された配列要素の配列番号を記憶する探索経路スタック３１０とインデックスキーの記憶領域３１１を有するデータ格納装置３０８は、主記憶装置３０５または外部記憶装置３０６で実現することができ、あるいは通信装置３０７を介して接続された遠方に配置された装置を用いることも可能である。図１の配列１００は配列３０９の一例である。また、図２と同様に、インデックスキーの記憶領域３１１は連続した領域のように図示されているが、不連続の領域でもよいことは当然である。
【００６４】
図３の例示では、主記憶装置３０５、外部記憶装置３０６及び通信装置３０７が一本のバス３０４によりデータ処理装置３０１に接続されているが、接続方法はこれに限るものではない。また、主記憶装置３０５をデータ処理装置３０１内のものとすることもできるし、探索経路スタック３１０を中央処理装置３０２内のハードウェアとして実現することも可能である。あるいは、配列３０９は外部記憶装置３０６に、探索経路スタック３１０を主記憶装置３０５に持つなど、使用可能なハードウェア環境、インデックスキー集合の大きさ等に応じて適宜ハードウェア構成を選択できることは明らかである。
【００６５】
また、特に図示されてはいないが、処理の途中で得られた各種の値を後の処理で用いるためにそれぞれの処理に応じた一時記憶装置が用いられることは当然である。
図３に示したとおり、カップルドノードツリーのノードを格納した配列要素からなる配列３０９と、インデックスキーの記憶領域３１１とは別の領域である。したがって、リーフノードを格納した配列要素にインデックスキーが含まれる場合に比べて、図３の構成では、一般に１つの配列要素に必要な記憶領域の量が少ない。つまり、カップルドノードツリーを格納する配列３０９からインデックスキーの記憶領域３１１を分離することによって、キャッシュメモリ３０３へのカップルドノードツリーの読み込みにおいて１キャッシュブロックあたりに格納されるノード数を増やすことが可能となる。それにより、後述する検索処理等においてキャッシュミスの頻度が減って処理がより高速に行われるようになる。
【００６６】
次に、カップルドノードツリーを用いた基本的な操作である、検索、挿入、削除について順に詳しく説明する。これらの操作は、本出願人による上記先の出願における検索、挿入、削除の操作を、カップルドノードツリーの構造の変更に合わせて一部変更したものである。
【００６７】
図４は、一実施形態におけるビット列の検索処理を示すフローチャートである。
まず、ステップＳ４０１で、検索開始ノードとしてのルートノードの配列番号を取得する。取得された配列番号に対応する配列要素は、ルートノードを格納している。
【００６８】
次に、ステップＳ４０２で、探索経路スタックに取得された配列番号を格納し、ステップＳ４０３で、その配列番号に対応する配列要素を参照すべきノードとして読み出す。そして、ステップＳ４０４で、読み出したノードから、ノード種別を取り出し、ステップＳ４０５で、ノード種別がブランチノードであるか否かを判定する。
【００６９】
ステップＳ４０５の判定において、読み出したノードがブランチノードである場合は、ステップＳ４０６に進み、ノードから弁別ビット位置についての情報を取り出し、更に、ステップＳ４０７で、取り出した弁別ビット位置に対応するビット値を検索キーから取り出す。そして、ステップＳ４０８で、ノードから代表ノード番号を取り出して、ステップＳ４０９で、検索キーから取り出したビット値と代表ノード番号とを加算し、新たな配列番号として、ステップＳ４０２に戻る。
【００７０】
以降、ステップＳ４０５の判定においてリーフノードと判定されてステップＳ４１０ａに進むまで、ステップＳ４０２からステップＳ４０９までの処理を繰り返す。ステップＳ４１０ａでは、リーフノードから参照ポインタを取り出し、続くステップＳ４１０ｂではインデックスキーの記憶領域から、その参照ポインタが指すインデックスキーを読み出す。そして、続くステップＳ４１１において、検索キーと取り出したインデックスキーが等しいか否かを判定する。等しければ検索成功であり、等しくなければ検索失敗である。
【００７１】
なお、図４ではカップルドノードツリーの全体を検索の対象としているが、上記の説明から明らかに、カップルドノードツリーの任意の部分木を検索対象として検索を行うこと
も可能である。その場合、検索対象の部分木のルートノードの配列番号をステップＳ４０１で得るように図４の処理を変形すればよい。検索対象の部分木のルートノードは、図４の検索処理を呼び出す応用処理により指定されるので、ステップＳ４０１では呼び出し元から検索対象の部分木のルートノードの配列番号を受け取ればよい。本出願人による特願２００６−２９３６１９号において示された、インデックスキーを昇順に取り出す処理は、そのような応用処理の具体例である。
【００７２】
本出願人による上記先の出願における検索処理と図４の検索処理との違いは、ステップＳ４１０ａとＳ４１０ｂにおいて、インデックスキーを直接参照するのではなく、参照ポインタを介して間接参照する点である。その結果、ステップＳ４０３で配列３０９に格納されたノードを参照するほかに、ステップＳ４１０ｂでインデックスキーの記憶領域３１１に格納されたインデックスキーを参照する必要があり、記憶装置への参照回数が１回だけ増えている。
【００７３】
一方、カップルドノードツリーのノード数が多く、ツリーが深くなるほど、ステップＳ４０２〜Ｓ４０９のループの繰り返しにかかる計算コストが検索処理全体にかかる計算コストに占める割合が増え、このループの繰り返しの計算コストの削減の影響が大きくなる。つまり、ノード数の多いカップルドノードツリーの検索においては、インデックスキーの記憶領域３１１を配列３０９から分離したことによる高速化の利点の方が大きく、増加した間接参照のコストは無視しても問題がない程度に小さい。
【００７４】
次に、図５〜図８によりカップルドノードツリーにおけるノード挿入処理を説明する。図５〜図７が通常の挿入処理を説明するものであり、図８はルートノードの挿入処理を説明するものである。ルートノードの挿入処理と通常の挿入処理により、カップルドノードツリーが生成されることから、ノード挿入処理の説明はカップルドノードツリーの生成処理の説明でもある。
【００７５】
図５は挿入処理の前段である検索処理の処理フローを示す図であり、図４に示した検索処理において挿入キーを検索キーとしたものに相当する。ステップＳ５０１〜ステップＳ５１０ｂの処理は図４のステップＳ４０１〜ステップＳ４１０ｂに完全に対応するので説明は省略する。
【００７６】
図５のステップＳ５１１において、挿入キーとステップＳ５１０ｂで得たインデックスキーを比較し、等しければ挿入キーは既にカップルドノードツリーに存在するのであるから、挿入は失敗となり、処理を終了する。等しくなければ次の処理、図６のステップＳ５１２以下の処理に進む。
【００７７】
図６は、挿入するノード対のための配列要素を準備する処理を説明する処理フロー図である。
ステップＳ５１２において、配列から空きのノード対を求め、そのノード対のうち代表ノードとなるべき配列要素の配列番号を取得する。
【００７８】
ステップＳ５１３に進み、挿入キーとステップＳ５１０ｂで得たインデックスキーの大小を比較し、挿入キーが大きいときは値１を小さいときは値０のブール値を得る。
ステップＳ５１４に進み、ステップＳ５１２で得た代表ノードの配列番号にステップＳ５１３で得たブール値を加算した配列番号を得る。
【００７９】
ステップＳ５１５に進み、ステップＳ５１２で得た代表ノードの配列番号にステップＳ５１３で得たブール値の論理否定値を加算した配列番号を得る。
ステップＳ５１４で得た配列番号は、挿入キーをインデックスキーとして格納する記憶
領域への参照ポインタを持つリーフノードが格納される配列要素の配列番号であり、ステップＳ５１５で得た配列番号は、そのリーフノードとノード対を成すノードが格納される配列要素のものである。
【００８０】
つまり、前段の検索処理で得られたリーフノードに対応するインデックスキーと挿入キーの大小により、挿入されるノード対のうちどちらのノードに、挿入キーへの参照ポインタを保持するリーフノードが格納されるかが決定される。
【００８１】
例えば図２のカップルドノードツリーに“０１１０１１ＸＸＸＸＸＸＸＸ”を挿入する場合、検索結果のインデックスキーは、ノード２１１ｄに対応する、“０１１０１０ＸＸＸＸＸＸＸＸ”という値のインデックスキー２９１ｄになる。挿入キー“０１１０１１ＸＸＸＸＸＸＸＸ”とノード２１１ｄに対応するインデックスキー“０１１０１０ＸＸＸＸＸＸＸＸ”の大小比較によりブール値が求められ、今の例では挿入キーの方が大きいのでブール値１が得られ、挿入されるノード対の代表ノード番号に１を加えた配列要素に挿入キーへの参照ポインタを保持するリーフノードが格納される。一方、インデックスキー“０１１０１０ＸＸＸＸＸＸＸＸ”への参照ポインタは、大小比較で得られたブール値を論理反転した値を代表ノード番号に加算した配列番号の配列要素に格納される。
【００８２】
その際、インデックスキー“０１１０１０ＸＸＸＸＸＸＸＸ”と挿入キー“０１１０１１ＸＸＸＸＸＸＸＸ”とは５ビット目で異なることから、ノード２１１ｄは、弁別ビット位置を５とし、代表ノード番号を挿入されたノード対の代表ノードの配列番号とするブランチノードとなる。
【００８３】
また図２のカップルドノードツリーに“０１１００１ＸＸＸＸＸＸＸＸ”を挿入しようとする場合も、検索結果は、ノード２１１ｄに対応する、“０１１０１０ＸＸＸＸＸＸＸＸ”という値のインデックスキー２９１ｄになる。この場合には挿入キーの方が小さいのでブール値０が得られ、挿入されるノード対の代表ノード番号に０を加えた配列要素に挿入キーへの参照ポインタを保持するリーフノードが格納される。そして、インデックスキー２９１ｄ“０１１０１０ＸＸＸＸＸＸＸＸ”と挿入キー“０１１００１ＸＸＸＸＸＸＸＸ”とは４ビット目で異なることから、ノード２１１ｄは、弁別ビット位置を４とし、代表ノード番号を挿入されたノード対の代表ノードの配列番号とするブランチノードとなる。次に図７のステップＳ５１６以下の処理に進む。
【００８４】
図７は図６で準備された配列要素にノードを格納するとともにその挿入位置を求め、既存のノードの内容を変更して挿入処理を完成させる処理フローを示す図である。
ステップＳ５１６〜ステップＳ５２３までの処理は、挿入するノード対のカップルドノードツリー上の位置を求める処理であり、ステップＳ５２４以下の処理は各ノードにデータを設定して挿入処理を完成させる処理である。
【００８５】
ステップＳ５１６で、挿入キーとステップＳ５１０ｂで得たインデックスキーのビット列比較を例えば排他的論理和で行い、差分ビット列を得る。
ステップＳ５１７に進み、ステップＳ５１６で得た差分ビット列から、上位０ビット目から見た最初の不一致ビットのビット位置を得る。この処理は、例えばプライオリティエンコーダを有するＣＰＵではそこに差分ビット列を入力し、不一致のビット位置を得ることができる。また、ソフト的にプライオリティエンコーダと同等の処理を行い最初の不一致ビットのビット位置を得ることも可能である。
【００８６】
次にステップＳ５１８に進み、探索経路スタックのスタックポインタがルートノードの配列番号を指しているか判定する。指していればステップＳ５２４に移行し、指していなければステップＳ５１９に進む。
【００８７】
ステップＳ５１９において、探索経路スタックのスタックポインタを１つ戻してそこにスタックされている配列番号を取り出す。
ステップＳ５２０に進み、ステップＳ５１９で取り出した配列番号の配列要素を配列からノードとして読み出す。
【００８８】
ステップＳ５２１に進み、ステップＳ５２０で読み出したノードから、弁別ビット位置を取り出す。
次にステップＳ５２２に進み、ステップＳ５２１で取り出した弁別ビット位置がステップＳ５１７で得たビット位置より上位の位置関係か判定する。ここで上位の位置関係とは、ビット列のより左側の位置、すなわちビット位置の値が小さい位置であることとする。
【００８９】
ステップＳ５２２の判定結果が否定であれば、ステップＳ５１８に戻り、ステップＳ５１８での判定が肯定になるかステップＳ５２２での判定が肯定になるまで繰り返す。ステップＳ５２２での判定が肯定になると、ステップＳ５２３で探索経路スタックのスタックポインタを１つ進め、ステップＳ５２４以下の処理に移行する。
【００９０】
上記ステップＳ５１６〜ステップＳ５２３で説明した処理は、挿入するノード対の挿入位置を決定するために、挿入するインデックスキーと検索により取得されたインデックスキーの間でビット列比較を行い、ビット列比較で異なるビット値となる先頭の（最上位の）ビット位置と探索経路スタックに格納されているブランチノードの弁別ビット位置との相対的位置関係を調べ、弁別ビット位置が上位となるブランチノードの次のブランチノードのリンク先を挿入するノード対の挿入位置とするものである。
【００９１】
例えば図２のカップルドノードツリーに“１１１０００ＸＸＸＸＸＸＸＸ”を挿入するとき、検索結果のインデックスキーは、ノード２１０ｈに対応する“１０１０１１ＸＸＸＸＸＸＸＸ”になる。挿入キー“１１１０００ＸＸＸＸＸＸＸＸ”とノード２１０ｈに対応するインデックスキー２９０ｈ“１０１０１１ＸＸＸＸＸＸＸＸ”のビット列比較により異なるビット値となる最上位のビット位置１が得られる。得られたビット位置１と探索経路スタックに積まれた配列番号の配列要素に格納されたブランチノードの弁別ビット位置との位置関係を弁別ビット位置が上位になるまでを順次探索経路スタックを逆にたどると、ルートノード２１０ａに至る。そこで探索経路スタックのポインタを１つ進め、ノード２１１ｂの配列番号を得る。挿入キー“１１１０００ＸＸＸＸＸＸＸＸ”はノード２１１ｂのリンク先に挿入される。
【００９２】
また、探索経路スタックを逆にたどりルートノードに至っても、ルートノードの弁別ビット位置が、先に求めたビット列比較で異なるビット値となる最上位のビット位置より上位のビット位置でないということは、そのカップルドノードツリーのインデックスキーの上位ビットで、ルートノードの弁別ビット位置より上位のビットの値は全て等しい場合である。そして、挿入するインデックスキーにおいて、初めてルートノードの弁別ビット位置より上位のビットの値に異なるビット値のものがあるということである。したがって、挿入するノード対はルートノードの直接のリンク先となり、ルートノードの弁別ビット位置は、既存のインデックスキーと異なる値である挿入キーの最上位ビットの位置に変わる。
【００９３】
次に、ステップＳ５２４以下の各ノードにデータを設定して挿入処理を完成させる処理について説明する。
ステップＳ５２４では探索経路スタックからスタックポインタの指す配列番号を取り出す。
【００９４】
ステップＳ５２５ａに進み、挿入キーの格納に必要な記憶領域をインデックスキーの記憶領域上に確保し、確保した記憶領域を指すポインタを取得する。
次にステップＳ５２５ｂにおいて、挿入キーを、ステップＳ５２５ａで得たポインタの指すインデックスキーの記憶領域に書き込む。
【００９５】
ステップＳ５２５ｃに進み、ステップＳ５１４で得た配列番号の指す配列要素のノード種別にリーフノードを示す１を、参照ポインタにステップＳ５２５ａで得たポインタを書き込む。
【００９６】
ステップＳ５２６に進み配列からステップＳ５２４で得た配列番号の配列要素を読み出す。
次にステップＳ５２７において、ステップＳ５１５で得た配列番号の配列要素にステップＳ５２６で読み出した内容を書き込む。
【００９７】
最後にステップＳ５２８において、ステップＳ５２４で得た配列番号の指す配列要素のノード種別にブランチノードを示す０を、弁別ビット位置にステップＳ５１７で得たビット位置を、代表ノード番号にステップＳ５１２で得た配列番号を書き込み、処理を終了する。
【００９８】
上述の図２のカップルドノードツリーに“１１１０００ＸＸＸＸＸＸＸＸ”を挿入する例では、ステップＳ５２５ｃにおいて、取得された空ノード対のノード［１］を挿入キー“１１１０００ＸＸＸＸＸＸＸＸ”への参照ポインタを保持するリーフノードとし、ステップＳ５２７において、ノード［０］にノード２１１ｂの内容を書き込む。そして、ステップＳ５２８において、ノード２１１ｂの弁別ビット位置にビット列比較により異なるビット値となる最上位のビット位置１を格納し、代表ノード番号には取得されたノード対の代表ノードが格納される配列要素の配列番号が格納される。
【００９９】
図８は、本発明の一実施形態におけるルートノードの挿入処理を含むリーフノードの挿入処理全体の処理フローを説明する図である。
ステップＳ５５１において、取得することを求められたカップルドノードツリーのルートノードの配列番号が登録済みであるか判定される。登録済みであれば、図５〜図７を用いて説明した通常の挿入処理が行われる。
【０１００】
ステップＳ５５１での判定が登録済みでなければ、まったく新しいカップルドノードツリーの登録、生成が始まることになる。
まず、ステップＳ５５２において、配列から空きのノード対を求め、そのノード対のうち代表ノードとなるべき配列要素の配列番号を取得する。次にステップＳ５５３において、ステップＳ５５２で得た配列番号に０を加えた配列番号を求める。（実際には、ステップＳ５５２で取得した配列番号に等しい。）次にステップＳ５５４ａにおいて、挿入キーの格納に必要な記憶領域をインデックスキーの記憶領域上に確保し、確保した記憶領域を指すポインタを取得する。続くステップＳ５５４ｂでは、挿入キーを、ステップＳ５５４ａで得たポインタの指す記憶領域に書き込む。さらにステップＳ５５４ｃでは、ステップＳ５５３で得た配列番号の配列要素すなわち挿入するルートノードに対応する配列要素の、ノード種別にリーフノードを示す１を、参照ポインタにステップＳ５５４ａで得たポインタを書き込む。そしてステップＳ５５６では、ステップＳ５５３で取得したルートノードの配列番号を登録して処理を終了する。
【０１０１】
先にも述べたように、インデックスキーの集合があるとき、そこから順次インデックスキーを取り出し、図８及び図５〜図７の処理を繰り返すことにより、インデックスキーの集合に対応した本発明のカップルドノードツリーを構築することができることは明らかで
ある。
【０１０２】
本出願人による上記先の出願における挿入処理と図５〜図８の挿入処理との違いは、挿入キーを配列３０９内に書き込むか、挿入キーはインデックスキーの記憶領域３１１に書き込んで配列３０９には参照ポインタを書き込むか、という違いである。
【０１０３】
この違いにより、上記先の出願よりも有利になった点は、記憶領域がより効率的に利用されるようになったという点である。図７のステップＳ５２５ａや図８のステップＳ５５４ａでは、挿入しようとするインデックスキーの長さに応じて必要最小限の記憶領域を確保すればよい。また、長いインデックスキーを利用する場合でも、配列３０９の各配列要素に無駄な空き領域が大量に生じることがない。また、インデックスキーの格納領域３１１は配列３０９と分離されているため、インデックスキーの長さが予め判明していなくてもよいという利点もある。
【０１０４】
一方、この違いのため上記先の出願に比べてステップ数が増えているが、追加されたステップは、図７のステップＳ５２５ａとＳ５２５ｂ、及び図８のＳ５５４ａとＳ５５４ｂであり、１回の挿入処理につき簡単なステップが２つ追加されるだけである。つまり、挿入処理で増える計算コストは少なく、利点に比べて無視することができる程度である。
【０１０５】
次に図９、図１０を参照して、本発明の一実施形態におけるカップルドノードツリーから特定のインデックスキーに対応するリーフノードを削除する処理フローを説明する。
図９は、削除処理の前段である検索処理の処理フローを示す図であり、図４に示した検索処理において削除キーを検索キーとしたものに相当する。ステップＳ９０１〜ステップＳ９１０ｂの処理は図４のステップＳ４０１〜ステップＳ４１０ｂに完全に対応するので説明は省略する。
【０１０６】
図９のステップＳ９１１において削除キーとステップＳ９１０ｂで得たインデックスキーを比較し、等しくなければ削除するインデックスキーはカップルドノードツリーに存在しないのであるから、削除は失敗となり、処理を終了する。等しければ次の処理、図１０のステップＳ９１２以下の処理に進む。
【０１０７】
図１０は、削除処理の後段の処理フローを説明する図である。
まず、ステップＳ９１２で探索経路スタックに２つ以上の配列番号が格納されているか判定する。２つ以上の配列番号が格納されていないということは、言い換えれば１つだけで、その配列番号はルートノードの格納された配列要素のものである。その場合はステップＳ９１８に移行し、ステップＳ９０１で得たルートノードの配列番号に係るノード対を削除する。次にステップＳ９１９に進み、登録されていたルートノードの配列番号を削除する。さらにステップＳ９２０ａに進み、削除キーと等しいインデックスキーが格納されていた記憶領域、すなわちステップＳ９１０ａで得た参照ポインタの指す記憶領域を解放して、処理を終了する。
【０１０８】
ステップＳ９１２において探索経路スタックに２つ以上の配列番号が格納されていると判定されたときはステップＳ９１３に進み、ステップＳ９０８で得た代表ノード番号にステップＳ９０７で得たビット値を反転した値を加算した配列番号を得る。この処理は、削除対象のインデックスキーに対応するリーフノードと対をなすノードの配置された配列番号を求めるものである。
【０１０９】
次にステップＳ９１４において、ステップＳ９１３で得た配列番号の配列要素の内容を読み出し、ステップＳ９１５において探索経路スタックのスタックポインタを１つ戻して配列番号を取り出す。
【０１１０】
次にステップＳ９１６に進み、ステップＳ９１４で読み出した配列要素の内容をステップＳ９１５で得た配列番号の配列要素に上書きする。この処理は、削除対象のインデックスキーが格納されたリーフノードへのリンク元であるブランチノードを上記リーフノードと対をなすノードに置き換えるものである。
【０１１１】
続くステップＳ９１７において、ステップＳ９０８で得た代表ノード番号に係るノード対を削除する。
最後にステップＳ９２０ａにおいて、上記のとおり、ステップＳ９１０ａで得た参照ポインタの指す記憶領域を解放し、処理を終了する。
【０１１２】
本出願人による上記先の出願における削除処理と図９〜図１０の削除処理との違いは、配列３０９のみを操作対象とするか、さらにインデックスキーの記憶領域３１１も操作対象とするかという違いである。
【０１１３】
この違いにより、ステップＳ９１０ｂでは間接参照の必要があり、ステップＳ９２０ａが追加されているので、先の出願の削除処理よりも図９〜図１０の削除処理ではステップ数が増えている。しかし、それにより増える計算コストに比べて、上述の利点の方が顕著である。
【０１１４】
図１１Ａ及び図１１Ｂは、図２に例示したカップルドノードツリーにおいて“０１１０１０”を削除キーとして削除処理を行う例を説明する図である。
図１１Ａに示したカップルドノードツリーは、ノード対２０１ｆ以下のノードは記載を省略している。削除対象のインデックスキー“０１１０１０”は一時記憶エリアである削除キー２７０に格納されている。探索経路スタック３１０のスタックポインタは配列番号２２１ｃ＋１を指しており、検索処理が完了したことを示している。図中太枠で囲まれたノードが検索処理でたどられたノードであり、その配列番号がルートノード２１０ａのものからリーフノード２１１ｄのものまで探索経路スタック３１０に積まれている。
【０１１５】
なお、ノード２１１ｄに対応するインデックスキー２９１ｄは“０１１０１０ＸＸＸＸＸＸＸＸ”と表記されているが、図１１Ａ及び図１１Ｂの例では、説明の簡単のため、インデックスキー２９１ｄにおける“ＸＸＸＸＸＸＸＸ”の部分にはビット値が存在せず、“０１１０１０ＸＸＸＸＸＸＸＸ”と“０１１０１０”が等しい場合を説明する。また、図２に示したインデックスキー２９１ｄ、２９１ｅ、２９０ｅ、２９０ｃをまとめて図１１Ａでは２９０という符号で表している。
【０１１６】
削除キーによる検索処理においては、まず始めにルートノード２１０ａの配列番号２２０を取得し、それを探索経路スタック３１０に格納する。ルートノード２１０ａの弁別ビット位置２３０ａが０であり、削除キーのビット位置０のビット値が０であるので、代表ノード番号２２０ａ＋０＝２２０ａが探索経路スタック３１０に格納される。
【０１１７】
するとノード２１０ｂが読み出され、弁別ビット位置２３０ｂが１であり、削除キーのビット位置１のビット値が１であるので、代表ノード番号２２０ｂ＋１が探索経路スタック３１０に格納される。
【０１１８】
次にノード２１１ｃが読み出され、弁別ビット位置２３１ｃが２であり、削除キーのビット位置２のビット値が１であるので、代表ノード番号２２１ｃ＋１が探索経路スタック３１０に格納される。配列番号が２２１ｃ＋１の配列要素に格納されたノード２１１ｄのノード種別２６１ｄは１であり、リーフノードであることを示している。このリーフノードに対応するインデックスキー２９１ｄは、参照ポインタ２８１ｄにより示される記憶領
域に格納されている。その記憶領域はインデックスキーの記憶領域３１１の一部である。そこで参照ポインタ２８１ｄの参照するインデックスキー２９１ｄを取り出すとその値は“０１１０１０”であり、削除キー２７０に格納された削除対象のインデックスキーと一致している。
【０１１９】
図１１Ａに示した状態において、削除対象のインデックスキーに対応するノード２１１ｄと対をなすノード２１０ｄの内容が読み出され、その内容が、探索経路スタック３１０のスタックポインタを１つ戻したところに格納されている配列番号２２０ｂ＋１の配列要素（ノード２１１ｃ）に書き込まれる。その後ノード対２０１ｄを削除し、インデックスキー２９１ｄを格納していた記憶領域を解放する。ノード対が削除された配列要素は空となり、再利用可能となる。また、解放されたインデックスキーの記憶領域も再利用可能である。
【０１２０】
図１１Ｂに示したカップルドノードツリーは、削除処理の終了後のものである。ノード２１１ｃのノード種別２６１ｃ、弁別ビット位置２３１ｃ、代表ノード番号２２１ｃには、括弧書きで示すように、ノード２１０ｄに格納されていた値がそのまま格納されている。
【０１２１】
次に、図１２Ａ及び図１２Ｂを参照して挿入処理の具体例を説明する。
図１２Ａに示すのは、ビット列“０１００ＸＸＸＸＸＸＸＸ”、“０００１ＸＸＸＸＸＸＸＸ”、“００００ＸＸＸＸＸＸＸＸ”をインデックスキーとして参照する参照ポインタを持つカップルドノードツリーである。これから挿入しようとする挿入キーは“００１１ＸＸＸＸＸＸＸＸ”である。図示のツリーはノード対１２０１ａ、１２０１ｂ、１２０１ｃで構成されている。
【０１２２】
ノード対１２０１ａの代表ノードはルートノード１２１０ａであり、弁別ビット位置には１が保持されている。ノード対１２０１ａの下位のノード対１２０１ｂの代表ノード１２１０ｂはブランチノードであり、弁別ビット位置には３が保持され、代表ノード１２１０ｂと対になるノード１２１１ｂはリーフノードであり、インデックスキー１２９１ｂ“０１００ＸＸＸＸＸＸＸＸ”への参照ポインタ１２８１ｂが保持されている。ブランチノードであるノード１２１０ｂはノード対１２０１ｃにリンクしている。
【０１２３】
ノード対１２０１ｃを構成するノード１２１０ｃと１２１１ｃはともにリーフノードであり、それぞれインデックスキー１２９０ｃ“００００ＸＸＸＸＸＸＸＸ”とインデックスキー１２９１ｃ“０００１ＸＸＸＸＸＸＸＸ”への参照ポインタ１２８０ｃ、１２８１ｃが格納されている。
【０１２４】
図１２Ｂは、挿入キー“００１１ＸＸＸＸＸＸＸＸ”を挿入したカップルドノードツリーを示す図である。新たなノード対１２０１ｄがノード対１２０１ｂとノード対１２０１ｃの間に挿入されている。
【０１２５】
図１２Ａと図１２Ｂを比べると、挿入されたノード１２１０ｄの内容は、挿入前のノード１２１０ｂのものであり、挿入後のノード１２１０ｂの弁別ビット位置が３から２に変化している。
【０１２６】
以上本発明を実施するための最良の形態について詳細に説明したが、本発明の実施の形態はそれに限ることなく種々の変形が可能であることは当業者に明らかである。
また、本発明のビット列検索方法を実行する装置が、カップルドノードツリーを格納する記憶手段と図４に示した処理をコンピュータに実行させるプログラムによりコンピュータ上に構築可能なことは明らかである。
【０１２７】
さらに、図８、図５〜図７に示した挿入処理とその均等物をコンピュータに実行させるプログラムにより、本発明の挿入方法が実現可能であり、図９及び図１０に示した削除処理とその均等物をコンピュータに実行させるプログラムにより、本発明の削除方法が実現可能であることも明らかである。そして、それらのプログラムにより、ブランチノードとリーフノードの識別手段、ブランチノードの弁別ビット位置に応じてリンク先のノード対のどちらかにリンクする手段等がコンピュータ上に実現される。
【０１２８】
したがって、上記プログラム、及びプログラムを記憶したコンピュータ読み取り可能な記憶媒体は、本発明の実施の形態に含まれる。さらに、本発明のカップルドノードツリーのデータ構造も、本発明の実施の形態に含まれる。
【０１２９】
以上詳細に説明した、本発明が提供する新しいデータ構造であるカップルドノードツリーを用いることにより、記憶領域をより有効に利用してより高速なビット列データの検索を行うことが可能となり、しかもビット列データの追加削除も容易に実行することができる。
【図面の簡単な説明】
【０１３０】
【図１】配列に格納されたカップルドノードツリーの構成例を説明する図である。
【図２】カップルドノードツリーのツリー構造を概念的に示す図である。
【図３】本発明を実施するためのハードウェア構成例を説明する図である。
【図４】本発明の一実施形態における検索処理を示すフローチャートである。
【図５】本発明の一実施形態における挿入処理の前段である検索処理の処理フローを示す図である。
【図６】本発明の一実施形態における挿入処理における挿入するノード対のための配列要素を準備する処理フローを説明する図である。
【図７】ノード対を挿入する位置を求め、ノード対の各ノードの内容を書き込んで挿入処理を完成させる処理フローを示す図である。
【図８】本発明の一実施形態におけるルートノードの挿入処理を含むリーフノードの挿入処理全体の処理フローを説明する図である。
【図９】本発明の一実施形態における削除処理の前段である検索処理の処理フローを示す図である。
【図１０】本発明の一実施形態における削除処理の後段の処理フローを説明する図である。
【図１１Ａ】削除処理前のカップルドノードツリーと削除キー“０１１０１０”を説明する図である。
【図１１Ｂ】削除処理後のカップルドノードツリーを説明する図である。
【図１２Ａ】挿入処理前のカップルドノードツリーと挿入キー“００１１”を説明する図である。
【図１２Ｂ】挿入処理後のカップルドノードツリーを説明する図である。
【図１３】従来の検索で用いられるパトリシアツリーの一例を示す図である。
【符号の説明】
【０１３１】
１０、２０、３０  配列番号
１００  配列
１０１  ノード
１０２、１１４、１１７、１２４、１２６、２６０ａ〜２６０ｈ、２６１ｂ〜２６１ｈ
ノード種別
１０３、１１５、２３０ａ〜２３０ｆ、２３１ｂ〜２３１ｆ  弁別ビット位置
１０４、１１６、２２０、２２０ａ〜２２０ｆ、２２１ｂ〜２２１ｆ  代表ノード番号
１１１、１２１、２０１ａ〜２０１ｈ、１２０１ａ〜１２０１ｄ  ノード対
１１２、１２２、２１０ａ〜２１０ｈ、１２１０ａ〜１２１０ｄ  ノード［０］、代表ノード
１１３、１２３、２１１ｂ〜２１１ｈ、１２１１ａ〜１２１１ｄ  ノード［１］、代表ノードと対をなすノード
１１８ａ、２５０ｃ〜２５０ｈ、２５１ｄ〜２５１ｈ  参照ポインタ
２７０  削除キー
２８０ｃ〜２８０ｈ、２８１ｄ〜２８１ｈ、１２８０ｃ、１２８１ｂ〜１２８１ｄ  参照ポインタ
２９０、２９０ｃ〜２９０ｈ、２９１ｄ〜２９１ｈ、１２９０ｃ、１２９１ｂ〜１２９１ｄ  インデックスキー
３０１  データ処理装置
３０２  中央処理装置
３０３  キャッシュメモリ
３０４  バス
３０５  主記憶装置
３０６  外部記憶装置
３０７  通信装置
３０８  データ格納装置
３０９  配列
３１０  探索経路スタック
３１１  インデックスキーの記憶領域
１７３０ａ〜１７３０ｈ  検査ビット位置
１７４０ａ〜１７４０ｆ  左リンク、左ポインタ
１７４１ａ〜１７４１ｆ  右リンク、右ポインタ
１７５０ａ〜１７５０ｈ  ノード
【図１】
2008269503.tif 000003
【図２】
2008269503.tif 000004
【図３】
2008269503.tif 000005
【図４】
2008269503.tif 000006
【図５】
2008269503.tif 000007
【図６】
2008269503.tif 000008
【図７】
2008269503.tif 000009
【図８】
2008269503.tif 000010
【図９】
2008269503.tif 000011
【図１０】
2008269503.tif 000012
【図１１Ａ】
2008269503.tif 000013
【図１１Ｂ】
2008269503.tif 000014
【図１２Ａ】
2008269503.tif 000015
【図１２Ｂ】
2008269503.tif 000016
【図１３】
2008269503.tif 000017