これらの目的の1つ又は複数は、独立クレームの趣旨により達成される。好ましい実施形態は従属クレームの趣旨である。
本発明は、Bツリー及び導関数がなお主要戦略であるデータベースアプリケーションの索引付け解決策及び通常、逆インデックスが使用される情報検索アプリケーションの索引付け解決策を提供する。逆インデックスとは、言葉が、その言葉を含むドキュメントを列挙するインデックスである。トライはレベル毎に処理されるため、本発明は、階層トライ構造を利用して、遅延評価を可能にすることができる。したがって、本発明は、第1レベルのトライを連想配列として使用して、逆インデックスを実施することができ、ここで、言葉はトライ内に格納されたキーである。第2レベル(すなわち、連想配列のリーフノードとして)において、本発明はトライを集合として使用して、ドキュメントのリスト(すなわち、IDの集合)を実施することができる。したがって、本発明では、Bツリー及び逆インデックスを1つの汎用解決策で置換することができ、したがって、この1つの汎用解決策を「コンフルエンスインデックス(confluence index)」と呼称することができる。
本発明のインデックスデータ構造及びクエリ処理モデルは、ビット単位のトライに基づき、従来技術によるインデックス構造に取って代わる潜在性を有する:データ構造は頻繁に更新することができ、低基数及び高基数を有するキーに対して機能し、圧縮/圧縮解除(データ構造はコンパクトであり、又は幾つかの場合、簡潔でさえある)なしで空間効率的である。加えて、トライに基づくため、キー演算による挿入、更新、削除、及びクエリにO(|M|)一定時間複雑性を継承する(|M|はキーの長さ)。これは、ツリーに基づく手法にとって通常のO(logn)複雑性よりもよい(nはインデックス内のキーの数である)。そして、本発明のインデックスデータ構造及びクエリ処理モデルは、データベースの充填から独立したクエリ時間を提供することができる。好ましい実施形態では、クエリ処理での設定演算子の結果は、トライとして「見える」。これにより、機能構成及び遅延評価が可能になる。副次的影響として、物理代数は論理代数にそのまま対応し、クエリオプティマイザで通常行われる所与のクエリに適した物理的実行プランを作成するタスクを簡易化する。本発明の第1の実施形態は、電子データベースアプリケーション又は情報検索システムで使用されるトライであり、トライは1つ又は複数のノードを含み、2つ以上の子ノードを有する、トライに含まれる親ノード、好ましくは各親ノードは、ビットマップ及び1つ又は複数のポインタを含み、各ポインタにはビットマップにおいて設定されたビットが関連付けられ、各ポインタは親ノードの子ノードを指す。トライは、1つのみの子ノードを有する、トライに含まれる親ノード、好ましくは、親ノードは、子ノードへのポインタを含まず、及び/又は子ノードは、メモリにおいて、親ノードに相対して予め定義された位置に格納されることを特徴とする。
第2の実施形態によれば、第1の実施形態において、1つのみの子ノードを有する親ノードの子ノードは、メモリにおいて、親ノードの直後の位置に格納される。
第3の実施形態によれば、第1又は第2の実施形態において、ノード、好ましくは各子ノードには、キー部分が関連付けられ、トライ内のルートノードから別のノード、特にリーフノードへのパスがキーを定義し、キーは、パス内のノードに関連付けられたキー部分を連結したものである。
末端最適化
本発明の第4の実施形態は、電子データベースアプリケーション又は情報検索システムで使用されるトライであり、トライは1つ又は複数のノードを含み、2つ以上の子ノードを有する、トライに含まれる親ノード、好ましくは少なくとも各親ノードはビットマップを含み、ノード、好ましくは各子ノードには、キー部分が関連付けられ、親が2つ以上の子ノードを有する、子ノード、好ましくは少なくとも各子ノードのキー部分の値は、子ノードが関連付けられたビットを有する親ノードに含まれるビットマップ内の(設定)ビットの値によって決まる。トライは、1つのみの子ノードを有し、全ての子孫ノードが多くとも1つの子ノードを有するノード、好ましくは各ノードは、末端分岐ノードと記され、末端分岐ノード、好ましくは各末端分岐ノードの子孫ノード、好ましくは各子孫ノードに関連付けられたキー部分の値は、子孫ノードの親ノードに含まれるビットマップ内の(設定)ビットの値によって決まらないことを特徴とする。
第5の実施形態によれば、第4の実施形態において、末端分岐ノードは2つ以上の子孫ノードを有する。
第6の実施形態によれば、第4又は第5の実施形態において、末端分岐ノードの親は2つ以上の子ノードを有する。
第7の実施形態によれば、第4〜第6の実施形態において、末端分岐ノードとしての記しは、ビットが設定されていないビットマップである。
第8の実施形態によれば、第7の実施形態において、末端分岐ノードのビットマップは、2つ以上の子ノードを有する親ノードに含まれるビットマップと同じ長さ又はフォーマットを有する。
第9の実施形態によれば、第4〜第8の実施形態の何れか1つにおいて、トライに含まれる末端分岐ノード、好ましくは各末端分岐ノード及び/又は末端分岐ノードの子孫ノード、好ましくは各子孫ノードは、子ノードへのポインタを含まず、及び/又は子ノードは、メモリにおいて、親ノードに相対して予め定義された位置に、好ましくは、メモリにおいて親ノードの直後の位置に格納される。
第10の実施形態によれば、第4〜第9の実施形態の何れか1つにおいて、末端分岐ノード、好ましくは各末端分岐ノードの子孫ノード、好ましく各子孫ノードに関連付けられたキー部分の値は、子孫ノードの親ノードに含まれる。
第11の実施形態によれば、第4〜第10の実施形態の何れか1つにおいて、末端分岐ノード、好ましくは各末端分岐ノードの子孫ノード、好ましくは全ての子孫ノードに関連付けられたキー部分の値は、末端分岐ノード後に連続して格納される。
第12の実施形態によれば、第4〜第11の実施形態の何れか1つにおいて、末端分岐ノード、好ましくは各末端分岐ノードの子孫ノード、好ましくは各子孫ノードに関連付けられたキー部分の値の符号化は、2つ以上の子ノードを有する親ノードに含まれるビットマップよりも、必要とするメモリ空間が少ない。
第13の実施形態によれば、第4〜第12の実施形態の何れか1つにおいて、末端分岐ノード、好ましくは各末端分岐ノードの子孫ノード、好ましくは各子孫ノードに関連付けられたキー部分の値は、二進数として符号化される。
第14の実施形態によれば、第4〜第13の実施形態の何れか1つにおいて、2つ以上の子ノードを有する親ノード、好ましくは各親ノードに含まれるビットマップは、32ビット、64ビット、128ビット、又は256ビットを有し、末端分岐ノード、好ましくは各末端分岐ノードの子孫ノード、好ましくは各子孫ノードに関連付けられたキー部分は、5ビット、6ビット、7ビット、又は8ビットによりそれぞれ符号化される。
第15の実施形態によれば、第4〜第14の実施形態の何れか1つにおいて、末端分岐ノード、好ましくは各末端分岐ノードの子孫ノード、好ましくは各子孫ノードに関連付けられたキー部分の値は、整数値として符号化される。
第16の実施形態によれば、第4〜第14の実施形態の何れか1つにおいて、親ノードである末端分岐ノードの子孫ノード、好ましくは、親ノードである各子孫ノードは、設定ビットが子ノードに関連付けられたキー部分の値を決めるビットマップを含まない。
第17の実施形態によれば、第4〜第16の実施形態の何れか1つにおいて、2つ以上の子ノードを有する、トライに含まれる親ノード、好ましくは、少なくとも各親ノードは、1つ又は複数のポインタを含み、各ポインタには、親ノードに含まれるビットマップに設定されたビットが関連付けられ、各ポインタは親ノードの子ノードを指す。
第18の実施形態によれば、第4〜第17の実施形態の何れか1つにおいて、トライは第1又は第2の実施形態によるトライである。
ビットマップ圧縮
本発明の第19の実施形態は、電子データベースアプリケーション又は情報検索システムで使用されるトライであり、トライは1つ又は複数のノードを含み、2つ以上の子ノードを有するノード、好ましくは少なくとも各親ノードは、論理ビットマップの形態のビットマップ及び幾つかのポインタを含み、各ポインタには論理ビットマップにおいて設定されたビットが関連付けられ、各ポインタはノードの子ノードを指す。トライは、論理ビットマップが複数のセクションに分割され、ヘッダビットマップ及び幾つかのコンテンツビットマップにより符号化され、各セクションには、ヘッダビットマップ内のビットが関連付けられ、1つ又は複数のビットが設定された論理ビットマップの各セクションについて、ヘッダビットマップにおいて、セクションに関連付けられたビットは設定され、セクションはコンテンツビットマップとして格納されることを特徴とする。
第20の実施形態によれば、第19の実施形態において、ビットが設定されていない論理ビットマップの各セクションについて、ヘッダビットマップにおいて、セクションに関連付けられたビットは設定されず、セクションはコンテンツビットマップとして格納されない。
第21の実施形態によれば、第19又は第20の実施形態の何れかにおいて、セクションのそれぞれはコヒーレントである。
第22の実施形態によれば、第19〜第21の実施形態の何れかにおいて、全てのセクションは同じサイズを有する。
第23の実施形態によれば、第22の実施形態において、セクションのサイズは1バイトである。
第24の実施形態によれば、第19〜第23の実施形態の何れか1つにおいて、コンテンツビットマップとして記憶されるセクションの量は、ヘッダビットマップにおいて設定されたビット数に等しい。
第25の実施形態によれば、第19〜第24の実施形態の何れか1つにおいて、ヘッダビットマップのサイズは1バイトである。
第26の実施形態によれば、第19〜第25の実施形態の何れか1つにおいて、コンテンツビットマップは、メモリにおいてヘッダビットマップに相対して予め定義された位置に格納される。
第27の実施形態によれば、第19〜第26の実施形態の何れか1つにおいて、論理ビットマップのコンテンツビットマップは、配列、リスト、又は連続した物理若しくは仮想メモリロケーションに格納される。
第28の実施形態によれば、第19〜第27の実施形態の何れか1つにおいて、コンテンツビットマップは、コンテンツビットマップのセクションに関連付けられた設定ビットがヘッダビットマップに配置される順と同順又は逆順で格納される。
第29の実施形態によれば、第19〜第28の実施形態の何れか1つにおいて、論理ビットマップの全てのコンテンツビットマップ内のあるコンテンツビットマップのランクは、ヘッダビットマップ内の全ての設定ビット内の、コンテンツビットマップのセクションに関連付けられた設定ビットのランクに対応する。
第30の実施形態によれば、第19〜第29の実施形態の何れか1つにおいて、ノードに含まれるポインタ、好ましくはノードの各ポインタ及び/又はリーフノードではない各ノードのポインタは、第19〜第29の実施形態の何れか1つにおける論理ビットマップに定義された符号化方法で符号化される。
第31の実施形態によれば、第19〜第30の実施形態の何れか1つにおいて、トライは第1〜第18の実施形態の何れか1つにおけるトライである。
第32の実施形態によれば、第19〜第31の実施形態の何れか1つにおいて、ノード、好ましくは各子ノードにはキー部分が関連付けられ、ルートノードからトライ内の別のノード、特にリーフノードへのパスはキーを定義し、キーは、パス内のノードに関連付けられたキー部分を連結したものである。
制御情報を含むキー
本発明の第33の実施形態は、電子データベースアプリケーション又は情報検索システムで使用されるトライであり、トライは1つ又は複数のノードを含み、ノード、好ましく各子ノードにはキー部分が関連付けられ、ルートノードからトライ内の別のノード、特にリーフノードへのパスはキーを定義し、キーは、パス内のノードに関連付けられたキー部分を連結したものである。トライは、キーが制御情報及びコンテンツ情報を含むことを特徴とする。
第34の実施形態によれば、第33の実施形態において、キーは、コンテンツ情報を含む1つ又は複数のキー部を含み、キー部のそれぞれについて、制御情報は、キー部に含まれるコンテンツ情報のデータ型を指定するデータ型情報要素を含む。
第35の実施形態によれば、第34の実施形態において、キー部、好ましくは各キー部は、キー部に含まれるコンテンツ情報のデータ型を指定するデータ型情報要素を含む。
第36の実施形態によれば、第35の実施形態において、データ型情報要素は、好ましくはコンテンツ情報要素前に、コンテンツ情報要素により配置される。
第37の実施形態によれば、第34の実施形態において、データ型情報要素は一緒に配置され、好ましくは、データ型が指定されるコンテンツ情報要素と同順又は逆順で配置される。
第38の実施形態によれば、第37の実施形態において、制御情報は、キーにおいてコンテンツ情報前に配置される。
第39の実施形態によれば、第34〜第38の実施形態の何れか1つにおいて、キーは、異なるデータ型のコンテンツ情報を含む2つ以上のキー部を含む。
第40の実施形態によれば、第34〜第39の実施形態の何れか1つにおいて、データ型の少なくとも1つは、固定サイズのデータ型である。
第41の実施形態によれば、第40の実施形態において、固定サイズのデータ型は整数、長整数、倍精度浮動小数点、又は時刻/日付けプリミティブである。
第42の実施形態によれば、第34〜第41の実施形態の何れか1つにおいて、データ型の少なくとも1つは、可変サイズのデータ型である。
第43の実施形態によれば、第42の実施形態において、可変サイズのデータ型は、文字列、好ましくはユニコード文字列、又は可変精度整数である。
第44の実施形態によれば、第34〜第43の実施形態の何れか1つにおいて、キー部の情報は、2つ以上のキー部分に含まれる。
第45の実施形態によれば、第34〜第44の実施形態の何れか1つにおいて、キー部に含まれるコンテンツ情報のデータ型は、可変サイズのデータ型であり、コンテンツ情報要素の終わりは、特定のシンボルにより又はキー部を含むキー部分の特定の1つ内の特定のビットにより記される。
第46の実施形態によれば、第34〜第45の実施形態の何れか1つにおいて、制御情報は、最後のキー部を識別する情報を含む。
第47の実施形態によれば、第33〜第46の実施形態の何れか1つにおいて、制御情報は、トライが動的集合の格納に使用されるか、それとも連想配列の格納に使用されるかについての情報を含む。
第48の実施形態によれば、第33〜第47の実施形態の何れか1つにおいて、トライは、第1〜第32の何れか1つによるトライである。
第49の実施形態によれば、第33〜第48の実施形態の何れか1つにおいて、2つ以上の子ノードを有するノード、好ましくは少なくとも各親ノードは、ビットマップ及び幾つかのポインタを含み、各ポインタには、ビットマップにおいて設定されたビットが関連付けられ、各ポインタはノードの子ノードを指す。
インタリーブ多項目キー
本発明の第50の実施形態は、電子データベースアプリケーション又は情報検索システムで使用されるトライであり、トライは1つ又は複数のノードを含み、ノード、好ましくは各子ノードにはキー部分が関連付けられ、トライ内のルートノードから別のノード、特にリーフノードへのパスが、ノードが関連付けられたキーを定義し、キーは、パス上のノードに関連付けられたキー部分を連結したものである。トライは、2つ以上のデータ項目はキーにおいて符号化され、データ項目の最後における1つ又は2つ、好ましくは各データ項目は、2つ以上の構成要素からなり、キーは2つ以上の連続セクションを含み、セクションの少なくとも1つ又は2つ、好ましくは各セクションは、キーに符号化されたデータ項目の2つ以上の構成要素を含むことを特徴とする。
第51の実施形態によれば、第50の実施形態において、キーのセクション、好ましくは各セクションは、キーに符号化されたデータ項目のそれぞれから少なくとも及び/又は多くとも1つの構成要素を含む。
第52の実施形態によれば、第50又は第51の実施形態の何れか1つにおいて、キーの2つ以上、好ましくは全てのセクションについて、異なるデータ項目に属する構成要素は、セクション内で同じ順序で並べられる。
第53の実施形態によれば、第50〜第52の実施形態の何れか1つにおいて、データ項目の構成要素を含むセクションの順序は、データ項目内の構成要素の順序に対応する。
第54の実施形態によれば、第50〜第53の実施形態の何れか1つにおいて、子ノード、好ましくは子ノードのそれぞれに関連付けられたキー部分は、データ項目の構成要素の一部に対応する。
第55の実施形態によれば、第50〜第53の実施形態の何れか1つにおいて、子ノード、好ましくは子ノードのそれぞれに関連付けられたキー部分は、データ項目の1つの構成要素に対応し、及び/又はデータ項目、好ましくは各データ項目の構成要素、好ましくは各構成要素は、トライの1つの子ノードに関連付けられたキー部分に対応する。
第56の実施形態によれば、第50〜第53の実施形態の何れか1つにおいて、子ノード、好ましくは子ノードのそれぞれに関連付けられたキー部分は、データ項目の2つ以上の構成要素に対応する。
第57の実施形態によれば、第50〜第56の実施形態の何れか1つにおいて、キーのデータ項目の2つ以上、好ましくは全ては、同じ数の構成要素を有する。
データ項目及びその構成要素のタイプ
第58の実施形態によれば、第50〜第57の実施形態の何れか1つにおいて、2つ以上のデータ項目はジオロケーションデータを表す。
第59の実施形態によれば、第50〜第58の実施形態の何れか1つにおいて、データ項目は、経度、緯度、文字列、又はこれらの2つ以上の組合せを表す。
第60の実施形態によれば、第50〜第59の実施形態の何れか1つにおいて、データ項目の構成要素は、データ項目の二進符号化のビット群である。
第61の実施形態によれば、第60の実施形態において、ビット群は6ビットを含む。
第62の実施形態によれば、第50〜第61の実施形態の何れか1つにおいて、データ項目は数である。
第63の実施形態によれば、第62の実施形態において、データ項目は整数、長整数、又は倍長整数である。
第64の実施形態によれば、第62又は第63の実施形態の何れか1つにおいて、データ項目は64ビット整数である。
第65の実施形態によれば、第62〜第64の実施形態の何れか1つにおいて、データ項目の構成要素は数字である。
第66の実施形態によれば、第65の実施形態において、数字は予め定義された基数、好ましくは64を有する。
第67の実施形態によれば、第50〜第66の実施形態の何れか1つにおいて、データ項目は文字列である。
第68の実施形態によれば、第67の実施形態において、データ項目の構成要素は1文字である。
第69の実施形態によれば、第50〜第68の実施形態の何れか1つにおいて、データ項目はバイトの配列である。
第70の実施形態によれば、第50〜第69の実施形態の何れか1つにおいて、トライは第1〜第49の実施形態の何れか1つにおけるトライである。
第71の実施形態によれば、第70の実施形態において、第34の実施形態に従属する場合、データ項目は、キー部又はキー部に含まれるコンテンツ情報に対応する。
第72の実施形態によれば、第33〜第71の実施形態の何れか1つにおいて、2つ以上の子ノードを有するノード、好ましくは少なくとも各親ノードは、ビットマップ及び幾つかのポインタを含み、各ポインタにはビットマップにおいて設定されたビットが関連付けられ、各ポインタはノードの子ノードを指す。
一般的なトライ特徴
ビットマップ及びメモリの詳細
第73の実施形態によれば、第1〜32、第49、又は第72の実施形態の何れか1つにおいて、ビットマップは、予め定義されたサイズの整数としてメモリに記憶される。
第74の実施形態によれば、第1〜第32、第49、第72、又は第73の実施形態の何れか1つにおいて、ビットマップのサイズは32ビット、64ビット、128ビット、又は256ビットである。
第75の実施形態によれば、第1〜第32、第49、又は第72〜第74の実施形態の何れか1つにおいて、トライは、標的コンピュータシステムで格納され処理されるのに適し、ビットマップのサイズは、標的コンピュータシステムのCPUのレジスタ、システムバス、データバス、及び/又はアドレスバスのビット幅に等しい。
第76の実施形態によれば、第1〜第32、第49、又は第72〜第75の実施形態の何れか1つにおいて、トライのビットマップ及び/又はポインタ及び/又はノードは、配列、好ましくは長整数若しくはバイトのインアンド配列、リスト、又は連続した物理若しくは仮想メモリロケーションに格納される。
第77の実施形態によれば、第1〜第16、第26、第27、又は第76の実施形態の何れか1つにおいて、メモリは、物理若しくは仮想メモリ、好ましくは連続メモリであり、又は物理若しくは仮想メモリ、好ましくは連続メモリを含む。
ポインタ
第78の実施形態によれば、第1〜第32、第49、又は第72〜第77の実施形態の何れか1つにおいて、2つ以上の子ノードを有する親ノード、好ましくは少なくとも各親ノードに含まれるポインタの量は、前記親ノードに含まれるビットマップにおいて設定されたビット量に等しい。
第79の実施形態によれば、第1〜第32、第49、又は第72〜第78の実施形態の何れか1つにおいて、親ノードの全てのポインタ内のあるポインタのランクは、親ノードのビットマップ内の全ての設定ビット内のそのポイントに関連付けられた設定ビットのランクに対応する。
第80の実施形態によれば、第1〜第32、第49、又は第72〜第79の実施形態の何れか1つにおいて、ポインタは、ビットがビットマップにおいて設定されるのと同順又は逆順に格納される。
第81の実施形態によれば、第1〜第33、第49、又は第72〜第80の実施形態の何れか1つにおいて、親ノードに含まれるポインタは、子ノードに含まれるビットマップを指す。
第82の実施形態によれば、第1〜第33、第49、又は第72〜第81の実施形態の何れか1つにおいて、トライのリーフノード、好ましくは各リーフノードに含まれるポインタの数はゼロである。
キー部分
第83の実施形態によれば、第3、又は第33〜第82の実施形態の何れか1つにおいて、親が2つ以上の子ノードを有する子ノード、好ましくは少なくとも各子ノードのキー部分の値は、ビットが子ノードに関連付けられた親ノードに含まれるビットマップ内の(設定)ビットの値によって決まる。
第84の実施形態によれば、第4〜第18又は第83の実施形態の何れか1つにおいて、キー部分に利用可能な異なる値の最大量は、ビットマップのサイズによって定義される。
第85の実施形態によれば、第4〜第18、第83、又は第84の実施形態の何れか1つにおいて、ビットマップのサイズは、キー部分に可能な英字を定義する。
第86の実施形態によれば、第3又は第32〜第85の実施形態の何れか1つにおいて、トライ内の各キー部分は、同じ予め定義されたサイズの値を格納可能である。
第87の実施形態によれば、第86の実施形態において、予め定義されるサイズは、5ビット値、6ビット値、7ビット値、又は8ビット値に対応する。
効率的な範囲クエリのキー符号化
第88の実施形態によれば、第1〜第87の実施形態の何れか1つにおいて、データ項目の値、好ましくは全てのデータ項目の値の符号化は、データ項目のデータ型を符号なし整数を本質的な特徴とするオフセット二進数表現に変換することによって得られる。
第89の実施形態によれば、第88の実施形態において、整数は長整数である。
第90の実施形態によれば、第88又は第89の実施形態の何れか1つにおいて、データ項目のデータ型が浮動小数点数である場合、符号化は、データ項目のデータ型をオフセット二進数表現に変換することによって得られる。
第91の実施形態によれば、第88〜第90の実施形態の何れか1つにおいて、データ項目のデータ型が2の補数の符号付き整数である場合、符号化は、データ項目のデータ型をオフセット二進数表現に変換することによって得られる。
他
第92の実施形態によれば、第1〜第91の実施形態の何れか1つにおいて、トライは、動的集合又は連想配列を格納する。
トライへのブール演算
本発明の第93の実施形態は、電子データベース又は情報検索システムからデータを検索する方法であって、2つ以上の入力トライの表現を取得するステップと、結果トライの少なくとも部分を評価するステップであって、結果トライは、論理演算を使用した入力トライの組合せである、評価するステップと、出力として、結果トライの表現、結果トライのノードに関連付けられたキー及び/又は他のデータ項目の集合若しくは部分集合、又は結果トライのノードに関連付けられたキーから導出されるキー若しくは値の集合を提供するステップとを含む。
第94の実施形態によれば、第93の実施形態において、結果トライのリーフに関連付けられたキー及び/又は他のデータ項目は、出力として提供される。
第95の実施形態によれば、第93又は94の実施形態において、出力として提供されるキーの集合は、トライで提供される。
第96の実施形態によれば、第93又は94の実施形態の何れか一方において、出力として提供されるキーの集合は、カーソル又は反復子として提供される。
第97の実施形態によれば、第93〜96の実施形態の1つにおいて、トライの部分はノード及び/又はトライの分岐である。
第98の実施形態によれば、第93〜97の何れか1つにおいて、トライの表現は、物理的トライデータ構造又はトライを評価することが可能なトライ演算子へのハンドルである。
第99の実施形態によれば、第93〜98の実施形態の何れか1つにおいて、トライの表現は、トライのルートノードを表し、トライノードインターフェースを実装し、トライノードインターフェースは、トライノードを表し、それが表すトライノードの子ノードをクエリ及び/又はトラバースする方法又は関数を提供する。
第100の実施形態によれば、第93〜99の実施形態の何れか1つにおいて、トライ又はトライの部分を評価することは、トライ又はトライの部分をトラバースすることを含む。
第101の実施形態によれば、第100において、トライ又はトライの部分を評価することは、トラバースされたノードがトライに存在することの情報を提供することを含む。
第102の実施形態によれば、第100又は101の実施形態の何れか一方において、トライ又はトライの部分を評価する間、任意の所与の瞬間において、トライ又はトライの部分のトラバースのためにその瞬間に実現する必要がある、トライ又はトライの部分の物理的データ構造の少なくとも部分が実現される。
第103の実施形態によれば、実施形態100〜102の何れか1つにおいて、任意の所与の瞬間において、トライ又はトライの部分の物理的データ構造の全体未満が実現され、好ましくは、トライ又はトライの部分のトラバースのためにその瞬間に実現する必要がある、トライ又はトライの部分の物理的なデータ構造の部分のみが実現される。
第104の実施形態によれば、実施形態93〜102の何れか1つにおいて、トライ又はトライの部分を評価することは、トライ又はトライの部分の物理的データ構造を全体として実現することを含む。
第105の実施形態によれば、実施形態93〜104の何れか1つにおいて、入力トライの少なくとも1つは、結果トライの少なくとも部分を評価するステップ中に少なくとも部分が評価される仮想トライである。
第106の実施形態によれば、実施形態105において、少なくとも、仮想トライの表現を取得する瞬間において、仮想トライの物理的データ構造は全体として存在しない。
第107の実施形態によれば、実施形態105又は106の何れか一方において、仮想トライ又は仮想トライの部分の物理的データ構造は全体として実現されない。
第108の実施形態によれば、実施形態105〜107の何れか1つにおいて、少なくとも、結果トライの少なくとも部分の評価に必要な仮想トライの部分が評価される。
第109の実施形態によれば、実施形態105〜108の何れか1つにおいて、結果トライの少なくとも部分の評価に必要ない仮想トライの部分の少なくとも幾つかは、評価されず、好ましくは、結果トライの少なくとも部分の評価に必要な仮想トライの部分のみが評価される。
第110の実施形態によれば、実施形態105〜109の何れか1つにおいて、仮想トライの少なくとも部分は、結果トライの少なくとも部分が評価された後、評価される。
第111の実施形態によれば、実施形態105〜110の何れか1つにおいて、結果トライの部分及び仮想トライの部分は、インタリーブ方式で評価される。
第112の実施形態によれば、実施形態105〜111の何れか1つにおいて、2つ以上の入力トライは高次入力トライであり、結果トライは高次結果トライであり、少なくとも1つの仮想トライの表現は、2つ以上の低次入力トライの表現を取得するステップと、低次結果トライを少なくとも部分的に評価するステップであって、低次結果トライは低次入力トライの低次論理演算を使用した結合である、評価するステップと、低次結果トライの表現を出力として提供するステップとを実行する低次結合演算子の出力として提供される。
第113の実施形態によれば、実施形態112において、低次結果トライの表現を出力として提供するステップは、低次結果トライを少なくとも部分的に評価するステップが完了する前、実行される。
第114の実施形態によれば、実施形態112又は113の何れか一方において、低次論理演算は、高次論理演算と同じ論理演算である。
第115の実施形態によれば、実施形態112又は113の何れか一方において、低次論理演算は、高次論理演算と異なる論理演算である。
第116の実施形態によれば、実施形態112〜115の何れか1つにおいて、低次入力トライの少なくとも1つは、表現が低次結合演算子の出力として提供される、必要な変更を加えた実施形態105〜111の何れか1つにおいて定義される仮想トライである。
第117の実施形態によれば、実施形態93〜116の何れか1つにおいて、入力トライは、電子データベース若しくは情報検索システムに記憶されたキーの集合又は電子データベース若しくは情報検索システムに記憶されたキーの1つ若しくは複数の集合から導出された結果キーの集合を記憶する。
第118の実施形態によれば、実施形態93〜117の何れか1つにおいて、トライは1つ又は複数のノードを含み、各子ノードにはキー部分が関連付けられ、ルートノードからトライにおける別のノードへのパスは、ノードに関連付けられるキーを定義し、キーは、パス上のノードに関連付けられたキー部分を連結したものである。
第119の実施形態によれば、実施形態93〜118の何れか1つにおいて、論理演算を使用した2つ以上の入力トライの結合は、各入力トライにより記憶されたキーの各集合が論理演算を使用して結合される場合に取得されるキーの集合を記憶するトライである。
第120の実施形態によれば、実施形態93〜119の何れか1つにおいて、論理演算が差である場合、結果トライの親ノードは第1の入力トライの親ノードであり、結果トライの親ノードのリーフは、第1の入力トライ内の対応する親ノードの子ノードの集合と他の入力トライ内の任意の対応する親ノードの子ノードの集合との論理演算を使用した結合であり、論理演算が差ではない場合、結果トライ内の各ノードの子ノードの集合は、入力トライ内の対応するノードの子ノードの集合の論理演算を使用した結合であり、異なるトライのノードに関連付けられたキーが同一である場合、異なるトライの2つ以上のノードは互いに対応する。
第121の実施形態によれば、実施形態93〜120の何れか1つにおいて、結果トライのノードの子ノードの集合は、論理演算を使用して、結果トライのノードに対応する入力トライのノードの子ノードの集合を結合することにより決定される。
結合ステップ
第122の実施形態によれば、実施形態93〜121の何れか1つにおいて、結果トライ又は結果トライの部分を評価するステップは、結果トライのルートノードに対して結合関数を実行することを含み、結果トライの入力ノードに対して結合関数を実行することは、論理演算を使用して、結果トライの入力ノードに対応する入力トライのノードの子ノードの集合を結合することにより結果トライの入力ノードの子ノードの集合を決定することと、結果トライの入力ノードに決定された子ノードのそれぞれに対して結合関数を実行することとを含む。
第123の実施形態によれば、実施形態93〜122の何れか1つにおいて、結果トライ又は結果トライの部分を評価するステップは、深さ優先探索、幅優先探索、又はそれらの組合せを使用して実行される。
第124の実施形態によれば、実施形態123において、深さ優先探索において結果トライ又は結果トライの部分を評価するステップを実行することは、入力ノードの子ノードの1つに対して結合関数を実行することと、結合関数がその子ノードの次の兄弟ノードに対して実行される前、その子ノードにより形成されたサブトライをトラバースすることとを含む。
第125の実施形態によれば、実施形態123又は124の何れか一方において、幅優先探索において結果トライ又は結果トライの部分を評価するステップを実行することは、結果トライの入力ノードに対して決定された子ノードのそれぞれに対して結合関数を実行することと、結果トライの入力ノードの孫ノードの何れかに対して結合関数を実行する前、結果トライの入力ノードに対して決定された子ノードのそれぞれの子ノードの集合を決定することとを含む。
ビットマップ
第126の実施形態によれば、実施形態93〜125の何れか1つにおいて、入力トライにおけるノード、好ましくは入力トライ内の少なくとも全ての親ノードはビットマップを含む。
第127の実施形態によれば、実施形態126において、トライ内の子ノードのキー部分の値は、ビットが子ノードに関連付けられた子ノードの親ノードに含まれるビットマップ内の(設定)ビットの値によって決まる。
第128の実施形態によれば、実施形態126又は127の何れか一方において、論理演算を使用して、結果トライのノードに対応する入力トライのノードの子ノードの集合を結合することは、好ましくは、論理演算を使用して、結果トライのノードに対応する入力トライのノードのそれぞれのビットマップをビット単位で結合し、それにより、結合ビットマップを取得することを含む。
第129の実施形態によれば、実施形態128において、結果トライのノードの子ノードは、結合ビットマップに基づいて、好ましくは結合ビットマップのみに基づいて決定及び/又は評価される。
第130の実施形態によれば、実施形態128又は129の何れか一方において、ビットマップを結合するステップは、結果トライのノードの子ノードが決定及び/又は評価される前、及び/又は結果トライの評価が結果トライのノードの子ノードにトラバースする前、実行される。
論理演算
第131の実施形態によれば、実施形態93〜130の何れか1つにおいて、論理演算は論理積、論理和、差分、又は排他的論理和である。
第132の実施形態によれば、実施形態131において、論理演算を使用することは、ANDブール演算、ORブール演算、AND NOTブール演算、又はXORブール演算を使用することを含む。
第133の実施形態によれば、実施形態93〜132の何れか1つにおいて、論理演算を使用することは、ビット単位ANDブール演算、ビット単位ORブール演算、ビット単位AND NOTブール演算、又はビット単位XORブール演算を使用してノードのビットマップを結合することを含む。
範囲クエリ
第134の実施形態は、電子データベース若しくは情報検索システムに記憶されたキーの集合又は電子データベース若しくは情報システムに記憶されたキーの1つ若しくは複数の集合から導出された結果キーの集合に対して範囲クエリを実行することにより、電子データベース又は情報検索システムからデータを検索する方法であって、1つ又は複数の範囲の定義を取得するステップと、
実施形態93〜133の何れか1つの電子データベース又は情報検索システムからデータを検索する方法を実行するステップと、
を含み、1つの入力トライは、1つ又は複数の範囲についてサーチされるキーの集合又は結果キーの集合を記憶する入力集合トライであり、別の入力トライは、定義が取得された1つ又は複数の範囲に含まれる全ての値を記憶する範囲トライであり、論理演算は論理積である、方法である。
第135の実施形態によれば、実施形態134において、範囲は、特定のデータ型の第1の値と第2の値との間の全ての値を含む順序付き離散値の集合である。
第136の実施形態によれば、実施形態135において、範囲は第1の値及び/又は第2の値を含む。
第137の実施形態によれば、実施形態134〜136の何れか1つにおいて、実施形態93〜133の何れか1つの方法を実行するステップにおいて、実施形態93〜111の何れか1つの方法が実行され、仮想トライである入力トライの少なくとも1つは範囲トライである。
1項目入力集合トライ
第138の実施形態によれば、実施形態137において、1つ又は複数の範囲の定義は、1データ項目の1つ又は複数の範囲の定義を含む。
多項目入力集合トライ
第139の実施形態によれば、実施形態134〜137の何れか1つにおいて、入力集合トライのリーフに関連付けられたキーは、特定のデータ型の2つ以上のデータ項目を符号化する。
第140の実施形態によれば、実施形態139において、1つ又は複数の範囲の定義は、データ項目の1つ又は複数の1つ又は複数の範囲の定義を含む。
1項目範囲トライからの多項目範囲トライの取得
第141の実施形態によれば、実施形態139又は140の何れか一方において、範囲トライは、入力集合トライのリーフに関連付けられたキーにより符号化されるデータ項目のそれぞれの1項目範囲トライを結合することによって得られる多項目範囲トライであり、データ項目の1項目範囲トライは、データ項目の1つ又は複数の範囲に含まれる全ての値を格納する。
第142の実施形態によれば、実施形態141において、1項目範囲トライの結合は、多項目範囲トライとの入力集合トライの結合を実施する関数内で実行される。
第143の実施形態によれば、実施形態141において、1項目範囲トライの結合は、多項目範囲トライとの入力集合トライの結合を実施する関数への入力として、多項目範囲トライを提供する関数によって実行される。
第144の実施形態によれば、実施形態141〜143の何れか1つにおいて、1項目範囲トライは、1項目範囲トライ、好ましくは、必要な変更を加えた実施形態105〜111の何れか1つにおいて定義される仮想トライを結合する演算中、少なくとも部分が評価される仮想トライである。
第145の実施形態によれば、実施形態141〜144の何れか1つにおいて、範囲の定義が取得されない各データ項目の1項目範囲トライは、データ項目の可能な値の全範囲を記憶する。
第146によれば。実施形態141〜144の何れか1つの方法、多項目範囲トライは、1項目範囲トライに記憶されたデータ項目の値の全ての組合せを記憶する。
範囲トライの構造
第147の実施形態によれば、実施形態141〜146の何れか1つにおいて、範囲トライは、入力集合トライと同じ構造又はフォーマットを有する。
第148の実施形態によれば、実施形態147において、範囲トライのリーフに関連付けられたキーは、入力集合トライのリーフに関連付けられたキーと同じデータ型のデータ項目を符号化する。
第149の実施形態によれば、実施形態147又は148の何れか一方において、範囲トライにおいて、特定のデータ型のデータ項目又はそのようなデータ項目の構成要素は、入力集合トライ内の対応するデータ項目又はデータ項目の構成要素と同じレベルのノードに符号化される。
範囲クエリの出力
第150の実施形態によれば、実施形態134〜149の何れか1つにおいて、方法は、入力集合トライのリーフに関連付けられたキーの集合を出力として提供する。
第151の実施形態によれば、実施形態139〜149の何れか1つにおいて、方法は、入力集合トライのリーフに関連付けられたキーによって符号化されたデータ項目のサブセットを符号化する縮小項目キーの集合を出力として提供する。
第152の実施形態によれば、実施形態151において、範囲トライとの入力集合トライの結合の結果として、縮小項目キーに符号化されないデータ項目に関連する入力集合トライの異なる分岐から得られる縮小項目キーの集合は、出力を提供する前、マージされる。
第153の実施形態によれば、実施形態151又は152の何れか一方において、範囲トライとの入力集合トライの結合の結果として得られる縮小項目キーの集合は、出力を提供する前、新たに作成されたトライに書き込まれ、それにより、出力を提供する前、複製キーをなくす。
ファジーサーチ
第154の実施形態は、文字列近似照合を実行することにより電子データベース又は情報検索システムからデータを検索する方法であって、文字のサーチ文字列を取得するステップと、サーチ文字列及び/又はサーチ文字列の変形を含む近似文字列の集合を記憶する一致トライを構築するステップと、結果トライの少なくとも部分を評価するステップであって、結果トライは論理積演算を使用した、電子データベース又は情報検索システムに記憶された文字列の集合を記憶したストレージトライと一致トライとの結合である、評価するステップと、出力として、結果トライのノードの結果集合に関連付けられた文字列及び/又は他のデータ項目を提供するステップであって、トライは1つ又は複数のノードを含み、各子ノードにはキー部分が関連付けられ、ルートノードからトライ内の別のノードへのパスは、ノードに関連付けられたキーを定義し、キーはパス上のノードに関連付けられたキー部分を連結したものである、提供するステップとを含む方法である。
第155の実施形態によれば、実施形態154において、一致トライに記憶された文字列の集合に含まれる文字列は、電子データベース又は情報検索システムに永続的に記憶される。
第156の実施形態によれば、実施形態154又は155の何れか一方において、一致トライに記憶された文字列の集合に含まれる文字列は、電子データベース又は情報検索システム内のエントリを表す。
第157の実施形態によれば、実施形態154〜156の何れか1つにおいて、一致トライ内の1つ又は複数の子ノードは、2つ以上の親ノードを有する。
第158の実施形態によれば、実施形態154〜157の何れか1つにおいて、ストレージトライ及び結果トライ内の各子ノードは、1つのみの親ノードを有する。
第159の実施形態によれば、実施形態154〜158の何れか1つにおいて、結果トライは、ストレージトライにより記憶されたキーの集合が一致トライにより記憶されたキーの集合と論理積演算された場合、取得されたキーの集合を記憶するトライである。
第160の実施形態によれば、実施形態154〜158の何れか1つにおいて、結果トライ内の各ノードの子ノードの集合は、一致トライ内の対応するノードの子ノードの集合とストレージトライ内の対応するノードの子ノードの集合との論理積であり、同じキーが異なるトライのノードに関連付けられている場合、異なるトライのノードは互いに対応する。
第160の実施形態によれば、実施形態154〜160の何れか1つにおいて、一致トライは、少なくとも部分が、結果トライの少なくとも部分を評価するステップ中に評価又は動的に生成される仮想トライである。
第161の実施形態によれば、実施形態160において、仮想トライ又は仮想トライの部分の物理的データ構造は全体として実現されない。
第162の実施形態によれば、実施形態160又は161の何れか一方において、少なくとも、結果トライの少なくとも部分の評価に必要な仮想トライの部分は評価される。
第163の実施形態によれば、実施形態160〜162の何れか1つにおいて、結果トライの少なくとも部分の評価に必要ない仮想トライの部分の少なくとも幾つかは評価されず、好ましくは、結果トライの少なくとも部分の評価に必要な仮想トライの部分のみが評価される。
第164の実施形態によれば、実施形態160〜163の何れか1つにおいて、仮想トライの少なくとも部分は、結果トライの少なくとも部分が評価された後、評価される。
第165の実施形態によれば、実施形態160〜164の何れか1つにおいて、結果トライの部分及び仮想トライの部分は、インタリーブ方式で評価される。
第166の実施形態によれば、実施形態154〜165の何れか1つにおいて、トライ又はトライの部分を評価することは、トライ又はトライの部分をトラバースすることを含む。
第167の実施形態によれば、実施形態154〜166の何れか1つにおいて、トライ又はトライの部分を評価することは、トラバースされたノードがトライに存在することの情報を提供することを含む。
第168の実施形態によれば、実施形態154〜167の何れか1つにおいて、トライ又はトライの部分の評価中、任意の所与の瞬間において、少なくとも、トライ又はトライの部分をトラバースするためにその瞬間に実現する必要があるトライ又はトライの部分の物理的データ構造の部分が実現される。
第169の実施形態によれば、実施形態154〜168の何れか1つにおいて、任意の所与の瞬間において、トライ又はトライの部分の物理的データ構造の全体未満が実現され、好ましくは、トライ又はトライの部分をトラバースするためにその瞬間において実現する必要があるトライ又はトライの部分の物理的データ構造の部分のみが実現される。
第170の実施形態によれば、実施形態154〜169の何れか1つにおいて、トライ又はトライの部分を評価することは、トライ又はトライの部分の物理的データ構造を全体として実現することを含む。
第171の実施形態によれば、実施形態154〜170の何れか1つにおいて、出力において提供されるデータ項目は、結果トライのノードの結果集合のノードに関連付けられた文字列、好ましくはドキュメント識別子を含むデータユニットを表す。
第172の実施形態によれば、実施形態154〜171の何れか1つにおいて、ストレージトライは、好ましくは、ドキュメントに含まれる文字列及びドキュメント識別子のそれぞれを2つのキー部、例えば(文字列、長)として格納するインデックストライ又は物理インデックストライである。
第173の実施形態によれば、実施形態154〜172の何れか1つにおいて、一致トライは一致ノードの集合を含み、各一致ノードには、近似文字列の集合からの文字列の1つに対応する1つ又は複数のキーが関連付けられ、ノードの結果集合は、一致トライ内の一致ノードの集合に対応する結果トライのノードの集合であり、結果トライのノードに関連付けられたキーが、一致トライのノードに関連付けられたキーと同一である場合、結果トライのノードは一致トライのノードに対応する。
第174の実施形態によれば、実施形態154〜173の何れか1つにおいて、方法は、数Nを取得するステップを更に含み、サーチ文字列の変形は、サーチ文字列での多くともN個の1文字挿入、削除、及び/又は置換によって取得することができる文字列の集合からなる。
第175の実施形態によれば、実施形態154〜174の何れか1つにおいて、一致トライを構築するステップは、近似文字列の集合を表す有限オートマトンを構築することと、有限オートマトンから一致トライを導出することとを含む。
第176の実施形態によれば、実施形態1〜175において、有限オートマトンの2つの状態間の遷移、好ましくはあらゆる遷移には、特定の文字、好ましくはサーチ文字列に含まれる文字、ワイルドカード文字、又は空文字列が関連付けられる。
第177の実施形態によれば、実施形態175又は176の何れか一方において、有限オートマトンを構築するステップは、近似文字列の集合を表す非決定性有限オートマトンを構築することと、非決定性有限オートマトンから決定性有限オートマトンを導出することとを含み、一致トライは決定性有限オートマトンから導出される。
第178の実施形態によれば、実施形態1〜177において、決定性有限オートマトンの2つの状態間の遷移、好ましくはあらゆる遷移には、特定の文字、好ましくはサーチ文字列に含まれる文字又はワイルドカード文字が関連付けられる。
第179の実施形態によれば、実施形態154〜178の何れか1つにおいて、一致トライ及びストレージトライ内のノード、好ましくは少なくとも全ての親ノードは、ビットマップを含み、トライ内の子ノードのキー部分の値は、ビットが子ノードに関連付けられた子ノードの親ノードに含まれるビットマップ内の(設定)ビットの値によって決まる。
第180の実施形態によれば、先の実施形態において、結果トライのノードの子ノードを決定することは、結果トライのノードに対応する一致トライのノード及びストレージトライのノードの子ノードの集合を論理積演算することを含む。
第181の実施形態によれば、先の実施形態において、一致トライのノード及びストレージトライのノードの子ノードの集合を論理積演算することは、ビット単位AND演算を使用して一致トライのノード及びストレージトライのノードのビットマップを結合し、それにより、結合されたビットマップを取得することを含む。
第182の実施形態によれば、先の実施形態において、結果トライのノードの子ノードは、結合ビットマップに基づいて、好ましくは結合ビットマップのみに基づいて決定及び/又は評価される。
第183の実施形態によれば、実施形態181又は182の何れか一方において、ビットマップを結合するステップは、結果トライのノードの子ノードが決定及び/又は評価される前、及び/又は結果トライの評価が結果トライのノードの子ノードにトラバースする前、実行される。
第184の実施形態によれば、実施形態171及び実施形態179〜183の何れか1つにおいて、有限オートマトンから一致トライを導出するステップは、遷移に関連付けられた特定の文字又はワイルドカード文字の符号化により有限オートマトンの2つの状態間の遷移、好ましくはあらゆる遷移を関連付けることにより、拡張有限オートマトンを取得することを含み、この符号化は、長さ及び/又はフォーマットが一致トライの親ノードに含まれるビットマップに等しい1つ若しくは複数のビットマップからなり、又は1つ若しくは複数のビットマップを表し、一致トライは拡張有限オートマトンから導出される。
第185の実施形態によれば、実施形態1〜184において、特定の文字の符号化の場合、厳密に1ビットが、符号化に含まれるか、又は表されるビットマップのそれぞれにおいて設定される。
第186の実施形態によれば、実施形態184又は185の何れか一方において、ワイルドカード文字の符号化の場合、全ての有効文字符号化のビットは、符号化に含まれ、又は符号化によって表されるビットマップにおいて設定され、遷移元の状態に関連付けられた特定の文字の符号化を除く全ての有効文字符号化のビットは、符号化に含まれ、又は符号化によって表されるビットマップにおいて設定される。
第187の実施形態によれば、実施形態179〜186の何れか1つにおいて、一致トライ、ストレージトライ、又は結果トライに格納された文字は、各トライのM>1個、好ましくは5>M個のキー部分によって符号化される。
第188の実施形態によれば、実施形態1〜187において、有限オートマトンから一致トライを導出するステップは、有限オートマトンの2つの状態間の遷移、好ましくはあらゆる遷移をM−1レベルの中間状態と、中間状態のM−1個を介して2つの状態をリンクするM個の遷移の1つ又は複数のシーケンスとで置換することにより、又は有限オートマトンの2つの状態間の遷移、好ましくはあらゆる遷移に、M−1レベルの中間状態と、中間状態のM−1個を介して2つの状態をリンクするM個の遷移の1つ又は複数のシーケンスを関連付けることにより、近似文字列の集合を表す完全有限オートマトンを取得することを含み、シーケンス内のM個の遷移のそれぞれには、長さ及び/又はフォーマットが一致トライの親ノードに含まれるビットマップに等しいビットマップからなり、又は表される中間符号化が関連付けられ、一致トライは完全有限オートマトンから導出される。
第189の実施形態によれば、実施形態188において、有限オートマトンの2つの状態間の遷移に、特定の文字が関連付けられる場合、シーケンスのM個の遷移が関連付けられた中間符号化に含まれ、又は表されるビットマップを連結したものは、特定の文字の符号化であり、ビットマップのそれぞれにおいて厳密に1ビットが設定される。
第190の実施形態によれば、実施形態188又は189の何れか一方において、有限オートマトンの2つの状態間の遷移にワイルドカードが関連付けられる場合、シーケンスのM個の遷移が関連付けられた中間符号化に含まれ、又は表されるビットマップを連結したものは、全ての有効文字符号化のビットが、符号化に含まれ、若しくは表されるビットマップにおいて設定され、又は遷移の発端である状態に関連付けられた特定の文字の符号化を除く全ての有効文字符号化のビットが、符号化に含まれ、若しくは表されるビットマップにおいて設定される符号化及び/又は特定の文字の符号化の1つ又は複数の部分又は全ての有効文字符号化のビットが符号化に含まれ、又は表されるビットマップにおいて設定され、若しくは遷移が発端とする状態に関連付けられた特定の文字の符号化を除く全ての有効文字符号化のビットが、符号化に含まれ、又は表されるビットマップにおいて設定される符号化の1つ又は複数の部分を含む1つ又は複数の符号化を含む。
第191の実施形態によれば、実施形態184〜186の何れか1つ、又は実施形態188〜190の何れか1つにおいて、拡張有限オートマトン又は完全有限オートマトンはそれぞれ、幾つかの行を含むデータ構造により表され、又は格納され、各行は、拡張有限オートマトン又は完全有限オートマトンの1つの状態を表し、状態を発端とする遷移のそれぞれにタプルを含み、各タプルは、遷移に関連付けられた符号化と、遷移が終わる状態への参照とを含む。
第192の実施形態によれば、実施形態1〜191において、データ構造は、遷移が終わる各状態について、好ましくは状態への各参照においてビットとして符号化される、この状態が一致状態であるか否かについての情報を含む。
第193の実施形態によれば、実施形態191又は192の何れか一方において、データ構造は、遷移元の拡張有限オートマトン又は完全有限オートマトンの状態のそれぞれの行を含む。
トライデータ構造
第194の実施形態によれば、実施形態93〜193の何れか1つにおいて、トライは実施形態1〜92の何れか1つに記載のトライである。
発明の異なるカテゴリ
第195の実施形態は、特に、キー若しくはキー及び値を格納し、クエリの結果キー若しくはキー及び値を格納し、又はクエリの入力キー若しくはキー及び値を格納する、電子データベースアプリケーション又は情報検索システムにおいて実施形態1〜92の何れか1つにおけるトライを使用するコンピュータ実施方法である。
第196の実施形態は、実施形態1〜92の何れか1つにおけるトライを生成するコンピュータ実施方法である。
第197の実施形態は、実施形態1〜92の何れか1つにおけるトライを格納した非一時的コンピュータ可読媒体である。
本発明の第198の実施形態は、実施形態1〜92の何れか1つにおけるトライを表す電子データのストリームである。
第199の実施形態は、実施形態1〜92の何れか1つにおけるトライにより、キー若しくはキー及び値、クエリの結果キー若しくはキー及び値、又はクエリの入力キー若しくはキー及び値を格納する電子データベース又は情報検索システムである。
第200の実施形態は、実施形態93〜196の何れか1つにおける方法を実行する命令を含む、コンピュータプログラム、特にデータベースアプリケーション情報検索システムプログラムである。
第201の実施形態は、実施形態93〜196の何れか1つにおける方法を実行するように構成された、1つ又は複数のプロセッサ及びメモリを含むデータ処理デバイス又はシステムである。
第202の実施形態は、実施形態201におけるコンピュータプログラムを記憶した好ましくは非一時的コンピュータ可読媒体である。
図面の簡単な説明
以下、本発明について、好ましい実施形態に関連して図面を参照して更に詳細に説明する。
発明の好ましい実施形態の詳細な説明
図1は、従来技術によるデータベースで使用されるトライデータ構造の一例を示す。図1は、各子ノード(すなわち、ルートノードを除く全てのノード)にはキー部分が関連付けられ、キー部分の値は、親ノードからのポインタによって示され、英数字{0,…,9}から選択され、すなわち、ルートノードを除く各レベルのノードには1桁の数字が関連付けられるトライデータ構造101を示す。ルートノードからトライ内の別のノードへのパスは、ノードが関連付けられたキーを定義し、キーは、パス上のノードに関連付けられたキー部分を連結したものである。トライ101には値「007」を有するキーが関連付けられ、トライ101のリーフノード108には値「042」を有するキーが関連付けられているため、トライ101は、値「007」及び「042」を有するキーを「格納」する。
第1レベル110に配置されたルートノード102は、値「0」のキー部分が関連付けられた1つの子ノード104を有する。したがって、ルートノード102から、トライ101の第2レベル111に配置された子ノード104へのポインタ103があり、子ノード104は値「0」を示す。第2レベルの子ノード104から、2つの異なるポインタが、第3レベル112に配置されたノード105、106を指し、これらのノード105、106のそれぞれから、1つの更なるポインタがリーフノード107、108をそれぞれ指す。したがって、ルートからリーフノードへのパス上のノードのキー部分を連結したものが、値「007」及び「042」を有するキーになる。
図2は、従来技術で使用されるトライデータ構造の更なる例を示す。この例のトライデータ構造は図1のものと同様であるが、より大きな英字の、ノードに関連付けられたキー部分の可能な値を有する。特に、図2は256変数トライデータ構造を示し、キー部分値の表現は8ビット(すなわち、1バイト)のサイズを有する。
図2のトライデータ構造は、2つの異なるキー「0000FD」及び「002A02」を格納し(リーフノードに関連付けられた2つの異なるキーを有し)、4つのレベル210〜214を有する。第1レベル210に配置されたルートノード202は、キー部分値「00」が関連付けられた子ノード204へのポインタを有する。子ノード204は、キー部分値「00」及び「2A」がそれぞれ関連付けられた子ノード205、206への2つのポインタを含む。第3レベル212に配置された各子ノード205、206は、リーフノード207、208への1つのポインタをそれぞれ含む。リーフノード207、208は第4レベル213に配置される。リーフノード207にはキー部分値「FD」が関連付けられ、リーフノード208にはキー部分値「02」が関連付けられている。
図3は、図2のトライデータ構造の従来技術による実施を示す。ポインタが関連付けられたノードは全体的に、メモリにおいて割り振られる。したがって、この状況では、空(無)ポインタであってもメモリ空間を占有する。例えば、ルートノード302は、配列306に割り振られた256個のポインタを有し、キー部分値「00」が関連付けられ、子ノード304を指す1つのポインタ303のみが空ではない。子ノードは同じように実施される。
図4は、メモリ空間をより効率的に使用する既知の解決策を提供する、図2のトライデータ構造の例示的な実施を示し、空(ヌル)ポインタの格納を回避する。解決策の本質は、可能な全てのポインタを含む配列の代わりに、各キー部分値と共に非空ポインタのみのリストを格納することにある。例えば、キー部分値「00」が関連付けられた1つの子ノードを有するルートノード402は、1つのエントリを有するリストを含む。リストのエントリは、キー部分値403と、子ノード405を指す、関連付けられたポインタ404とを含む。他の子ノードもそれに従って実施される。
図5は、親ノードの全ての非空ポインタを記すのに使用されるビットマップに基づいて割り振り問題への既知の解決策を提供する、図2のトライデータ構造の別の例示的な実施を示す。換言すれば、ビットマップ内の設定ビットは有効(非空)分岐を記す。各親ノードは1つ又は複数のポインタも含み、各ポインタにはビットマップ内の設定ビットが関連付けられ、各ポインタは親ノードの子ノードを指す。
子ノードのポインタを決定するためには、先行する子ポインタの量を計算する必要がある。ポインタを見つけるためのオフセットは、図6に示されるように、標的位置前にビットマップ内で設定された最下位ビットの量である。このコンパクトなトライノード構造は、無ポインタを格納する必要性をなくし、それと同時に、非常に高速なアクセスを可能にする。
図5の例のトライデータ構造は英字基数256を有し、その結果、ビットマップサイズは256ビットになる。換言すれば、各ビットマップは、256個の異なるキー部分値(又は子ノード)の256個のポインタを識別することができる。256個の異なる値を用いて、8ビット(28)すなわち1バイトを符号化することができる。
ルートノード502は、ビットマップに設定された、キー部分値「00」を表す1ビットを有する。したがって、ルートノード502は、子ノード504への1つのみのポインタ503を含み、子ノードには値「00」を有するキー部分が関連付けられる。子ノード504は、ビットマップにおいて設定された2つのビット505、507、すなわち、キー部分値「2A」及び「00」を表すビットを有する。したがって、子ノード504は、各子ノード509、510をそれぞれ指す2つのポインタ507及び508を含む。
値「2A」を有するビットマップ内のビットに関連付けられたポインタ506は、キー部分値「2A」を表すビット505から開始して、幾つの最下位ビットが設定されているかを計算することによりアドレス指定される。この場合、1つの最下位ビット、すなわち、ビット506しか設定されておらず、したがって、1ポインタのオフセットがあり、探しているポインタが、子ノード504に含まれる2番目のポインタであると判断することができる。
本発明によるトライの好ましい実施形態の一般特徴
全てのトライのように、本発明によるトライ又はトライデータ構造は、1つ又は複数のノードを含む。図1〜図6を参照して上述した従来技術によるトライと同様に、好ましい実施形態のトライのノード、好ましくは各子ノードにはキー部分が関連付けられ、ルートノードからトライ内の別のノード、特にリーフノードへのパスは、キーを定義し、キーは、パス内のノードに関連付けられたキー部分を連結したものである。ルートノードにはキー部分が関連付けられず、トライが、他の目的を果たすため、キー部分が関連付けられない更なるノードを含み得ることが理解されよう。例えば、サブツリー内のエントリの数は、通常は全ツリーをトラバースする必要があるカウント動作を回避又は加速させるために、そのようなノードに格納することができる。
本発明によるトライの好ましい実施形態では、2つ以上の子ノードを有するノード、好ましくは少なくとも各親ノードは、ビットマップ及び幾つかのポインタを含む。各ポインタには、ビットマップにおいて設定されたビットが関連付けられ、各ポインタはノードの子ノードを指す。通常、ビットは、値が「1」である場合、ビットマップにおいて「設定」されている。しかしながら、特定の実施形態では、ビットは、値が「0」である場合、「設定」されているものとしてカウントし得る。本明細書では、ビットマップ内のビットは、その値が、図5に示される従来技術によるトライを参照して先に説明したように、ビットマップ内のビットが有効分岐を記すという考えが関連付けられた値に対応する場合、「設定」されているものとしてカウントされる。
好ましくは、ビットマップは、予め定義されたサイズの整数としてメモリに格納される。更に、ビットマップのサイズは、好ましくは、32ビット、64ビット、128ビット、又は256ビットである。トライを格納し処理する標的コンピュータシステムの動作性能は、標的コンピュータシステムのCPUのレジスタ、システムバス、データバス、及び/又はアドレスバスのビット幅に等しいようにビットマップのサイズを選ぶことにより上げることができる。
例えば、上述したように、ビットマップにおいて設定されたビットに関連付けられたポインタのメモリアドレスは、ビットマップにおいて設定された最下位ビットの数に基づいて計算することができる。この特定は、単純なビット演算と、設定ビットの数を特定するCTPOP(ポピュレーションカウント)演算とを使用して非常に効率的に行うことができる。多くの近代のCPUは実に、固有命令としてCTPOPを提供している。しかしながら、近代のCPUでは長整数は64ビット幅であるため、CTPOPは64ビットでしか機能しない。これは、256ビットのビットマップを使用する従来技術によるトライにとっては、演算が最高で4回(4×64=256)実行されることを意味する。代替的には、従来技術によるトライは、最初の3つのビットマップを有する先行ビットマップの合計ビットカウントを格納する。次に、最下位ビットの数は、ビットの最後の群のCTPOP+ビットの先行群のビットカウントとして計算することができる。
現在、大半のコンピュータシステムでは、システムビット幅は64ビットであり、64ビットというビットマップサイズは現在、最も好ましいサイズであり、本発明の実施例で本発明者により使用された。この結果、64変数トライが生成され、これは、あらゆるノードが64シンボルの英字シンボルを格納することができ、すなわち、6ビット(26=64)を符号化することができることを意味する。以下に説明するように、本発明の実施形態によるトライは、幾つかのノード及びそれに関連付けられたキー部分を使用して、プリミティブデータ型に含まれる情報を格納し得る。例えば、64ビット長整数によって表されるキーを格納するには、11レベルを有する64変数トライが必要である(11*6ビット>=64)。
ビットマップ及び/又はポインタは、例えば、配列、リスト、又は連続した物理若しくは仮想メモリロケーションに格納し得る。なお、「メモリ」という用語が本明細書で使用される場合は常に、物理的又は仮想的なメモリを指し得、好ましくは連続メモリを指し得る。好ましい実施形態では、長整数(64ビット)は、ビットマップを表すために使用されるとともに、子ポインタのそれぞれを表すのにも使用される。メモリにおいてノードを別個に割り振る代わりに、ノードは長整数の配列に格納され、ノードのメモリポインタを有する代わりに、現在のノードはこの配列へのインデックスにより指定される。子ポインタは、配列内のノード位置のインデックスであり得る。その場合、トライをトラバースするとき、現在のノードインデックスに基づいて子ノードのインデックスを見つけるためのオフセットは、ビットマップの標的位置前にビットマップにおいて設定された最下位ビットの量に1を加算したものである。
好ましい実施形態は幾つかのそのような配列を用いて機能する。ポインタの一部分、例えば下部は、配列内のインデックスであり、ポインタの別の部分、例えば上部は配列への参照である。任意の大きなサイズの配列を割り振ることは常に可能であるわけではないため、これはメモリ管理目的で行われる。例えば、Javaでは、配列のサイズは32ビット整数に制限され、これにより、231(正の値のみ)=2,147,483,648の配列サイズになる。しかしながら、多くの現実世界用途では、16MB以上を含む配列が必要とされ、これは64ビット長整数配列では200万個のエントリに対応する。
図5及び図6の従来技術によるトライのように、2つ以上の子ノードを有する親ノード、好ましくは少なくとも各親ノードは通常、前記親ノードに含まれるビットマップにおいて設定されたビット量に等しいポインタ量を含む。例えば、図5のノード504は、設定された2ビット505、506を有するビットマップを有し、2つのポインタ507、508を含む。親ノードの全ポインタ内でのポインタのランクは、好ましくは、親ノードのビットマップ内の全ての設定ビット内の、ポインタに関連付けられた設定ビットのランクに対応する。例えば、図5の親ノード504では、第1のポインタ507はビットマップの第1の設定ビット505に対応し、第2のポインタ508は第2の設定ビット506に対応する。ポインタは通常、ビットがビットマップにおいて設定された順と同順又は逆順に格納される。各ポインタは、好ましくは、例えば図9及び図12において以下に示されるように、子ノードに含まれるビットマップ(のアドレス)、例えば、このビットマップの開始アドレスを指す。
図5及び図6の従来技術によるトライでのように、親が2つ以上の子ノードを有する好ましい実施形態のトライの子ノード、好ましくは少なくとも各子ノードのキー部分の値は、ビットが子ノードに関連付けられた親ノードに含まれるビットマップにおける(設定)ビットの値によって決まる。したがって、キー部分に利用可能な異なる値の最大量は通常、ビットマップのサイズによって定義され、及び/又はビットマップのサイズは、キー部分に可能な英字を定義する。
本発明の好ましい実施形態では、トライ内の各キー部分は、同じ予め定義されるサイズの値、例えば5ビット値(ビットマップのサイズが32ビットである場合)、6ビット値(ビットマップのサイズが64ビットである場合)、7ビット値(ビットマップのサイズが128ビットである場合)、又は8ビット値(ビットマップのサイズが256ビットである場合)を格納することが可能である。ノード又はキー部分によって表される文字の英字は、そのサイズを有する可能な全てのビット群の集合である。例えば、キー部分が6ビット値を格納可能な場合、英字は、6ビットを含む全てのビット群の集合である。
本発明によるトライデータ構造は、キー値マップ(「連想配列」とも呼ばれる)の実施に使用することができ、値はリーフノード及びキー集合(「動的集合」とも呼ばれる)に格納され、データはリーフノードに格納されない。所与のキーの値を調べるために、あらゆるキーが1つのみの値を有する場合、マップが使用され、一方、所与の集合が所与のキーを含むか否かを判断するためには、集合が使用される。両方の場合で同様に、キーへの集合演算(論理和、論理積、又は差分等)は頻繁に必要とされる演算である。
図7A〜図7Cは、コンパクトに、全ての値に一定時間内でアクセスすることができるように、リーフノードがマップにいかに格納されるか及び「最後」のビットマップがいかに集合に格納されるかを示す。図7Aは、より長い文字列又はテキスト等のより大きな及び/又は可変サイズ値のデータ型を有するキー値マップの場合、リーフノードがいかに格納されるかを示す。図7Aに示されるように、値は別個に格納される。値への追加のポインタidxに必要な空間は、ポインタのサイズと比較して値のサイズが大きい場合、ごくわずかである。
値データ型が、日付け又は整数等の固定サイズである場合、値を「直列」に格納する、例えば、図7Bに示されるように、親ノードのビットマップの直後に格納することがより効率的である。例えば、長−長マップ、すなわち、キーが長整数型であり、値も長整数型であるマップは、直列化を用いる本発明の好ましい実施形態によりトライデータ構造により効率的に実施することができる。直列化は、固定サイズ値データ型である場合、位置は、例えば、CTPOP(ビットマップ+(ビット位置−1))*サイズとして計算することができるため、固定サイズ値データ型でのみ機能する。逆に、可変サイズ値データ型の場合、位置を特定するために、全ての値のエントリを経る必要がある。
図7Cは、「最後」のビットマップを記憶する直列を集合にいかに使用することができるかを示す。値がないため、最後のビットマップはそれ自体、ポインタの必要なく直列化される。なお、本明細書で使用される用語では、物理レベルでのこれらの「最後」のビットマップは、リーフノードの親ノードの部分であるが、これらのビットマップにおいて設定されたビットは、論理レベルでのリーフノードのキー部分の値を示す。
トライデータ構造は、キーを順序付きで格納し、したがって、キーを順にトラバースすることができる。例えば、64ビット長整数キーは、最上位6ビット(又は64=4+10*6であるため、4ビット)から始まって最下位6ビットまで格納し得る。この方法では、整数は符号なし長整数として扱われる。通常、2の補数を使用して符号化される符号付き整数の場合、正確な順序を有するために、例えば、64ビット長整数の場合264−1を追加することによりオフセット二進表現に変換しなければならない。浮動小数点数も同様に扱われる。したがって、浮動小数点数又は2の補数の符号付き整数等のキーのデータ項目の値の符号化は、データ項目のデータ型を、符号なし整数、例えば、符号なし長整数で構成されるオフセット二進表現に変換することを含み得る。
空間効率的トライデータ構造
多くの用途状況では、メモリ空間の使用は非効率的である。これは、トライが疎に存在し、及び/又は各ノードが1つのみの子ポインタを有するノード連鎖に劣化する場合、特に当てはまる。
連鎖ノード最適化
本発明者は、経験的研究において、任意のキーについて、典型的な用途状況でのトライが、1つのみの子を有する多くのノードを有することを発見した。これは、多くのキーが共通のプレフィックス、インフィックス、又はポストフィックスを共有するためである。そのような状況では、従来技術によるトライは、1つの子ポインタを有するノードの連鎖に劣化し、従来技術によるトライデータ構造の空間効率は低い。
本発明の第1の空間最適化は、ノードが1つのみの子を有する場合、すなわち、親ノードに含まれるビットマップにおいて、1つのみのビットが設定される場合、子ポインタをなくす。本明細書ではこの手法を「連鎖ノード最適化(chained node optimization)」と呼ぶ。連鎖ノード最適化が効率的なトライの一例を図8に示す。トライのレベル4にあるリーフノード841、842、843は、レベル0におけるルートノード800、ルートノード800の唯一の子ノードであるレベル1におけるノード810、ノード810の唯一の子ノードであるレベル2におけるノード820、及びノード820の唯一の子ノードであるレベル3におけるノード830を含む共通のプレフィックスを共有する。
本発明の第1の空間最適化は、1つ又は複数のノードを含むトライであって、2つ以上の子ノードを有する、トライに含まれる親ノード、好ましくは各親ノードは、ビットマップ及び1つ又は複数のポインタを含み、各ポインタにビットマップにおいて設定されたビットが関連付けられ、各ポインタは親ノードの子ノードを指す、トライに適用される。最適化は、1つのみの子ノードを有する、トライに含まれる親ノード、好ましくは各親ノードが、子ノードへのポインタを含まず、及び/又は子ノードがメモリにおいて、親ノードに相対して予め定義された位置に格納されることによって達成される。好ましくは、1つのみの子ノードを有する親ノードの子ノードは、メモリにおいて親ノードの直後に格納される。
本発明による第1の空間最適化を図9に示し、図9は、連鎖ノード最適化前のトライ910の部分と、連鎖ノード最適化が適用された後のトライ910に対応するトライ920の部分とを示す。上述した好ましい実施形態と同様に、トライ910、920におけるノードは、長整数の配列内に格納され、これは、トライ910、920の部分の図の左側にある表現「long[]」によって示される。
トライ910は、1ビットのみが設定され(1)、他の全てのビットは設定されない(0)ノード911の(64ビット幅)ビットマップにより示されるように、1つのみの子を有する第1のノード911を含む。従来技術によるトライのように、ノード911は結果として、ノード911の子ノードであるノード912を指す長整数である1つのポインタ914を含む。ノード912は、ノード912の(64ビット幅)ビットマップにおいて設定された2ビット及びノード912に含まれる2つのポインタ915、916によって示されるように、図9に示されていない2つの子ノードを有する。ノード911とノード912との間の3つのドット(「...」)によって示されるように、ノード912は通常、ノード911の直後のメモリロケーションに格納されず、長整数の配列内の任意の場所に格納することができる。
トライ920もまた、1ビットのみが設定され(1)、他の全てのビットは設定されない(0)ノード921の(64ビット幅)ビットマップにより示されるように、1つのみの子を有する第1のノード921を含む。しかしながら、トライ910におけるノード911とは対照的に、トライ920におけるノード921は、ノード921の子ノードであるノード922を指すポインタを含まない。その代わり、ノード922は、好ましい場合、ノード921の直後のメモリロケーションに格納されるが、代替的には、親ノード921に相対するメモリ内の位置が予め定義される限り、長整数の配列内の任意の場所に格納することができる。例えば、子ノード922は、親ノード921の直前に格納することができ、又は親ノード921と子ノード922との間に固定長の別のデータオブジェクトが存在することができる。トライ910のノード912のように、トライ920のノード912は、メモリ(長整数の配列)内のロケーションがノード922に含まれる2つのポインタ925及び926によって示される、図9に示されていない2つの子ノードを有する。
ノードに含まれるビットマップ及び各ポインタの両方が長整数により、すなわち、同じデータ型又は同じ長さのデータ型により表される図9の実施形態例では、本発明による連鎖ノード最適化は、1つのみの子ノードを有するノードの格納に必要なメモリ空間を50%低減する。
末端最適化
本発明の第2の空間最適化は、トライの「端部」が1ノードの連鎖又は列、すなわち、共通のポストフィックスを有さない多くのキーを含むトライのメモリでのよりコンパクトな表現を提供する。第2の空間最適化が効率的なトライの一例を図10に示す。図10におけるトライのリーフノード1041、1042、1043、1044、1045はそれぞれ、独立した(非共通)ポストフィックスの部分である。各ポストフィックスは、トライのレベル3において1つのノード1021、1022、1023、1024、1025、トライのレベル4において1つのノード1031、1032、1033、1034、1035、及びレベル5において1つのリーフノードを含む。レベル3におけるノード1021、1022、1023、1024、1025及びレベル4におけるノード1031、1032、1033、1034、1035はそれぞれ、1つのみの子を有する。
第2の空間最適化によれば、1ノードの列の開始におけるノードは、「末端分岐ノード」と記される。図10では、末端分岐ノードは、トライのレベル3におけるノード1021、1022、1023、1024、1025である。列内の残りのノードのキー部分の値は単に、それらの親ノードに含まれるビットマップ内の(設定)ビットの値によって決まるのではなく、「ネイティブ」又は文字通りの符号化で連続して格納される。本明細書では、この手法を「末端最適化」と呼ぶ。
したがって、本発明の第2の空間最適化は、1つ又は複数のノードを含むトライであって、2つ以上の子ノードを有する、トライに含まれる親ノード、好ましくは少なくとも各親ノードは、ビットマップを含み、ノード、好ましくは各子ノードにはキー部分が関連付けられ、親が2つ以上の子ノードを有する子ノード、好ましくは少なくとも各子ノードのキー部分の値は、ビットが子ノードに関連付けられた親ノードに含まれるビットマップ内の(設定)ビットの値によって決まる、トライに適用される。
ノードがメモリにおいて独立して割り振られるPh. Bagwell,“Fast And Space Efficient Trie Searches”, Technical Report, EPFL, Switzerland (2000)では、「ツリーテール圧縮」と呼ばれる手法が、文字列ノードへのポインタを参照し、又は末端分岐ノードに直接、末端列の数値を格納する。しかしながら、この手法は空間効率的ではなく、その理由は、オフセット及びノードタイプ(ビットマップを有するノード又は文字/ポインタリストを有するノード)をノードに格納する必要があるためである。
本発明による末端最適化は、ビットが設定されていないビットマップにより、トライ内の1つのみの子ノードを有し、全ての子孫ノードが多くとも1つの子ノードを有するノード、好ましくは各ノードを末端分岐ノードと記すことにより、この問題を解決する。本発明は、常に少なくとも1ビットが設定された好ましい実施形態の標準ノードに含まれるビットマップの特別な品質を使用する。これは、全てゼロのビットマップを有するノードが、子ノードを有さないノードであるが、子ノードを有さないノードは、メモリにおいて表す必要がないためである。したがって、特別な意味は、ビットが設定されていないビットマップに起因することができ、末端分岐ノードのビットマップは、2つ以上の子ノードを有する親ノードに含まれるビットマップと同じ長さ又はフォーマットを有することができる。
末端分岐ノード、好ましくは各末端分岐ノードの子孫ノード、好ましくは各子孫ノードに関連付けられたキー部分の値は、子孫ノードの親ノードに含まれるビットマップにおける(設定)ビットの値によって決まらない。むしろ、キー部分の値は、表現に必要なメモリ空間が、2つ以上の子ノードを有する親ノードに含まれるビットマップよりも少ないように符号化される。通常、キー部分の値は、整数値等の二進数(数)として符号化される。例えば、標準ノードに含まれるビットマップが32ビット、64ビット、128ビット、又は256ビットをそれぞれ有する場合、末端分岐ノードの子孫ノードに関連付けられたキー部分は5ビット、6ビット、7ビット、又は8ビットによりそれぞれ符号化される。
本発明の好ましい実施形態による末端最適化の一般格納構成を図11に示す。ビットが設定されていない64ビット幅ビットマップの後、二進数として符号化される幾つかの(通常、少なくとも2つの)6ビットキー部分が続く。しかしながら、好ましい実施形態では、各6ビットキー部分は8ビットブロック(1バイト)に格納される。利用可能な8ビットのうち6ビットしか使用しないため、これはいくらかの空間を無駄にするが、8ビット内の6から8ビットのうちの8への変換及びこの逆の変換は、実施の複雑性を上げ、性能を低下させる。本発明者によって行われた測定では、空間の無駄が許容できるものであり、8ビットのうちの8を格納することによる空間改善はごくわずかであることが示された。
末端分岐ノード及び/又はその子孫ノードは、それらの1つの子ノード(もしあれば)へのポインタを含む必要がなく、その理由は、図12に示されるように、子ノードがメモリにおいて親ノードに相対して予め定義された位置に、好ましくは親ノードの直後に格納することができるためである。更に、末端分岐ノード、好ましくは各末端分岐ノードの子孫ノード、好ましくは全ての子孫ノードに関連付けられたキー部分の値は、末端分岐ノード後、連続して格納される。最後に、図12において観察することができるように、1ノード列では、末端分岐ノードの場合のみ、ノードを末端分岐ノードと記すためにビットマップを有する必要があり、一方、末端分岐ノードの子孫ノードはいずれも、ビットマップ、特に設定ビットが子ノードに関連付けられたキー部分の値を決めるビットマップを含む必要がない。
図14Cに示され、後述される例から明らかになるように、最も好ましい実施形態による末端最適化は、末端分岐ノードが2つ以上の子孫ノードを有する場合のみ、連鎖ノード最適化よりも空間効率的である。更に、1ノード列内の最初のノードが既に末端分岐ノードと記されており、したがって、末端分岐ノードの親が2つ以上の子ノードを有する場合、最大の空間節約を達成することができる。
本発明による第2の空間最適化を図12に示し、図12は、末端最適化前のトライ1210の部分と、末端最適化が適用された後のトライ1210に対応するトライ1220の部分とを示す。トライ1210、1220のノードはここでも、長整数の配列に格納される。
トライ1210は、1ビットのみが設定され(1)、他の全てのビットは設定されない(0)ノード1111のビットマップにより示されるように、1つのみの子を有する第1のノード1211を含む。一番右側のビットが値「0」を有し、一番左側のビットが値「63」を有する64ビット幅ビットマップ内の左から4番目のビットであることから分かるように、設定されている1ビットは値「60」を有する。ノード1211は、ノード1211の子ノードであるノード1212を指す長整数である1つのポインタ1213を含む。ノード1211とノード1212との間の3つのドット(「...」)によって示されるように、ノード1112は通常、ノード1111の直後のメモリロケーションに格納されず、長整数の配列内の任意の場所に格納することができる。値「01」を有するビットである、ノード1212の64ビット幅ビットマップにおいて設定された右から2番目のビットによって示されるように、ノード1212も1つの子ノードを有する。しかしながら、ノード1212の子ノードはリーフノードであるため、ノード1212は子ノードへのポインタを含まず、リーフ部1214を含み、リーフ部1214は、ポインタ、マップの値(図7A及び図7B参照)、又は集合の場合、空(図7C参照)であり得る。リーフノードはメモリにおいて表現されない。なお、好ましい実施形態では、トライの深さ又はトライに格納されるキーの長さは既知であるため、特定の「リーフインジケータ」は必要ない。
観察することができるように、ノード1211は末端分岐ノードであり、その理由は、1つのみの子ノード1212を有し、全ての子孫ノード(1212及び1212の子ノード)が多くとも1つの子ノードを有する(ノード1212は1つの子ノードを有し、ノード1212の子ノードは子ノードを有さない)ためである。トライ1220は、末端最適化を適用した結果として、トライ1210から得られる。トライ1210のノード1211に対応するトライ1220のノード1221は、ビットが設定されていない64ビット幅ビットマップを提供することにより末端分岐ノードとして記されている。トライ1211の子ノード1212に対応する子ノード1222に関連付けられたキー部分の値は、ノード1221のビットマップにおける(設定)ビットの値によって決まらない。むしろ、キー部分の値は、図12において数字「60」によって示されるように、ノード1221に含まれる、整数等の二進数として符号化される。キー部分の値のそのような表現は、たった6ビット(64=26)しか必要とせず、したがって、必要とするメモリ空間は、2つ以上の子ノードを有する親ノードに含まれる64ビット幅ビットマップよりもはるかに少ない。例えば、値60は二進数「111100」として符号化し得る。
末端分岐ノード1221は、子ノード1222へのポインタを含まない。むしろ、子ノード1222は、親ノード1221に相対したメモリ内の予め定義された位置、すなわち、親ノードの直後に格納される。ノード1222は、末端分岐ノード1221の子孫ノードであり、ビットマップを含まず、子ノードへのポインタを含まず、図12において数字「01」によって示されるように、ノード1222の子ノードに関連付けられたキー部分の値を符号化する二進数のみを含む。例えば、値01は二進数「000001」として符号化し得る。ノード1222の表現の後、メモリではリーフ部1224が続く。ここでも、リーフ部1224は、ポインタ、マップの値(図7A及び図7B参照)、又は集合の場合、空(図7C参照)であり得る。
ビットマップ及びノードに含まれる各ポインタの両方が長整数によって表される図12の実施形態例では、末端最適化されたトライ1220は、ノード1221及び1222の格納に64+6+6=76ビットを必要とする。これと比較して、最適化されていないトライ1210は、同じ情報(ノード1211及び1212、トライ1210及び1220の両方に存在するリーフ部1214はカウントに含めない)の格納に64+64+64=192ビットを必要とする。
好ましい実施形態でのように、長整数の配列がトライの格納に使用される場合、本発明による末端最適化は、位置合わせ損失を被る。最悪の場合、1つの6ビットキー部分が64ビット長整数に格納される。しかしながら、実験では、平均で、末端分岐ノードの子孫ノードの格納に使用される空間の50%が占有されることが示された。更に、末端最適化はそれでもなお、必要とする空間は、ポインタ又は連鎖ノード最適化を用いて幾つかのシングル子ノードを格納するよりもはるかに少ない。
標準ノード、連鎖ノード最適化によって最適化されたノード、及び末端最適化によって最適化されたデータに均一にアクセスする方法について、図13を参照してこれより概説する。実施例においてクエリ実行モデルで使用されるノードアクセスの主な方法は、トライノードの全ての非空子ポインタでビットが設定されたビットマップを返すgetBitSet()及びビット数によって指定される所与のノード分岐の子ノードを返すgetChildNode(bitNum)である。これらの方法は両方とも、インターフェースCDBINodeによって提供され、ここで、CDBIは「コンフルエンスデータベースインデックス」を表す。別のインターフェースCDBINodeMemは、CDBINodeインターフェースを通してのオブジェクト指向アクセスをデータモデルに提供する。
解決する必要がある問題は、統一された中央場所で、コードの多くの場所で別個に対処する必要なく3つの事例をいかに扱うかであった。本発明者によって発見された解決策によれば、図13に示すように、ノードは、ノードポインタ(インデックス)を介するのみならず、ベースノードインデックス(「nodeRef」)及びノード内のインデックス(「idxInNode」)も介して参照され、ポインタのない連鎖及び末端を、末端ノードの連鎖の冒頭を指すベースノードインデックスを有する1つのノードとして扱う。このようにして、メモリ空間最適化は、「get」演算に大きな複雑性を追加せず、したがって、性能は低下しない。
nodeRefは常に最初のビットマップを指すため、getBitSet()及びgetChildNode(bitNum)の実装において3つの事例を検出するのに使用される:
−ビットマップは、2つ以上の設定ビットを有する場合、通常ノードに属する。getBitSet()はそのビットマップを返し、getChildNode(bitNum)は、idx(子ノードへのポインタ)を決定し、nodeRefがそれに設定された(且つidxInNodeが0に設定された)新しいCDBINodeMemを返す。
−ビットマップは、0である(ビットが設定されていない)場合、末端分岐ノードに属する。getBitSet()は、idxInNode位置に文字通り格納された6ビット値をビットマップに変換して返し、getChildNode(bitNum)は、同じnodeRef及びidxInNode+1を有する新しいCDBINodeMemを返す。
−ビットマップは、1ビットが設定されている場合、連鎖ノードに属する。getBitSet()はidxInNode位置におけるビットマップを返し、getChildNode(bitNum)はここでも、同じnodeRef及びidxInNode+1を有する新しいCDBINodeMemを返す。CDBINodeMemは、時間がかかる新しい子ノードを作成せず、ただnodeRef及びidxInNode(gotoChildNodeメソッド)を更新するだけで、すなわち、プロキシとして機能する既存のオブジェクトを変更することにより、フライウェイトパターンとして使用することもできる。
図14A〜図14Cは、第1のキーはキー部分値[00,02,02]を有し、第2のキーはキー部分値[00,03,00,01]を有する2つのキーを空のトライに挿入する場合のトライの成長を示す。図14Aは、値0を有するルートインデックスポインタによって示される空トライを示す。図14Bは、キー部分値[00,02,02]を有する第1のキーを追加した後のトライを示す。前のエントリがないため、第1のキーは末端最適化を使用して格納される。図14Cは、キー部分値[00,03,00,01]を有する第2のキーを追加した後のトライを示す。既存の末端ノードは分割される。1つのみの子を有するため、一致するプレフィックス(「00」)は連鎖ノードとして格納され、その後、2つの子ノード(「02」及び「03」)を有する通常ノードが続く。第1のキーの残り(「02」)は、リーフ部を有するノードとして格納される(末端最適化を用いての格納はより多くの空間を必要とする)。第2のキーの残り(「00」及び「01」)はここでも、末端最適化を使用して格納される。
本発明の様々な実施形態によるデータ構造の空間要件を測定するために、完全長整数値範囲を有する長整数の無作為集合が格納される実験を行った。図15は測定結果を示し、x軸は、トライインデックスにロードされたエントリ数を対数尺度で示し、y軸は、1エントリの格納に必要とされた平均バイト数を示す。
連鎖ノード最適化単独で、空間要件は約40%低下し、末端最適化単独で約60%〜約70%低下したことを観察することができる。連鎖ノード最適化と末端最適化との組合せは、末端最適化単独と比較して目に見える空間改善を提供しなかった(グラフは末端最適化の場合と重なる)。しかしながら、本発明者により実行された経験的測定は、両最適化を一緒に適用することに価値がまだあること示した。連鎖ノード最適化が末端最適化に加えて適用される場合、辿る必要があるポインタ数が少なく、データ局所性がより高く、メモリ階層(CPUキャッシュ)を守るため、性能は高まる。
ビットマップ圧縮
本発明の第3の空間最適化は、メモリにおいて、トライが疎に存在するトライのよりコンパクトな表現を提供する。これは、同じ値のセクション(例えば、疎に存在するノードの場合、値0を有するセクション又は密に存在するノードの場合、値1を有するセクション)を群化し効率的に格納することにより、ビットマップ(例えば、子ノードのキー部分値を示すビットマップ)のメモリ空間を低減することができる。本明細書ではこの第3の空間最適化を「ビットマップ圧縮」と呼ぶ。
本発明の第3の空間最適化は、1つ又は複数のノードを含むトライに適用され、ここで、2つ以上の子ノードを有するノード、好ましくは少なくとも各親ノードは、論理ビットマップの形態のビットマップと、幾つかのポインタとを含み、各ポインタには論理ビットマップにおいて設定されたビットが関連付けられ、各ポインタはノードの子ノードを指す。論理ビットマップは、本発明の他の態様に関して述べたように、キー部分値を含むビットマップに対応する。最適化は、論理ビットマップが複数のセクションに分割され、ヘッダビットマップ及び幾つかのコンテンツビットマップによって符号化されることにより達成され、ここで、各セクションにはヘッダビットマップ内のビットが関連付けられ、1つ又は複数のビットが設定された論理ビットマップの各セクションについて、ヘッダビットマップ内のセクションに関連付けられたビットは設定され、セクションはコンテンツビットマップとして格納される。
ヘッダビットマップ及び幾つかのコンテンツビットマップを使用して、論理ビットマップを格納することは、ビットが設定されていない論理ビットマップのセクションのコンテンツビットマップを省くことによって必要とされるメモリ空間を大幅に低減することができる。換言すれば、少なくとも1つの設定ビットを有するコンテンツビットマップ(すなわち、論理ビットマップのセクション)のみがメモリに格納される。論理ビットマップの各セクションが少なくとも1つの設定ビットを有する最悪の状況では、追加のヘッダビットマップを格納する必要があるため、メモリ使用はわずかに増大する。しかしながら、ノードは一般に疎に存在し、したがって通常、ビットマップ圧縮を使用する場合、必要なメモリは少なくなる。
本発明のビットマップ圧縮の一実施形態を図16に示し、図16は、ビットマップ圧縮なしの論理ビットマップ1602を含む親ノードを有するトライ1601のセクションを上部に示す。図16の下部において、ビットマップ圧縮がトライ1601の親ノードに適用された後に得られた親ノードを有するトライ1611のセクションを示す。トライ1611の親ノードは、ビットマップ圧縮から生じたヘッダビットマップ1612及び2つのコンテンツビットマップ1613、1614を含む。
両トライ1601、1611内の親ノードはポインタ1603〜1605を更に含む。トライ1601において、各ポインタには、論理ビットマップ1602において設定されたビット1606〜1608が関連付けられる。トライ1611では、ポインタ1603〜1605には、コンテンツビットマップにおいて設定されたビット1616〜1618が関連付けられる。
トライ1601内の論理ビットマップは、下部1611において、論理ビットマップ1602をセクション1621(例えば、8ビットの)に分割し、少なくとも1つの設定ビットを有するセクション1622、1623をコンテンツビットマップ1613、1614に格納することにより、ヘッダビットマップ1612及びコンテンツビットマップ1613、1614に変換される。設定されたビットがないセクションは、コンテンツビットマップとして格納されない。ヘッダビットマップ1612内の各ビットは、論理ビットマップの異なるセクションを表す。コンテンツビットマップ1613、1614は、ヘッダビットマップ1612において設定された各ビット1619、1620によって参照される。コンテンツビットマップ1613、1614は、セクションに関連付けられた設定ビット1619、1620がヘッダビットマップ1612に配置されるのと同順(図示せず)又は逆順で格納し得る。換言すれば、論理ビットマップの全てのコンテンツビットマップ内のあるコンテンツビットマップのランクは、ヘッダビットマップ内の全ての設定ビット内のそのコンテンツビットマップのセクションに関連付けられた設定ビットのランクに対応し得る。このようにして、トライを処理しながらコンテンツビットマップを容易にアドレス指定することができる。また、論理ビットマップのセクションは、好ましくは、メモリ内で全てコヒーレントである。したがって、論理ビットマップ全体は、ヘッダビットマップに続く幾つかのコンテンツビットマップにより、メモリにおいてコヒーレントに表すことができる。
好ましい実施形態では、全てのセクションは同じサイズを有する。同じサイズのセクションは、セクションの構造についての更なる情報が必要ないため、論理ビットマップの圧縮及び圧縮解除の効率的な処理を可能にする。また、ヘッダビットマップもセクションと同じサイズであり得る。
ヘッダビットマップ及びコンテンツビットマップの格納に異なる構造を使用することもできる。論理ビットマップのヘッダビットマップ及びコンテンツビットマップは、配列、リスト、又は連続した物理若しくは仮想メモリロケーションに格納し得る。図16に示すように、ヘッダビットマップ及びコンテンツビットマップが1バイトのサイズを有する場合、ビットマップは、トライ1601又は図9及び図12〜図14のトライで行われるように、長整数の配列の代わりにバイトの配列に格納し得、これにより位置合わせ損失が低減する。コンテンツビットマップは、好ましくは、ヘッダビットマップに相対して予め定義されたメモリ位置に格納される。コンテンツビットマップ及びヘッダビットマップを互いの近くに格納することにより、処理効率を改善し得る。図16では、コンテンツビットマップは、メモリにおいてヘッダビットマップの直後に格納される。
上述したビットマップ圧縮は、子ノードの参照に使用されるポインタのようなポインタに適用することもでき、直列化リーフビットマップに適用することもできる。これは通常、空間効率を更に改善するが、性能を損ない、その理由は、特定のポインタのオフセットを計算する際、可変サイズ符号化により、ポインタを通して反復する必要があるためである。
ビットマップ圧縮は、本発明の他の態様と組み合わせ得る。例えば、ポインタ低減と組み合わせて、ビットが設定されていない(論理)ビットマップにより記される本発明による末端分岐ノードは、いかなるコンテンツビットマップもなく、ヘッダビットマップのみとして符号化し得る。
図17は、図15を参照して上述した実験の結果を示す。しかしながら、連鎖ノード最適化及び末端最適化に加えて、ビットマップ圧縮が適用された。図15との比較において観察することができるように、ビットマップ圧縮により達成された空間節約は、連鎖ノード又は末端最適化が適用されない場合、約40%であり、連鎖ノードのみが加えて適用された場合、約50%〜約70%であり、末端最適化のみ又は連鎖ノード及び末端最適化の両方が加えて適用された場合、約30%〜約60%である。
キー符号化
本発明は、固定サイズ又は可変サイズのキー(例えば、文字列)を有する異なるプリミティブデータ型のキー及びトライ内のプリミティブデータ型の2つ以上の項目を含む複合キーを格納する方法を提供する。
制御情報を含むキー
本発明の好ましい実施形態では、キーは、キーに格納された構成要素の数、データ型、又は長さについての事前知識なしであっても、例えば、カーソルにより反復することができるような柔軟な方法で符号化することができる。
これらの実施形態は、データベースアプリケーション又は情報検索システムで使用されるトライ、例えば、上述したトライ及びトライデータ構造の実施形態の1つによるトライ又はトライデータ構造に適用される。トライは1つ又は複数のノードを含み、ノード、好ましくは各子ノードにはキー部分が関連付けられ、ルートノードからトライ内の別のノード、特にリーフノードへのパスは、ノードに関連付けられたキーを定義し、キーは、パス上のノードに関連付けられたキー部分を連結したものである。上述した柔軟性は、キーが、コンテンツ情報に加えて制御情報を含むことにより達成される。
キーは通常、1つ又は複数のキー部を含み、各キー部はコンテンツ情報を含み、コンテンツ情報は、キーに含まれる全体コンテンツ情報の一部である。キー部のそれぞれについて、制御情報は好ましくは、キー部に含まれるコンテンツ情報のデータ型を指定するデータ型情報要素を含む。
原理上、キー部に関連付けられた制御情報及びコンテンツ情報を配置する2つの方法がある。第1の方法を図18に示し、図18では、キー部又は好ましくは各キー部10、20、30は、データ型情報要素(図18における陰影付き要素)及びコンテンツ情報要素を含む。データ型情報要素は、コンテンツ情報要素のデータ型を指定する。これは、制御情報及びコンテンツ情報が両方とも異なるキー部10、20、30にわたり分散していることを意味する。この場合、キーのデータ型情報要素又は各データ型情報要素は通常、好ましくはデータ型情報要素の(直)前に、キー内のデータ型情報要素に関連付けられたコンテンツ情報要素によって配置される。したがって、データ型情報要素は、キー部10、20、30のプレフィックス又はヘッダ要素のようである。
キー部に関連付けられた制御情報及びコンテンツ情報を配置する第2の方法を図19に示し、図19は、データ型情報要素(図19における陰影付き要素)は、一緒に配置され、好ましくは、データ型を指定するコンテンツ情報要素と同順又は逆順で配置される。データ型情報要素のような制御情報は、好ましくは、キーのプレフィックス又はヘッダ要素として、キーにおいてコンテンツ情報の前に配置される。本発明者によって行われた研究では、同じデータ型を有するキーが同じプレフィックス(トライ内の開始ノード)を有し、したがって、トライ内で必要とされるノード数が低減し、空間節約に繋がるため、データ型情報要素を格納するこの第2の方法が好ましいことが分かった。
キー部に関連付けられたコンテンツ情報のデータ型は整数、長整数、倍精度浮動小数点、若しくは時間/日付けプリミティブの場合等の固定サイズであってもよく、又は文字列、例えば、ユニコード文字列若しくは可変精度整数の場合等の可変サイズであってもよい。本発明の幾つかの実施形態では、キーは、異なる(プリミティブ)データ型のコンテンツ情報を含む2つ以上のキー部を含む。
図20及び図21を参照して以下に説明するように、制御情報は、例えば、データ型情報要素の高位ビットのステータスによって最後のキー部を識別する情報を含み得る。代替的には、キー部カウントは別個に格納することができる。更に、制御情報は、トライが動的集合の格納に使用されるか、それとも連想配列の格納に使用されるかについての情報を含み得る。
キー部のコンテンツ情報は、1つのキー部分に含まれ得るが、通常、2つ以上のキー部分に含まれる。固定サイズのキー部の場合、キー部に含まれるコンテンツ情報を含むために必要なキー部分の数は通常、既知である。キー部に含まれるコンテンツ情報のデータ型が可変サイズのデータ型である場合、コンテンツ情報要素の終わりは、特定のシンボル、例えば、文字列の最後の文字としてヌル文字(「
」、ASCIIではNULと呼ばれる)を有するヌル終端文字列により記し得る。代替的又は好ましくは、図21を参照してユニコード文字列について以下に説明するように、キー部を含むキー部分の特定の1つ内の特定のビットによって記し得る。
上述したように、キー部のコンテンツ情報は多くの場合、2つ以上のキー部分に含まれるが、キー部分は、好ましくは、2つ以上のキー部のコンテンツ情報を含まない。換言すれば、キー部のコンテンツ情報は、キー部分の境界と位置合わせされる。同様に、キー部分は、好ましくは、データ型情報要素、キー部カウント、又はトライが動的集合の格納に使用されるか、それとも連想配列の格納に使用されるかについての情報のような2つ以上の制御情報要素の情報を含まない。この手法は通常、大きな位置合わせ損失なしで、実装をより容易且つ効率的にする。更に、これにより、以下に説明するように、異なるキー部のコンテンツ情報をインタリーブ様式で格納できるようになる。
本発明によるキー符号化の一例を図20に示す。トライに格納するキーは、制御情報2010及びコンテンツ情報2020を含む。キーは、コンテンツ情報を含む幾つかのキー部を含み、キー部のそれぞれについて、制御情報2010は、キー部に含まれるコンテンツ情報のデータ型を指定するデータ型情報要素2012、2013を含む。更に、制御情報2010は、トライが動的集合の格納に使用されるか、それとも連想配列の格納に使用されるかについての情報2011を含む。トライが連想配列の格納に使用される場合、キーに関連付けられたトライのリーフノードは通常、リーフ値2030又はそのようなリーフ値へのポインタを含む。
上述したように、本発明の好ましい実施形態では、トライ内の各親ノードは64ビット幅ビットマップを含み、したがって、トライ内の各キー部分は6ビット値を格納することが可能である。トライが動的集合の格納に使用されるか、それとも連想配列の格納に使用されるかについての情報2011は、第1のキー部分によって格納され、したがって、6ビットがこの情報に使用される。実際には、このイエス/ノー情報に対して1ビットで十分であるが、上述した位置合わせの理由で、6ビット値を格納可能なキー部分全体が使用される。情報は、各ビットが設定された64ビット幅ビットマップ及びノード2041の各子ノードへのポインタ(idx)を含む情報がノード2041に符号化される。
データ型情報要素2012、2013のそれぞれも、1つのキー部分によって格納され、その値はノード2042、2043のビットマップに符号化される。5ビットがデータ型情報に使用され、それにより、32個の異なるタイプの識別子が可能である。各キー部分によって格納することができる6番目のビット、例えば、キー部分の高位ビットは、データ型情報要素に関連付けられたキー部がキー内の最後のキー部であるか否かを示すのに使用される。図20の例では、データ型情報要素2013の高位ビットは、データ型情報要素2013に関連付けられたキー部がキー内の最後のキー部であることを示すように設定される。
各キー部に含まれるコンテンツ情報も、一般に6ビットの値2021、2022に分解され、各値は1つのキー部分によって格納される。ビットマップが(6ビット)値2021、2022の符号化に使用されるノードは、スペースの理由で図20に示されていない。例えば、キー部が32ビット整数値を含む場合、この32ビット値は6つのキー部分によって格納され、そのうちの最初のキー部分は2ビット値を格納し、最後の5つはそれぞれ6ビット値を格納する(32=2+6+6+6+6+6)。
図21は、本発明により符号化されたキーを格納するトライを示す。トライの各親ノードは、64ビット幅ビットマップを含む。キーは、値「100」を有する32ビット整数を含む第1のキー部と、値「ab」を有する文字列を含む第2のキー部とを含む。キーの制御情報は、(1)動的集合識別子、(2)整数識別子、及び(3)最後のタイプのマーカを有する文字列型識別子を含む。キーのコンテンツ情報は、(1)32ビット整数値「100」及び(2)ユニコードで符号化された文字列値「ab」を含む。
動的集合識別子は値0の6ビット数(0x00)である。したがって、図21のトライのルートノード2100のビットマップは、値「0」が設定されたビットを有し、このビットに関連付けられた第2レベルのノードには、値「0」のキー部分が関連付けられる。整数識別子は値5の6ビット数(0x05)である。したがって、第2レベルのノードのビットマップは、値「5」が設定されたビットを有し、このビットに関連付けられた第3レベルのノードには、値「5」のキー部分が関連付けられる。最後のキー部のマーカを有する文字列型識別子は、値39の6ビット数(0x27)である。したがって、第3レベルのビットマップは値「39」が設定されたビットを有し、このビットに関連付けられた第4レベルのノードには、値「39」のキー部分が関連付けられる。
整数値「100」は、「00 000000 000000 000000 000001 100100」として32ビット二進数で符号化される。したがって、整数値「100」の格納に使用されるレベル5〜レベル10のノードに関連付けられたキー部分には、値0(0x00)、0(0x00)、0(0x00)、0(0x00)、1(0x01)、及び36(0x24)がそれぞれ関連付けられる。
文字列値「ab」は、文字「a」のユニコード値の後に、文字「b」のユニコード値が続くものとして符号化される。各ユニコード文字は、ユニコード値に応じて2〜4個のキー部分を使用して格納され、これは10ビット、15ビット、又は21ビットを必要とし得る。本発明の好ましい実施形態で使用されるユニコード文字の符号化方式は以下である:
10ビットユニコード文字:00xxxx xxxxxx
15ビットユニコード文字:010xxx xxxxxx xxxxxx
21ビットユニコード文字:011xxx xxxxxx xxxxxx xxxxxx
文字列内の最後の文字は、高位ビットを設定することによって記され、これにより、最後の文字の符号化方式は以下になる:
10ビットユニコード文字:10xxxx xxxxxx
15ビットユニコード文字:110xxx xxxxxx xxxxxx
21ビットユニコード文字:111xxx xxxxxx xxxxxx xxxxxx
ユニコード文字「a」は値97(0x61)を有し、「0001 100001」として10ビットを用いてユニコードで符号化される。好ましい実施形態で使用される符号化方式によれば、ユニコード文字「a」は「000001 100001」として符号化される。ユニコード文字「b」は値98(0x62)を有し、「0001 100010」として10ビットを用いてユニコードで符号化される。好ましい実施形態で使用される符号化方式によれば、ユニコード文字「b」は「100001 100010」として符号化され、「b」は値「ab」を有する文字列内の最後の文字であるため、高位ビットが設定される。したがって、文字列値「ab」の格納に使用されるレベル11〜14のノードに関連付けられたキー部分には、値1(0x01)、33(0x21)、33(0x21)、及び34(0x22)がそれぞれ関連付けられる。
インタリーブされた多項目キー
本発明の実施形態は、2つ以上のデータ項目を含むクエリをより効率的に実行することができるようにデータを格納する方法を提供する。本発明による手法は特に、より効率的に問い合わせることができるように、キー若しくはキー及び値をデータベース又は情報検索システムに格納し、データベース又は情報検索システムクエリの結果キー若しくは結果キー及び結果値を格納し、又はクエリをより効率的に実行することができるように、データベースクエリの入力キー若しくは入力キー及び入力値を格納するのに有用である。
本発明のデータを格納する方法は上述したデータ構造を有するトライ等のトライを使用し、トライはノードを含み、ノード、好ましくは各子ノードにはキー部分が関連付けられ、ルートノードからトライ内の別のノードへのパスは、ノードに関連付けられたキーを定義し、キーは、パス上のノードに関連付けられたキー部分を連結したものである。複数のデータ項目を含むクエリにおいて性能利得を達成するために、2つ以上のデータ項目がキーに符号化され、少なくとも1つ又は2つのデータ項目、好ましくは各データ項目は2つ以上の構成要素からなる。キーは、2つ以上の連続セクションを含み、少なくとも1つ又は2つのセクション、好ましくは各セクションは、キーに符号化されたデータ項目の2つ以上の構成要素を含む。「項目」は、本明細書では「次元」と呼ばれることもあり、上記の「キー部」又は「キー部のコンテンツ情報」と呼ばれるものに対応し得る。
図22は、値(X=12,Y=45)を有する二次元キー、すなわち、2つのデータ項目X及びYを符号化するキーの一例を示す。これらのデータ項目は両方とも、項目Xの場合、2つの構成要素、すなわち、「1」及び「2」からなり、項目Yの場合、「4」及び「5」からなる。キーは、2つの連続セクションS1及びS2を含む。両セクションは、キーに符号化されたデータ項目x及びyのそれぞれの1つの構成要素を含み、セクションS1は、データ項目Xの1番目の構成要素「1」及びデータ項目yの1番目の構成要素「4」を含み、セクションS2は、データ項目Xの2番目の構成要素「2」及びデータ項目Yの2番目の構成要素「5」を含む。好ましい実施形態では、キーが、X1Y1X2Y2等のインタリーブ様式で複数のデータ項目を符号化すると言える。
好ましい実施形態によれば、キーの符号化は、キーのセクション、好ましくは各セクションが、キーにおいて符号化された各データ項目から少なくとも及び/又は多くとも1つの構成要素を含むようなものである。例えば、図22に示されるキーの両セクションS1及びS2は、キーに符号化されるデータ項目X=12及びY=45のそれぞれの厳密に1つの構成要素を含む。
更に、キーの2つ以上、好ましくは全てのセクションについて、異なるデータ項目に属する構成要素は、セクション内で同じシーケンスで並べられる。例えば、図22に示されるキーの両セクションにおいて、構成要素は、データ項目Xの構成要素が最初に来て、データ項目Yの構成要素が次に来るようなシーケンスで並べられる。
更に、データ項目の構成要素を含むセクションの順序は、好ましくは、データ項目内の構成要素の順序に対応する。例えば、図22に示されるキーでは、セクションS1の後にセクションS2が続き、これは各項目内でキーが構成要素を含む順序に対応し、S1は項目Xの構成要素「1」を含み、これは、項目X内で、セクションS2に含まれる構成要素「2」の前に来る。S1は項目Yの構成要素「4」も含み、これは、項目Y内で、セクションS2に含まれる構成要素「5」の前に来る。
キーの2つ以上、好ましくは全てのデータ項目は、同数の構成要素を有する。例えば、図22に示されるキーに符号化される項目X及びYは両方とも2つの構成要素を有する。しかしながら、キーのデータ項目は、異なる数の構成要素を有することもできる。これは、例えば、1つの項目が64ビット整数であり、別の項目が32ビット整数である場合であり得る。キーがX1Y1X2Y2等の厳密に規則正しいインタリーブ様式でデータ項目を符号化する場合、少数の構成要素を有するデータ項目を充填し得、結果として、例えば、X1Y1X2Y2X3*X4*等になる。代替的には、例えば、X1Y1X2Y2X3X4になるようにインタリーブ手法を変更する必要があり得る。
図23は、図22に示されるキーをトライにいかに格納することができるかの一例を与える。好ましい実施形態では、子ノード、好ましくは各子ノードに関連付けられたキー部分は、データ項目の一構成要素に対応する。換言すれば、データ項目、好ましくは各データ項目の構成要素、好ましくは各構成要素は、トライの1つの子ノードに関連付けられたキー部分に対応する。図23の例では、第2レベルのノード2302には、項目Xの最初の構成要素に対応するキー部分1が関連付けられ、第3レベルのノード2303には、項目Yの最初の構成要素に対応するキー部分4が関連付けられ、第4レベルのノード2304には、項目Xの2番目の構成要素に対応するキー部分2が関連付けられ、第5レベルのノード2305には、項目Yの2番目の構成要素に対応するキー部分5が関連付けられる。これは好ましくないが、子ノードに関連付けられたキー部分は、データ項目の構成要素の一部のみ又はデータ項目の2つ以上の構成要素に対応することもできる。
図22及び図23の例では、データ項目X及びYは2桁の十進数であり、構成要素は十進数である。本発明によるトライに格納されるキーに符号化されるデータ項目の他の例は、経度又は緯度等のジオロケーションデータ、インデックス、整数、長整数若しくは倍長整数、32ビット整数、若しくは64ビット整数等の任意の種類若しくはデータ型の数、文字列、バイト配列、又はこれらの2つ以上の組合せである。
データ項目が数である場合、データ項目の構成要素は数字(図22及び図23の例のように)であり得る。データ項目が文字列の場合、データ項目の構成要素は一文字であり得る。データ項目がバイト配列の場合、データ項目の構成要素は1バイトであり得る。
しかしながら、好ましい実施形態では、データ項目の構成要素は、データ項目の二進数符号化のビット群であり、ビット群は好ましくは6ビットを含む。これは、先に説明したように、好ましい実施形態では、子ノードのキー部分の値が、ビットが子ノードに関連付けられた親ノードに含まれるビットマップ内の(設定)ビットの値によって決まるためである。その結果、ビットマップのサイズは、キー部分に可能な英字を定義する。例えば、各ビットマップが64ビットサイズを有する場合、ノードのキー部分に利用可能な異なる値の数は26である。これは、データ項目の二進数符号化の6ビットを含むビット群を、ノードに関連付けられたキー部分で表すことができることを意味する。32ビットビットマップが使用される場合、5ビットを含む群を表すことができる等である。
例えば、データ項目が64ビット長整数であり、各構成要素が、整数の二寸数符号化の6ビット群である場合、データ項目は64/6=11個の構成要素を有する。データ項目がユニコードで符号化される文字である場合、先に説明したように、2ビット〜64ビットの構成要素を有し得る。データ項目が、幾つかの文字で構成される文字列である場合、好ましい実施形態における構成要素はなお6ビット群であり、すなわち、文字列は、任意の他のデータ項目のように、同じタイプの構成要素(6ビット群)を有する。文字列の数構成要素は、1文字の構成要素の数を文字列内の文字数で乗算したものに対応する。
ビット群、例えば、6ビット群として好ましい実施形態の構成要素を見なす代わりに、予め定義された基数又は底、例えば64を有する数字として見なすこともできる。
複数のデータ項目を有するキーを格納するインタリーブ方法は、図45及び図46並びに図61〜図65を参照した範囲クエリの以下の説明から容易に明らかになるように、複数のデータ項目を含む範囲クエリの性能を大きく改善することができる。更に、インタリーブ格納が、双方向サーチ及び複数のデータ項目を含む「NOT」演算を含むサーチで性能を改善することができることを当業者は理解しよう。
集合演算
本発明の実施形態は、データベース若しくは情報検索システムに格納された2以上のキーの集合又はデータベースクエリ若しくは情報検索システムクエリの結果キーの集合に対する論理積(ブールAND)、論理和(ブールOR)、差分(ブールAND NOT)、及び排他的論理和(ブールXOR)等の演算を含むデータベース又は情報検索システムにおいてクエリを実行する時間効率的な方法を提供する。本明細書では、これらの演算は「集合演算」又は「論理演算」と呼ばれる。
なお大半のデータベースはVolcano処理モデルを使用しており、これは「一度に1タプル」を意味する。しかしながら、これは、複数レベルのキャッシュ及びインメモリデータベースを考慮すると、近代のCPUアーキテクチャには効率的ではない。物理的実行プラン内の全ての演算は密にインタリーブされて実行されるため、演算子の結合命令フットプリントは、大きすぎて命令キャッシュに収まらないことがあり、演算子の結合状態は、大きすぎてデータキャッシュに収まらないことがある。したがって、幾つかのデータベースは一度に1演算子モデル又は両方の組合せであるベクトル化実行モデルを適用する。本発明によるインデックスデータ構造及び統一されたレベル単位処理モデルは、インデックストライへのアクセス及び演算子実装に関して非常にリーンな命令フットプリントを生じさせる。
図24は、従来技術によるデータベースクエリ処理の様々なフェーズの例示的な流れ図を示す。クエリは解析され(2401)、書き換えられ(2402)、最適化され(2403)、クエリ実行エンジン(QEE2405)がデータベース2406への先行ステップにより生成されたQEPを実行することができるようにクエリ実行プランQEPが準備され改善される(2404)。
図25は、従来技術によるデータベースで使用される例示的なQEPを示す。QEPはツリーで表され、ツリーでは、親ノード2501、2502は演算子であり、リーフ2503、2504はデータソースである。最初の演算では、テーブルスキャン2504からの結果はソート演算子2502によってソートされる。2番目の演算では、ソートの結果はインデックススキャン2503の結果と併合結合される。
図26は、従来技術によるデータベースの反復子ベースの実行モデルにおける演算子制御及びデータフローを示し、ここでは、演算子は以下のメソッドを実施する:Open(データの生成に向けて演算子を準備する)、Next(演算子消費者の需要下で新しいデータユニットを生成する)、及びClose(実行を終了させ、リソースを解放する)。Nextメソッドへの各呼び出しは新しいタプルを生成する。
反復子ベースの実行モデルは、演算子の統一モデルを提供し、この統一モデルは、データソース(データベーステーブル又はデータベースインデックス)のデータモデルから独立し、演算子ノードの中間結果を統一する。しかしながら、データの1つのみのユニット、例えば、レコードのみが演算子呼び出し毎に送られる。この手法は、それら実施形態が小さな結果集合を返す大きなサブ結果集合を結合する演算子にとっては非効率的である。
図27に示されるように、タプルを他の演算子に渡してもよく、図27は、従来技術によるデータベースのクエリ実行モデルによる一度の1タプル処理を示す。ルート演算子2701から始まり、next()への呼び出しは演算子の子2702、2703に伝搬され、データソース(及びツリー表現のリーフ)に達するまで以下同様である。このようにして、制御は消費者から生産者まで下に流れ、データはクエリ実行プラン演算子ツリー内で生産者から消費者に上に流れる。
1度に1タプル処理モデルは、小さな中間結果、ひいては低メモリ要件を有する。実行プラン内の演算子は密にインタリーブされて実行され、かなり複雑であり得る。しかしながら、膨大な量の関数呼び出し及び全演算子の結合状態は、大きな関数呼び出しオーバーヘッド並びに命令及びデータキャッシュミスを生じさせ、その理由は、フットプリントが往々にして大きすぎ、CPUキャッシュに収まらないためである。
反復子ベースの実行モデル及び1度に1タプル処理モデルは両方とも、効率的であるには、高度なクエリオプティマイザを必要とする。
図28は、リストのような、適したデータ構造で、演算子の結果として全てのタプルを即座に返す、従来技術によるデータベースのクエリ実行モデルによる1度に1演算子処理を示す。1度に1演算子手法は、低関数呼び出しオーバーヘッドを有する密なループを有してキャッシュ効率的であるが、データキャッシュに収まらず、更にはメインメモリにも収まらないことがある大きな中間結果を演算子毎に生み出し、この手法を無用なものにし得る。
本発明は、全てのデータソースがトライである新規の実行モデルにより従来技術の問題を解決する。2つ以上の入力トライが各論理演算(集合演算)に従って組み合わせられて、各結果トライのノードに関連付けられたキーの集合を取得する。
次に、データベースクエリは、出力として結果トライの表現、結果トライのノードに関連付けられたキーの集合若しくは結果トライのノードに関連付けられたキーの部分集合、特に結果トライのリーフに関連付けられたキー、又は結果トライのノードに関連付けられたキーから導出されるキー若しくは値の集合を提供する。代替的には、ドキュメント識別子のように結果トライのノードに関連付けられた他のデータ項目を提供し得る。出力として提供されるキーの集合は、トライで、例えば物理的トライデータ構造で提供し得る。「結果トライ」の概念は、本明細書では、論理演算を使用して入力をトライを結合する場合、取得する必要があるキーの集合を定義するのに使用されることに留意されたい。しかしながら、結果トライは、入力トライの結合中、必ずしも物理的トライデータ構造で形成される必要はなく、キーの出力集合は、例えば、カーソル又は反復子により提供することもできる。
一般的に言えば、論理演算を使用した2つ以上の入力トライの結合は、各入力トライにより記憶されたキーの各集合が論理演算を使用して結合される場合、取得されるキーの集合を記憶する(結果)トライを生成する。特に、論理演算が差(AND NOT)である場合、結果トライ内の親ノードは第1の入力トライ内の親ノードであり、結果トライの親ノードのリーフは、第1の入力トライ内の対応する親ノードの子ノードの集合と他の入力トライがある場合、他の入力トライ内の対応する親ノードの子ノードの集合とのAND NOT結合である。論理演算が差分ではない場合、例えば、論理演算が論理積(AND)、論理和(OR)、又は排他的論理和(XOR)である場合、結果トライ内の各ノードの子ノードの集合は、入力トライ内の対応するノードの子ノードの集合の論理演算(例えば、AND、OR、又はXOR)を使用した結合である。この状況では、各子ノードにキー部分に関連付けられ、ルートノードからトライ内の別のノードへのパスが、ノードに関連付けられたキーを定義し、キーは、パス上のノードに関連付けられたキー部分を連結したものであり、異なるトライの2つ以上のノードは、異なるトライのノードに関連付けられたキーが同一である場合、互いに「対応」する。
好ましい実施態様では、あらゆる演算子はそれ自体、例えば、各トライ(ノード)インターフェース実装することにより、クエリ実行プランツリー内のルート演算子ノードまで、消費者が論理演算を使用する別の演算子である場合を含めて消費者へのトライとして再び出現する。そのようなトライノードインターフェースはトライノードを表し、表すトライノードの子ノードにクエリ及び/又はトラバースする方法又は関数を提供し、トライの表現はトライのルートノードを表す。したがって、反復子インターフェースを使用する代わりに、ノードインターフェースを使用することができる。これにより、機能構成及びより簡易でクリーンなソフトウェアアーキテクチャが可能になり、データベースエンジンの性能を更に改善し、その理由は、実装複雑性の低さが直接、関数呼び出しオーバーヘッドの低減並びにデータ及び命令キャッシュミスの低減に繋がるためである。
好ましくは、トライを実装するデータ構造は上述したようなものである。特に、入力トライ内のノード、特に、少なくとも入力トライ内の全ての親ノードがビットマップを含み、トライ内の子ノードのキー部分の値が、ビットが子ノードに関連付けられた親ノードに含まれるビットマップのビット(集合)の値により決定される場合、有利である。通常、結果トライのノードの子ノードの集合は、論理演算を使用して、結果トライのノードに対応する入力トライのノードの子ノードの集合を結合することにより決定される。そのような実施態様では、入力トライの対応するノードの子ノードの集合の結合は、ビット単位AND、ビット単位OR、ビット単位AND NOT、又はビット単位XOR等の論理演算を使用して入力トライの対応するノードのそれぞれのビットマップをビット単位で結合することにより容易に実行することができる。結合ビットマップが得られ、結合の結果が結合ビットマップに基づいて実行される。換言すれば、結果トライのノードの子ノードは、結合ビットマップに基づいて、好ましくは結合ビットマップのみに基づいて決定(評価)される。その結果、ビットマップを結合するステップは、結果トライのノードの子ノードが決定される前且つ結果トライの評価が結果トライのノードの子ノードにトラバースされる前、実行される。
したがって、トライの実施態様における物理代数は、集合演算の論理代数に直接対応する。従来技術では、ビットマップはトライにおいて、ポインタに必要なメモリ空間を低減するためだけに使用されるが、本発明は、トライに対して集合演算を実行するためにビットマップを利用する。
上述したように、「CDBINode」と呼ばれるトライノードインターフェースの例示的な実施態様は以下の主要メソッドを有する:getBitSet()−トライノードの全ての非空子ポインタの設定ビットを有するビットマップを返す−及びgetChildNode(bitNum)−ビット数によって指定される所与のノード分岐の子ノードを返す。
図29は、本発明のクエリ実行モデルによるトライ制御及びデータフローを示す。演算子2903は、集合演算、例えば、論理積、論理和、差分、又は排他的論理和を入力ベースデータの2つの集合2901、2902に対して実行する。ベースデータの2つの集合はそれぞれ入力トライで提供され、例えば、物理的トライデータ構造に記憶され、2つの入力トライは、各集合演算に従って演算子2901により結合される。演算子2903はそれ自体、入力トライと同じトライ(ノード)インターフェースを実施することにより、その消費者にとってトライとして見える。エグゼキュータ2904は、上述したトライノードメソッドgetBitSet及びgetChildNodeを呼び出して、エグゼキュータと演算子との間の破線矢印で示されるように、演算子2903によって提供される結果をトラバースする。演算子と入力トライとの間の破線矢印によって示されるように、集合演算子を実行する際、同じメソッドgetBitSet及びgetChildNodeは、演算子2903によって呼び出されて、入力トライ2901、2902をトラバースする。実線矢印で示されるデータフロー方向において、ビットマップ及び子トライノードは入力トライ2901、2902から演算子2903に、そして演算子2903からエグゼキュータ2904に渡される。
理解されるように、高次集合演算の入力トライの1つ又は複数は、トライに対する同じ又は異なる論理演算子を使用した別の(低次)集合演算の出力であり得る。上述したように、トライへの低次集合演算のそのような出力は、物理的トライデータ構造として提供し得る。しかしながら、好ましい実施形態では、高次集合演算の入力トライは、低次集合演算の出力であり、仮想トライとして提供される。仮想トライは、高次演算で使用されるトライを評価可能な低次演算子として理解することができる。この場合、高次演算子が入力トライの表現を受信し、入力トライの少なくとも1つが低次演算子の出力として提供される瞬間において、その入力トライの物理的データ構造は全体として存在せず、実際には決して全く実現されない。
そのような状況を図29Aに示し、図29Aでは、高次演算子2906は、例えば、物理的トライデータ構造で提供された入力ベースデータの集合2905及び低次演算子2903の出力に対して高次集合演算を実行する。高次演算子2905は、入力ベースデータ2905と低次演算子2903の出力との高次集合演算を使用した結合である高次結果トライの少なくとも部分を評価する。低次演算子2903は少なくとも部分的に低次結果トライを評価し、低次結果トライは、低次集合演算を使用した、例えば、物理的トライデータ構造で提供される入力ベースデータの2つの集合2901、2902の結合である。低次集合演算は、高次集合演算と同じ演算又は異なる演算であり得る。本明細書で使用される場合、「トライの部分」という表現はトライのノード及び/又は分岐を指し得る。
低次結果トライの少なくとも部分は、高次結果トライの少なくとも部分を評価するステップ中のみ、計算される。低次結果トライの部分は、高次演算子の需要に応じて評価され、したがって、高次結果トライの部分及び低次入力結果トライの部分は、インタリーブ方式で評価される。したがって、低次結果トライの少なくとも部分は、高次結果トライの少なくとも部分が計算された後でのみ計算される。
理解されるように、高次演算子2905が高次結果トライを評価する際、低次結果トライの全ての部分を評価する必要があるわけではない。したがって、高次結果トライの評価に必要ではない低次結果トライの部分の少なくとも幾つか−好ましくは全て−は、評価されない。しかしながら、明かに、少なくとも、高次結果トライの評価に必要な低次結果トライの部分は評価する必要がある。
図30は、論理積(ブールAND)演算子3003を2つの入力トライ3001、3002に適用する一例を示す。入力トライは、読みやすさのために8変数であるが、好ましい実施態様では、上述したようなトライデータ構造が使用される。入力トライ3001は、キー「13」、「14」、及び「55」が関連付けられた3つのリーフノードを含む。入力トライ3002も、キー「13」、「15」、及び「64」に関連付けられた3つのリーフノードを含む。トライ3005は、入力トライ3001、3002のAND結合によって得られた結果トライを表現している。
観察することができるように、結果トライ内の各ノードの子ノードの集合は、入力トライ内の対応するノードの子ノードの集合のAND結合である。例えば、結果トライ3005のルートノードは、キー「1」が関連付けられた1つの子ノードを有する。この1つの子ノードは、入力トライ3001のルートノードの子ノードの集合(「1」,「5」)と、入力トライ3002のルートノードの子ノードの集合(「1」,「6」)との論理積を形成する場合、得られる。更に、キー「1」が関連付けられたノードも1つの子ノードを有し、これにはキー「13」が関連付けられる。実際に、ノード「13」は、入力トライ3001のノード「1」の子ノードの集合(「13」,「14」)と、入力トライ3002の対応するノード「1」の子ノードの集合(「13」,「15」)との論理積を形成する場合、得られる。
したがって、論理積演算の結果トライ、ここでは結果トライ3005は、全てのノード及び各入力トライ、ここでは入力トライ3001、3002に含まれるノードのみを含む。特に、ここではキー「13」に関連付けられたノードである結果トライのリーフノードの集合は、全てのリーフノード及び入力トライのそれぞれ全てに含まれるリーフノードのみを含む。
論理積演算子3003の好ましい実施形態によって実行されるアルゴリズムは、以下のように擬似コードで記載することができる:
1.nodeA=トライAのルートノード
2.nodeB=トライBのルートノード
3.nodeAのgetBitSet−>00100010
4.nodeBのgetBitSet−>01000010
5.ビット単位and−>00100010
6.for全ての設定ビット
nodeA=nodeAのgetChildNode
nodeB=nodeBのgetChildNode
ifリーフノードが
ビット単位andを実行する
else
反復(ステップ3)
この好ましい実施形態では、全てのトライノードは上述したようにビットマップを含む。更に、トライは、上述したようにgetBitSetメソッド及びgetChildNodeメソッドを含むインターフェースを実施するノードによって形成される。ビット単位AND演算が2つの入力トライの対応するノードのビットマップ間で実行されて、2つの対応するノードが共通に有する子ノードの集合を求める。
図31〜図34を参照して以下に示すように、本発明の解決策は、階層トライ構造を利用する。階層トライ構造では、トライはレベル毎に処理されるため、遅延評価が可能である。したがって、集合演算の性能を大幅に改善することができる。
図31は、論理積演算が実行される、例としての2つの入力トライ3110、3120を示す。全てのトライのように、入力トライ3110及び3120は、レベル1に1つの(ルート)ノードを有する。入力トライ3110は、入力トライ3110のルートノードに含まれるビットマップ3111内で4番目及び7番目のビットが設定されていることにより示されるように、レベル2に2つのノードを有する。入力トライ3120は、入力トライ3120のルートノードに含まれるビットマップ3121内で7番目のビットが設定されていることにより示されるように、レベル2に1つのノードを有する。両入力トライは、レベル2のノードの各ビットマップ内で設定されているビットに従属する三角形で示されるように、レベル3又はそれ以降のレベルに更なるサブトライを有する。
図32は、レベル1及び2における入力トライ3110及び3120の対応するノードのビットマップに対して実行されたビット単位AND演算を示す。入力トライのレベル1におけるルートノードは常に、互いに対応し、したがって、それらのビットマップは、第1のビット単位AND演算を用いて結合される。入力トライ3110のルートノードのビットマップ3111において4番目及び7番目のビットが設定されており、入力トライ3120のルートノードのビットマップ3121において7番目のビット(のみ)が設定されているため、結合ビットマップ3201において、7番目のビット(のみ)が設定される。レベル2において、入力トライ3110のルートのビットマップ3111の7番目のビットに従属するノードは、入力トライ3120のルートのビットマップ3121の7番目のビットに従属するノードに対応し、一方、入力トライ3110のルートのビットマップ3111の2番目のビットに従属するノードは、入力トライ3120内に対応するノードを有さない。したがって、ビットマップ3113及び3122(のみ)が、レベル2においてビット単位AND演算を用いて結合され、3番目及び6番目のビットが、結合ビットマップ3202において設定される。
図33は、入力トライ3110及び3120に対する論理積演算中の分岐スキップを示す。2つの入力トライのルートノードのビットマップ3111及び3121へのビット単位AND演算は、7番目のビットのみが設定された結合ビットマップ3201を生成するため、論理積演算は、入力トライ3110のルートノードのビットマップ3111の4番目のビットに従属する入力トライ3110の分岐をトラバースする必要がない。これは図33において、ビットマップ3111の4番目の位置における「X」及びスキップされた分岐の描画に使用される破線によって示される。同様に、レベル2において、入力トライ3110内のノードのビットマップ3113において7番目のビットのみが設定されているが、入力トライ3120内の対応するノードのビットマップ3122においては設定されていない。したがって、論理積演算は、ビットマップ3113の7番目のビットに従属する分岐をトラバースする必要はない。
最後に、図34は、トライ3110及び3120への論理積演算の結果トライを示す。レベル1及びレベル2での結果トライのノードに関連付けられたビットマップ3201及び3202はそれぞれ、図32に示されるビット単位AND演算によって計算された結合ビットマップに対応する。
図31〜図34の例は、一般に、入力トライを結合する集合演算の過程で、入力トライの分岐の幾つかをトラバースする必要がないことを示し、これは性能を劇的に増大させることができる。結合ビットマップを使用して、いずれの分岐を更にトラバースする必要があり、いずれの分岐をスキップできるかを判断し得る。この手法は、「結果予測」又は「ツリー刈込み」と呼ぶことができる。
図35は、論理和(ブールOR)演算子3503を図30の2つの入力トライ3001、3002に適用する一例を示す。入力トライ3001、3002のOR結合によって得られた結果トライ3605の表現を図36に示す。
観察することができるように、結果トライ内の各ノードの子ノードの集合は、入力トライ内の対応するノードの子ノードの集合のOR結合である。例えば、結果トライ3605のルートノードは、キー「1」、「5」、及び「6」が関連付けられた3つの子ノードを有する。これらの3つの子ノードは、入力トライ3001のルートノードの子ノードの集合(「1」,「5」)と、入力トライ3002のルートノードの子ノードの集合(「1」,「6」)との論理和を形成する場合、得られる。キー「1」が関連付けられたノードも、キー「13」、「14」、及び「15」が関連付けられた3つの子ノードを有する。実際に、これらのノードは、入力トライ3001のノード「1」の子ノードの集合(「13」,「14」)と、入力トライ3002の対応するノード「1」の子ノードの集合(「13」,「15」)との論理和を形成する場合、得られる。最後に、キー「5」及び「6」がそれぞれ関連付けられた結果トライ内のノードはそれぞれ、キー「55」及び「64」がそれぞれ関連付けられた1つの子ノードを有し、これらは入力トライ3001及び3002のそれぞれの対応するノードの子ノードである。
したがって、論理和演算の結果トライ、ここでは結果トライ3605は、入力トライ、ここでは入力トライ3001、3002の何れかに含まれるノードを全て含む。特に、結果トライのリーフノードの集合、ここでは「13」、「14」、「15」、「55」、及び「64」に関連付けられたノードは、何れかの入力トライに含まれるリーフノードを全て含む。
論理和演算子3503の好ましい実施形態によって実行されるアルゴリズムは、以下のように疑似コードで記載することができる。
1.nodeA=トライAのルートノード
2.nodeB=トライBのルートノード
3.nodeAのgetBitSet−>00100010
4.nodeBのgetBitSet−>01000010
5.ビット単位or−>01100010
6.for全ての設定ビット
ifビットがnodeA及びnodeBで設定されている
nodeA=nodeAのgetChildNode
nodeB=nodeBのgetChildNode
ifリーフノードが
ビット単位orを実行する
else
再帰(ステップ3)
ifビットがnodeAのみで設定されている
nodeA=nodeAのgetChildNode
TrieAのみ再帰(ビット単位orをスキップ)
ifビットがnodeBのみで設定されている
nodeB=nodeBのgetChildNode
TrieBのみ再帰(ビット単位orをスキップ)
ここでも、上述したように、全てのトライノードはビットマップを含み、トライは、上述したように、getBitSetメソッド及びgetChildNodeメソッドを含むインターフェースを実施するノードにより形成される。ビット単位OR演算は、2つの入力トライの対応するノードのビットマップ間で実行されて、2つの対応するノードの何れかに含まれる子ノードの集合を求める。ビットが2つの対応するノードの一方のみのビットマップにおいて設定されている場合、その一方のノードに従属するサブトライは結果トライに追加され、これは、上記疑似コードでは、「TrieAのみ再帰」/「TrieBのみ再帰」によって示されている。
図37は、差分(ブールAND NOT)演算子3703を図30の2つの入力トライ3001、3002に適用する一例を示す。トライ3705は、入力トライ3001、3002のAND NOT結合によって得られた結果トライの表現である。
観察することができるように、結果トライ3705の全ての親ノードは、第1の入力トライ3001の親ノードに対応する。結果トライ3705の親ノードに従属するリーフノードは、第1の入力トライ3001内の対応する親ノードの子ノードの集合と、入力トライ3002内の任意の対応する親ノードの子ノードの集合とのAND NOT結合である。
例えば、結果トライ3705のルートノードは、それら自体が親ノードである、キー「1」及び「5」が関連付けられた2つの子ノードを有する。これらの2つのノードは、それら自体が親ノードである、入力トライ3002のルートノードの2つの子ノードに対応する。キー「1」が関連付けられたノードは1つの子ノードを有し、この子ノードはリーフノードであり、キー「14」が関連付けられる。このリーフノードは、第1の入力トライ3001のノード「1」の子ノードの集合(「13」,「14」)と、入力トライ3002の対応するノード「1」の子ノードの集合(「13」,「15」)との差分を形成する場合、得られる。最後に、キー「5」が関連付けられた結果トライ内のノードは1つの子ノードを有し、この子ノードにはキー「55」が関連付けられ、第1の入力トライ3001のキー「5」を有するノードの子に対応する。キー「5」を有するこのノードは、入力トライ3002内に対応するノードを有さない。
したがって、差分演算の結果トライ、ここでは結果トライ3605は、第1の入力トライ、ここでは入力トライ3001に含まれる全ての親ノードを含む。結果トライのリーフノードの集合、ここではキー「14」及び「55」が関連付けられたノードは、第1の入力トライ、ここではトライ3001の全てのリーフノードから、第2の入力トライ、ここではトライ3002のリーフノードを差し引いたものを含む。
差分演算子3703の好ましい実施形態によって実行されるアルゴリズムは、以下のように擬似コードで記載することができる:
1.nodeA=トライAのルートノード
2.nodeB=トライBのルートノード
3.nodeAのgetBitSet−>00100010
4.nodeBのgetBitSet−>01000010
5.nodeAのビット集合−>00100010
6.for全ての設定ビット
if nodeA及びnodeBにおいてビットが設定されている
nodeA=nodeAのgetChildNode
nodeB=nodeBのgetChildNode
ifリーフノードが
ビット単位and−notを実行する
else
再帰(ステップ3)
ifビットがnodeAのみで設定されている
nodeA=nodeAのgetChildNode
TrieAのみ再帰(ビット単位and−notをスキップ)
ここでも、上述したように全てのトライノードは形成され、インターフェースを実施する。ビットが、入力トライ3001及び3002の両方の対応するノードのビットマップにおいて設定される場合、両トライでの再帰がある。ビットが、第1の入力トライ3001のノードのビットマップにおいてのみ設定されている場合、そのノードに従属するサブトライが結果トライに追加され、これは、上記擬似コードにおいて「TrieAのみ再帰」によって示されている。トライ3002のノードのビットマップにおいてのみ設定されているビットは無視される。ビット単位AND NOT演算は、2つの入力トライの対応するノードの子ノードがリーフノードである場合のみ、2つの入力トライの対応するノードのビットマップ間で実行される。
演算子の実行は、トライレベル(好ましい実施態様では、各レベルは基数/底64の1桁である)にわたる再帰降下である。各レベルにおいて、各ノードのビットマップは、予測ビットを通しての再帰が続く結果予測として使用される。したがって、入力トライの結合は、結果トライのルートノードに対して結合関数を実行することを含む。結果トライの入力ノードに対して結合関数を実行することは、論理演算を使用して結果トライの入力ノードに対応する入力トライのノードの子ノードの集合を結合し、結果トライの入力ノードに特定された各子ノードの結合関数を実行することにより、結果トライ(空であることもある)の入力ノードの子ノードの集合を特定することを含む。既に上述したように、結果トライのルートノード及び/又は入力ノードを物理的に生成する必要はない。
結果トライを評価するステップは、深さ優先探索、幅優先探索、又はそれらの組合せを使用して実行し得る。深さ優先探索において結果トライを評価することは、入力ノードの子ノードの1つに対して結合関数を実行することと、結合関数が子ノードの次の兄弟ノードに対して実行される前、その子ノードにより形成されるサブトライをトラバースすることとを含む。幅優先探索において結果トライを評価することは、結果トライの入力ノードに決定された子ノードのそれぞれに対して結合関数を実行することと、結果トライの入力ノードの任意の孫ノードに対して結合関数を実行する前、結果トライの入力ノードに決定された子ノードのそれぞれの子ノードの集合を決定することとを含む。
集合演算の入力トライの1つ又は複数は、仮想トライ、すなわち、入力トライを結合する演算中、オンデマンドで動的に生成されるトライであり得る。通常、論理演算を使用した入力トライの結合に必要な仮想トライの部分のみが動的に生成される。仮想入力トライが適用される幾つかの状況があり、そのうちの1つは、後述するデータベース範囲クエリの実装である。別の状況は、高次集合演算の入力トライの1つ又は複数が、図29Aを参照して上述した、トライに対する低次集合演算の出力である状況である。
仮想トライは、仮想トライが、例えば集合演算子の入力トライとして受信される場合、物理的データ構造が全体として存在しないトライである。仮想トライは、トライを評価可能な演算子として理解することができる。好ましくは、演算子は、トライのルートノードを表し、トライノードインターフェースを実装し、トライノードインターフェースはトライノードを表し、表すトライノードの子ノードをクエリ及び/又はトラバースする方法又は関数を提供する。
トライ又はトライの部分の「評価」は、トライ又はトライの部分の「レンダリング」又は「合成」と呼ぶこともでき、通常、トライ又はトライの部分をトラバースすることと、トラバースされたノードがトライに存在することの情報を提供することとを含む。トライ又はトライの部分の物理的データ構造を全体として実現することを含み得る。しかしながら、好ましい実施形態では、任意の所与の瞬間において、トライ又はトライの部分の物理的データ構造の全体未満が実現され、好ましくは、トライ又はトライの部分をトラバースするためにその瞬間において実現する必要がある、トライ又はトライの部分の物理的データ構造の部分のみが実現される。明らかなことに、トライ又はトライの部分を評価する間、任意の所与の瞬間において、少なくとも、トライ又はトライの部分をトラバースするためにその瞬間において実現する必要があるトライ又はトライの部分の物理的データ構造の部分が実現される。
好ましい実施形態では、仮想トライがトライ(ノード)インターフェースを実装する場合、トライ又はトライの部分は、上述したように、getBitSetメソッド及びgetChildNodeメソッドを使用して評価される。例えば、入力トライの1つが仮想トライである高次論理積演算中、高次論理積演算子はアクセスし、仮想範囲トライは、アプリケーションプログラミングインターフェース(API)を通して高次結果トライを評価するのに必要な仮想トライの構成要素を「オンザフライ」で送出する。例えば、仮想トライの現在ノードのビットマップは、getBitSet()メソッドを通してアクセスし得、子ノードは、先に紹介したgetChildNode()メソッドを通してアクセスし得る。APIは一方では各ビットマップを返し、他方ではオブジェクトを返し−実際のトライの子ノードの代わりに−、次の再帰の各ビットマップを提供する。高次演算子の場合、仮想トライは物理的トライデータ構造に実装されるトライと全く同じように見える。
通常、仮想トライの表現は、仮想トライの何らかの演算の入力として使用する演算子に与えられる。仮想トライの少なくとも部分は、演算を実行するステップ中、評価される(オンデマンドで)。演算を実行するために、仮想トライの部分の全てにアクセスする必要があるわけではない場合、演算の実行に必要ない部分の少なくとも部分は評価されず、好ましくは、演算の実行に必要な仮想トライの部分のみが評価される。これは、図29Aに示される場合での図37A及び図37Bに示され、仮想トライは低次集合演算子2903であり、仮想トライの表現は、入力トライとして高次集合演算子2906に提供され、高次集合演算子2906は仮想トライを高次結果トライの少なくとも部分の評価に使用する。高次結果トライは、論理演算を使用した、集合演算子2906の入力トライ、すなわち、仮想トライ及びベースデータ2905の結合である。図37A及び図37Bの場合、高次集合演算はAND演算であり、低次集合演算はOR演算である。
図37Aは3つのトライA、B、及びCを示す。好ましい実施形態では、上述したように、トライは32進数、64進数である。したがって、子ノードへのポインタを参照するビットマップは32ビット又は64ビットを含み得る。簡潔にするために、例は4進数トライを示す。トライは、トライAではトライルート3701、トライBではトライルート3702、トライCではトライルート3703により示されている。上述したように、各トライはビットマップ3704、3705、3706を含む。
図37Bは、中間結果として(A or B)を実現させずに又は生じさせずに、すなわち、物理的トライデータ構造を作成せずに、((A or B)and C)評価がいかに行われるかを示す。図は、2レベルでの式ツリー及びその評価を示す。第1のレベルでは、トライA(3704)及びトライB(3705)のルートノードのビットマップが、ビット単位OR演算により結合され、ビットマップ3709を生成する。ビットマップ3709は、トライCのルートノードのビットマップ3706とビット単位AND演算により結合される。その結果生成されたビットマップ3710は、トライCとの一致がないため、トライBをそれ以上の考慮から除外する。その結果生成された物理的トライデータ構造は、ルートノード3712を用いて示される。第2のレベルにおいて、トライA及びトライCのビットマップ3707及び3708は結合され−トライBはここでは一致がない−、ビットマップ3711を生成する。
図37A及び図37Bの例から見て取ることができるように、低次OR演算の結果が、完全に評価された物理的トライデータ構造としてではなく高次AND演算子への仮想入力トライとして提供されることにより、「レイジー評価(lazy evaluation)」が可能になる。低次OR演算の低次結果トライは、高次ANS演算の高次結果トライの評価中、評価される。したがって、低次結果トライの少なくとも部分は、高次結果トライの少なくとも部分が評価された後、評価される。実際に、高次結果トライの部分及び低次結果トライの部分はインタリーブ方式で評価され、低次結果トライの部分は、高次演算子の需要に応じて評価される。これにより、高次結果トライの評価に必要な低次結果トライの部分のみを評価することができる。
なお、幾つかの演算では、例えば、結果のカウント(濃度)のみが必要な場合、物理的結果トライデータ構造を実際に実現する必要はない。当業者ならまた理解するように、高次演算子は、例えば高次結果トライが更に高次の演算子の入力として使用される場合、高次結果トライの部分のみを評価し得る。同様に、低次演算子の入力トライは、物理的トライデータ構造である必要はなく、ここでも仮想トライであり得、これは例えば、更に低次の演算子の出力である。最後に、演算子が通常、入力トライの表現を取得し、ここで、トライの表現は、ポインタのような物理的トライデータ構造へのハンドルであり得ることに留意する。仮想トライの場合、表現は、トライを評価可能なトライ演算子へのハンドルであり得る。
範囲クエリ
論理積演算(ブールAND)による2つ以上のトライの結合は、有利なことに、範囲クエリを効率的に実行するのに使用することができる。「範囲」は、特定のデータ型の第1の値と第2の値との間の全ての値を含む順序付き離散値の集合として説明することができ、ここで、第1及び/又は第2の値は、範囲内に含まれることもあれば、又は含まれないこともある。範囲クエリは、値が、1つ又は複数の指定された値の範囲に対応する(一致する)、キーの集合内のキーを返す。
本発明による範囲クエリは、1つ又は複数の範囲についてサーチすべきキーの集合を格納したトライ(以下、「入力集合トライ」)と、1つ又は複数の範囲に含まれる全ての値を格納するトライ(以下、「範囲トライ」)との論理積演算によって実行される。トライは、好ましくは、上述したように実施される。サーチすべきキーの集合には通常、入力集合トライのノードが関連付けられ、一致する値の範囲を示す値(キー)には通常、範囲トライのノード、特に範囲トライのリーフノードが関連付けられる。サーチすべきキーの集合は通常、データベースに格納されたキーの集合、又はデータベースクエリの結果キー若しくは入力キーの集合、又は情報検索システムに格納されたキーの集合、又は情報検索システムクエリの結果キー若しくは入力キーの集合である。
クエリを実行する1つ又は複数の範囲の定義は、ユーザ入力又は他の方法によって得られる。定義は範囲トライの生成に使用され、範囲トライのノード(通常、リーフノード)に関連付けられた値は、1つ又は複数の範囲に含まれる値に対応する。次のステップにおいて、入力集合トライは、上述したように、論理積演算により使用して範囲トライと結合されて、結果トライのノードに関連付けられたキーの集合を取得する。最後に、結果トライのノードに関連付けられたキーの集合又は結果トライのノードに関連付けられたキー、特に結果トライのリーフノードに関連付けられたキーのサブセット、又は結果トライのノードに関連付けられたキーから導出されたキー若しくは値の集合が、出力として得られる。
図38は、1つ又は複数の範囲についてサーチすべきキーの集合を格納する入力集合トライ3801及び1つ又は複数の範囲に含まれる全ての値を格納するように生成された範囲トライ3802を示す。トライ3801及び3802は両方とも、論理積演算子3803によって結合されて、範囲トライ3802に格納された1つ又は複数の範囲内に値がある入力集合トライ3801内のキーの集合を取得する。上述したように、入力集合トライ及び範囲トライのみならず、論理積演算子それ自体も、図38において3つの三角形によって示されるように、各トライ(ノード)インターフェースを実施し得る。トライノードインターフェースが、上述したgetBitSet()メソッド及びgetChildNode(bitNum)メソッドを有する場合、論理積演算子3803はこれらの演算を呼び出して、図38おいて破線矢印で示されるように、入力集合トライ3801及び範囲トライ3802をトラバースし得る。実線矢印で示されるデータフロー方向において、ビットマップ及び子トライノードは、集合トライ3801及び範囲トライ3802から論理積演算子3803に渡される。
図39は、本発明による範囲クエリを実行する方法の一例を示す。入力集合トライ3901のリーフノードには、値「13」、「14」、及び「55」を有する3つのキーが関連付けられる。範囲トライ3902は、値が範囲すなわち[14,…,56]内にあるキーが関連付けられた全てのリーフノードを含むように生成される。範囲トライの各レベルにおいて、範囲の終わりにあるノード(範囲トライ3902の例では、ノード1及び5)は、結果に部分的に寄与する。範囲の終わりの間のノード(範囲トライ3902の例では、ノード2、3、及び4)及びそれらに従属するサブトライは、結果に完全に寄与する。論理積演算子3903による入力トライ3901と範囲トライ3902とのAND結合は、結果トライ3905のノードに関連付けられたキーの集合を取得する。エグゼキュータ3904は、例えば、結果トライ3905に関連付けられたキーの値、すなわち、「14」及び「55」を出力し得る。この出力は、範囲[14,…,56]内にある入力集合トライ3901のリーフノードが関連付けられた全てのキーの値に対応する。
論理積演算子3903によって実行されるアルゴリズムは、以下のように疑似コードで記載することができる:
1.nodeA=トライAのルートノード(入力集合トライ)
2.nodeB=トライBのルートノード(範囲トライ)
3.nodeAのgetBitSet−>00100010
4.nodeBのgetBitSet−>01111110
5.ビット単位and−>00100010
6.for全ての設定ビット
nodeA=nodeAのgetChildNode
nodeB=nodeBのgetChildNode
ifリーフノードが
ビット単位andを実行する
else
再帰(ステップ3)
範囲トライ3902は、範囲トライが非常に多くのノードを含み得ることを示す一例である。したがって、全てのノードを有する範囲トライ3902の実現は、時間及びメモリ空間に関してコストがかかる。このため、範囲トライは、すでに上記に記載の仮想トライ、すなわち、論理積演算中、需要に応じて動的に生成されるトライとして実施し得る。これは、図39において、破線で描かれた範囲トライ3902の三角形の中味によって示されている。
論理積演算中、論理積演算子はアクセスし、仮想範囲トライは、アプリケーションプログラミングインターフェース(API)を通して論理積演算の結果トライの評価に必要な仮想トライの構成要素を「オンザフライ」で送出する。例えば、仮想トライの現在ノードのビットマップに先に紹介したgetBitSet()メソッドを通してアクセスし得、子ノードにgetChildNode()メソッドを通してアクセスし得る。APIは一方では各ビットマップを返し、他方ではオブジェクトを返し−実際のトライの子ノードの代わりに−、次の再帰の各ビットマップを提供する。論理積演算子の場合、仮想トライは物理的トライデータ構造に実装されるトライと全く同じように見える。
通常、論理積演算の結果トライの評価に必要ない仮想トライの部分の少なくとも幾つかは評価されず、好ましくは、論理積演算により入力集合トライと範囲トライとを結合するのに必要な仮想範囲トライの部分のみが動的に生成される。図39の例では、上述した分岐スキップに起因して、範囲トライのルートノードのビットマップにおいて設定されたビット2、3、4、及び5が関連付けられた仮想サブトライは、論理積演算中、アクセスされず、このため、それらのノードのいずれも物理的に生成(レンダリング又は合成)されない。
本発明による範囲クエリの幾つかの実施形態では、図39に示される実施形態のように、入力集合トライのリーフに関連付けられたキーは、特定のデータ型の1つのデータ項目を符号化する。これらの実施形態は、「一次元」範囲クエリと呼ぶこともできる。一次元範囲クエリでは、1つ又は複数の範囲の定義は、その1つのデータ項目の1つ又は複数の範囲の定義を含む。
多次元範囲クエリ処理
本発明による範囲クエリの他の実施形態では、入力集合トライのリーフノードに関連付けられたキーは、特定のデータ型の2つ以上のデータ項目を符号化する。この場合、1つ又は複数の範囲の定義は、データ項目のうちの1つ又は複数のデータ項目の1つ又は複数の範囲の定義を含む。そのような実施形態は「多次元」範囲クエリと呼ぶこともできる。原理上、各次元の範囲クエリを実行し、結果の論理積を実行することが可能であるが、関わるトライ及び演算子が多すぎるため、効率的ではない。
本発明による効率的な多項目又は多次元範囲クエリ処理の一例を図40に示す。入力集合トライ4001は二次元又は2項目トライであり、そのリーフノードのそれぞれには、値対(x,y)を指定するキーが関連付けられる。図54〜図57を参照して以下に説明するように、そのような値対を使用して、例えば、ジオロケーションデータの経度及び緯度又は(経度,ID)又は(緯度,ID)のような複合キーを指定することができる。この例での次元x及びyのそれぞれは、読みやすさのために8変数系での2つの数字を含むが、好ましい実施形態では、上述したようなトライデータ構造が使用される。以下の説明から明らかになるように、x次元及びy次元は、1キー内の複数のデータ項目の上述したインタリーブ符号化に従って、入力集合トライ4001にインタリーブ様式で格納される。
入力集合トライ4001は、レベル1においてルートノードを有する。ルートノードに関連付けられたビットマップは、x次元の第1の数字の値を示す。ビット「1」及び「5」が、ルートノードに関連付けられたビットマップにおいて設定され、これは、入力集合トライに格納されたキーのx次元の第1の数字が「1」又は「5」の何れかであることを示す。レベル2におけるノードに関連付けられたビットマップは、y次元の第1の数字の値を示す。ビット「3」及び「4」が、ルートノードのビット「1」に従属するレベル2におけるノードに関連付けられたビットマップにおいて設定され、ビット「6」が、ルートノードのビット「5」に従属するレベル2におけるノードに関連付けられたビットマップにおいて設定される。これは、x次元が「1」で開始するキーのy次元の第1の数字が「3」又は「4」の何れかであり、x次元が「5」で開始するキーのy次元の第1の数字が「6」であることを示す。レベル3においてノードに関連付けられたビットマップは、x次元の第2の数字の値を示す。これらのビットマップにおいて設定されたビットは、y次元が「3」で開始されるx次元「12」及び「16」を有するキーがあり、y次元が「4」で開始されるx次元「12」及び「15」を有するキーがあり、y次元が「6」で開始されるx次元「56」を有するキーがあることを示す。レベル4におけるノード及びレベル5におけるノードのビットマップは図40に示されておらず、レベル4におけるノードに従属する小さな三角形によってのみ示されている。
多項目の範囲トライ又は多次元範囲クエリは、1項目又は入力集合トライのリーフに関連付けられたキーによって符号化された各データ項目の一次元範囲トライを結合することによって得られる多項目範囲トライであり得、データ項目の1項目範囲トライは、データ項目の1つ又は複数の範囲に含まれる全ての値を格納する。1項目範囲トライは、上述したような仮想範囲トライであり得る。これは、1項目範囲トライを結合して多項目範囲トライを得るため、又は論理積演算によって入力集合トライと1項目トライとを結合するために必要な仮想1項目トライの部分のみが動的に生成されることを意味する。
図40の例では、二次元範囲クエリについて2つの一次元入力範囲が得られる:x次元の範囲[15,…,55]及びy次元の範囲[30,31]。x次元の範囲[15,…,15]を格納する(仮想)範囲トライ4002が作成され、y次元の範囲[30,…,31]を格納する(仮想)範囲トライ4003が作成される。
幾つかの多次元範囲クエリでは、データ項目(次元)の幾つかについて、範囲の定義が取得されないことがある。例えば、ユーザは、図40の二次元入力集合トライ4001に対して範囲クエリ処理を実行するためのx次元の範囲[15,…,55]のみを指定し、y次元の範囲の定義を指定しないことがある。これは、ユーザが、y次元の値に関係なく、x次元の値が15と55との間にある入力集合トライ4001内に格納された全てのキーに関心があることを意味する。範囲が指定されない次元はスキップ又は無視すべきである。これは、範囲の定義が得られないデータ項目にであっても、データ項目の可能な全範囲の値を格納する(仮想)1項目範囲トライを作成することによって達成することができる。そのようなトライは「ワイルドカードトライ」と呼ぶこともできる。例えば、一実施態様では、MatchAllトライは、上記トライ(ノード)インターフェース(「CDBINode」)を実施するトライである。その任意のノードでgetBitSet()メソッドを呼び出すと、全てのビットが設定されたビットマップが常に返される。
1項目又は一次元範囲トライの結合から得られる多項目又は多次元範囲トライは通常、1項目(一次元)範囲トライに格納されたデータ項目の値の全ての組合せを格納する。例えば、x次元の範囲が[11,…,13]であり、y次元の範囲が[7,…,8]である場合、結合された二次元範囲トライは、(x,y)値対(11,7)、(11,8)、(12,7)、(12,8)、(13,7)、及び(13,8)のキーを格納する。
図41は、図40の一次元範囲トライ4002及び4003の異なる部分がいかに結合されて、図42に示されているインタリーブされた二次元範囲トライを得るかを示す。図42において観察することができるように、結合された二次元範囲トライ内のx次元及びy次元は、図40の入力集合トライ4001と同じインタリーブされた様式で格納される。比較として、図43は、図40の一次元範囲トライ4002及び4003がいかに結合されて、図44に示される非インタリーブ二次元範囲トライを得るかを示す。抽象的な視点から、これは、全てのX値キーを含むトライを生成し、各リーフノードは、全てのY値キーを含むトライのルートである。
本発明の好ましい実施形態では、これは、一次元及び多次元範囲クエリの両方に当てはまり、範囲トライは、入力集合トライと同じ構造又はフォーマットを有する。したがって、多次元入力集合トライがデータ項目をインタリーブ様式で格納する場合、多次元範囲トライは好ましくは、インタリーブ格納を使用し、入力集合トライが非インタリーブ様式でデータ項目を格納する場合、多次元範囲トライも好ましくは、インタリーブ格納を使用しない。更に、範囲トライのリーフに関連付けられたキーは、好ましくは、入力集合トライのリーフに関連付けられたキーと同じデータ型のデータ項目を符号化する。最後に、範囲トライにおいて、特定のデータ型のデータ項目又はそのようなデータ項目の構成要素は好ましくは、入力集合トライ内の対応するデータ項目又はデータ項目の構成要素と同じレベルのノードにおいて符号化される。
多項目又は多次元範囲クエリ処理の幾つかの実施形態では、多項目又は多次元範囲を得るための1項目又は一次元範囲トライの結合は、多項目範囲トライとの入力集合トライの結合を実施する関数(例えば、論理積演算子)への入力として多項目範囲トライを提供する関数によって実行される。これは、結合がインタリーブ演算子6404によって実行される図64の例に示される。
他の実施形態では、多項目又は多次元範囲トライを得るための1項目又は一次元範囲トライの結合は、範囲トライとの入力集合トライの論理積を実施する関数又は演算子内で実行される。この場合、多次元範囲トライは概念的にのみ存在する。実際には、範囲トライとの入力集合トライの結合を実施する関数又は演算子は、複数の(仮想)一次元範囲トライが一緒に(仮想)多次元範囲トライを形成した場合等、(仮想)一次元範囲トライにアクセスする。範囲が指定されていない次元がある場合、これらの次元は、例えば、上述したようにワイルドカードトライを作成することにより、範囲トライとの入力集合トライの論理積を実施する関数又は演算子によってスキップ又は無視される。
図40の例では、結合は二次元論理積(AND)演算子4004によって実行される。論理積演算子4004によって実行されるアルゴリズムは、以下のように疑似コードで記載することができる:
1.nodeA=トライAのルートノード(入力集合トライ)
2.nodeB=トライBのルートノード(x次元の範囲)
3.nodeC=トライCのルートノード(y次元の範囲)
4.nodeAのgetBitSet−>00100010
5.nodeBのgetBitSet−>00111110
6.ビット単位and−>00100010
7.for全ての設定ビット
nodeA=nodeAのgetChildNode,
8.nodeAのgetBitSet−>00011000
9.nodeCのgetBitSet−>00001000
10.ビット単位and−>00001000
11.for全ての設定ビット
子nodeAの子ノードを取得,
nodeB=nodeBのgetChildNode
nodeC=nodeCのgetChildNode
ifリーフノードが
ビット単位andを実行する
else
再帰(ステップ4)
(仮想)多次元範囲トライは、一次元範囲トライが実際に結合されて(仮想)多次元範囲トライを取得した場合、少なくとも、多次元範囲トライが入力集合トライと同じ構造又はフォーマットを有するとき、結果トライ内の各ノードの子ノードの集合が、入力集合トライ内の対応するノードの子ノードの集合と、多次元範囲トライとのAND結合の結果であるという意味で、概念的に作成される。
例えば、図40は、入力集合トライ4001のように、x次元及びy次元をインタリーブ様式で格納する結果トライ4006を示す。結果トライ4006は、値(x=1,y=3)を有するキーが関連付けられたノード4007を有する。このノードは、値x=1を有するキーが関連付けられたノード4108の子ノードの集合全体を表す。結果トライ4006のノード4007に対応する入力集合トライ4001のノードはノード4009であり、ノード4009は、値x=1を有するキーが関連付けられたノードである。図40の一次元範囲トライ4002及び4003が実際に結合される場合に得られ、入力集合トライ4001と同じ構造及びフォーマットを有する多次元範囲トライ4100を図41に示す。結果トライ4006のノード4007に対応する多次元範囲トライ4100のノードはノード4101であり、ノード4101は、値x=1を有するキーが関連付けられたノードである。入力集合トライ4001のノード4009の子ノードの集合(ノード4010及び4011)と、多次元範囲トライ4100のノード4101の子ノードの集合(ノード4102)とのAND結合は、結果トライ4006のノード4007を生成する。
多次元又は多項目入力集合トライの異なる次元又は項目をインタリーブ様式で格納することは、多くの場合、図45及び図46を参照してこれより説明するように、より効率的な範囲クエリに繋がる。
図45は、図40の入力集合トライ4001と同じ値であるが、非インタリーブ様式で格納する入力集合トライ4501を示す。入力集合トライ4001と全く同じように、入力集合トライ4501は、レベル1においてルートノードを有し、ルートノードに関連付けられたビットマップは、x次元の第1の数字の値を示す。しかしながら、入力集合トライ4501のレベル2におけるノードに関連付けられたビットマップは、インタリーブ入力集合トライ4001におけるy次元の第1の数字ではなく、x次元の第2の数字の値を示す。レベル3におけるノードに関連付けられたビットマップは、y次元の第1の数字の値を示し、レベル4におけるノードのビットマップ(図45に示されず)は、y次元の第2の数字の値を示す。
本発明により、各(非インタリーブと同様に)二次元範囲トライとの入力集合トライ4501のAND結合を実行する場合、範囲X=[15,…,55]及びY=[30,…,31]を有する二次元範囲クエリについてトラバースされるノードは、図45において陰影が付されている(レベル5におけるノードは示されない)。レベル4において1つのみのノード(x=16,y=3)が陰影付きノードであるが、3つのより上位のレベルでは、合計で6つのノードをトラバース(訪問)する必要がある:ルートノード、x=1、x=5、x=15、x=16、及びx=53。
比較として、図46は、図40のインタリーブ入力集合トライ4001を示し、ここでも、本発明により範囲X=[15,…,55]及びY=[30,…,31]を有する二次元範囲クエリについてトラバースされるノードは、陰影が付されている(レベル5におけるノードは示されない)。図45と同じレベル4における1つのノード(x=16,y=3)は、陰影付きノードであるが、3つのより上位のレベルでは、合計で4つのノードをトラバースする必要がある:ルートノード、x=1、x=5、及び(x=1,y=3)。
この理由は、非インタリーブ入力集合トライ4501では、範囲[15,…,55]内に入る全てのx値が最後の(第2の)数字まで特定されるが、インタリーブ入力集合トライ4001では、y次元の第1の数字を見ることにより、トラバースする価値がないノードをより素早くなくすことができるためである。別の次元の第1の数字を見ることによってノードをなくす機会は、同じ次元の更なる数字を見ることによりノードをなくす機会よりも多い。理解されるように、異なる次元が有する数字が多いほど、インタリーブ式格納の性能利得は大きくなる。
上述したように、範囲クエリ処理は、例えば、一次元範囲クエリの場合又はユーザが入力集合トライに格納された多次元キーの全ての次元に興味を有する場合、出力として、入力集合トライのリーフに関連付けられたキーの集合を提供し得る。代替的には、範囲クエリ処理は、出力として、入力集合トライのリーフに関連付けられたキーによって符号化されたデータ項目のサブセットを符号化する縮小項目キーの集合を提供し得る。この一例を図47及び図48に示す。
図47では、二次元又は二項目トライ入力集合トライ4701は、図40の入力集合トライ4001と同じであり、各リーフノードには、値対(x,y)を指定するキーが関連付けられる。ユーザは、例において、入力集合トライに格納されている全てのx値に興味を有する。したがって、詳細に示されていないが、一次元範囲トライ4702は、x次元の可能な全ての範囲全体を格納するワイルドカードトライであり、一次元範囲トライ4703は、y次元の可能な値の範囲全体を格納するワイルドカードトライである。
図40の一次元範囲トライ4002及び4003のように、一次元範囲トライ4702及び4703は、少なくとも概念的に結合されて、二項目又は二次元範囲トライを取得する。一次元範囲トライは両方ともワイルドカードトライであるため、二次元範囲トライは可能な全ての値対(x,y)を含む。次に、二次元範囲トライは、二次元論理積(AND)演算子4704によって二次元入力集合トライ4701と結合される。図40の二次元論理積(AND)演算子4004のように、論理積演算子4704は、論理積演算に従って二次元入力集合トライを二次元範囲トライと結合して、各結果トライのノードに関連付けられたキーの集合を取得する。更に、先に説明したように、結果トライ内の各ノードの子ノードの集合は、二次元入力集合トライ内の対応するノードの子ノードの集合と、二次元範囲トライ内の対応するノードの子ノードの集合とのAND結合である。二次元範囲トライは可能な全ての値対(x,y)を格納しているため、結果トライは入力集合トライと同一である。
図40の論理積演算子4004とは対照的に、ユーザは入力集合トライに格納されているx値にしか興味がないため、図47の論理積演算子4704は、入力集合トライのリーフに関連付けられた(x,y)キーの集合を出力として提供しない。むしろ、論理積演算子4704は、出力として、x次元のみの値の集合、この例では、入力集合トライに格納されている全てのx値の集合を提供する。
範囲クエリ処理が、出力として、縮小項目キーの集合を提供する場合、図47のように、縮小項目キーに符号化されないデータ項目に関連する入力集合トライの異なる分岐から得られる縮小項目キーの集合は、複製を含まないことができる。例えば、図47から分かるように、入力集合トライ4701内にはx値が12である少なくとも2つのリーフノードがあり、すなわち、y値の第1の数字は3(12,3,…)である少なくとも1つ及びy値の第1の数字が4(12,4,…)である少なくとも1つがある。特に出力集合が上流演算子で使用される場合、出力を提供する前に複製キーをなくすために、縮小項目キーに符号化されないデータ項目に関連する入力集合トライの異なる分岐から得られる縮小項目キーの集合は、出力を提供する前にマージされる。二次元では、マージは、許容可能に効率的に、入力集合トライのレベル毎に実行することができる。しかしながら、多くの場合、縮小項目キーの集合を新たに作成されたトライに書き込み、それにより、複製が自動的になくなることが最も効率的であろう(例えば、入力集合トライが3つ以上の次元を有する場合)。
図47の例では、出力集合内の複製x値をなくすために、論理積演算による二次元範囲トライとの入力集合トライ4701の結合の結果として得られたx値キーの集合は、x値のみを有するキーがノードに関連付けられた、新たに作成された一次元トライに書き込まれる。この新たに作成された一次元トライを図48に示す。リーフノードに関連付けられたキーの値は、入力集合トライ4701に格納された全てのx値の集合に対応する。
x値のみを出力する二次元論理積演算子4004によって実行されるアルゴリズムは、以下のように擬似コードで記載することができる:
1.nodeA=トライAのルートノード(入力集合トライ)
2.nodeB=トライBのルートノード(x次元のワイルドカードトライ)
3.nodeC=トライCのルートノード(y次元のワイルドカードトライ)
4.nodeAのgetBitSet−>00100010
5.nodeBのgetBitSet−>11111111
6.ビット単位and−>00100010
7.for全ての設定ビット
nodeA=nodeAのgetChildNode,
8.nodeAのgetBitSet−>00011000
9.nodeCのgetBitSet−>11111111
10.ビット単位and−>00011000
11.for全ての設定ビット
子nodeAの子ノードを取得,
nodeB=nodeBのgetChildNode
nodeC=nodeCのgetChildNode
ifリーフノードが
ビット単位andを実行する
結果キー(xのみ)を出力トライに書き込む
else
再帰(ステップ4)
図47の例では、x次元の値のみが出力として提供される。理解されるように、y次元の値のみが出力として提供される場合、同じ原理が適用される。更に、一次元範囲トライ4702及び4703は両方ともワイルドカードトライであるため、入力集合トライ4701に格納された全てのx値は、出力として提供される。理解されるように、一次元範囲トライ4702及び/又は4703が、全ての可能なx値及び/又はy値のサブセットのみを格納する場合、入力集合トライ4701に格納された全てのx値のサブセットのみを出力として提供し得る。例えば、仮に一次元範囲トライ4702が図40の範囲トライ4002と同じであり、範囲[15,…,55]内のx値のみを格納する場合、論理積演算子4004によって提供される出力は、x=12の値を含まないであろう。別の例として、仮に一次元範囲トライ4702及び4703が両方とも、図40の各範囲トライ4002及び4003と同じであり、範囲[15,…,55]内のx値のみを格納し、そしてそれぞれ範囲[30,…,31]内のy値のみを格納する場合、論理積演算子4004によって提供される出力は、x=16の値のみを含むことになろう。
ファジーサーチ
テキスト検索用途での往々にしての要件は、近似文字列一致−ファジーサーチ機能とも呼ばれる−を提供することである。これは、パターンに厳密ではなく概ね一致する文字列の発見である。
この「ファジーさ」(2つの文字列シーケンス間の差)の典型的な尺度は、レーベンシュタイン距離である。2つの文字列間のレーベンシュタイン距離は、ある文字列を別の文字列に変更するのに必要な一文字編集(文字の挿入、削除、又は置換)の最小数である。
上述した仮想範囲トライと同様に、本発明の一態様は、インデックストライのようなストレージトライとブールANDを使用して論理積演算されて、一致するキー列又は一致するキー列を含むドキュメントを返す、好ましくは仮想のファジー一致トライに関する。インデックストライは、上述したように、2つのキー部(文字列,長)として、発生した言葉及びドキュメントIDをそれぞれ格納し得る。
本発明のこの態様によれば、データは、近似文字列一致を実行することによって電子データベース又は情報検索システムから検索される。まず、サーチ文字列が取得される。次に、サーチ文字列及び/又はサーチ文字列の変形を含む近似文字列の集合を格納している一致トライが構築される。一致トライは、論理積演算を使用して、電子データベース若しくは情報検索システムに格納された文字列の集合又は電子データベースクエリ若しくは情報検索システムクエリの結果文字列を格納したストレージトライと結合される。換言すれば、結果トライの少なくとも部分は評価され、結果トライは、論理積演算を使用した、電子データベース又は情報検索システムに記憶された文字列の集合を記憶したストレージトライとの一致トライの結合である。結果トライは、ストレージトライにより記憶されたキーの集合が一致トライにより記憶されたキーの集合と論理積演算される場合、取得されるキーの集合を記憶したトライである。
ストレージトライは、例えば、(文字列,長)等の2つのキー部として、ドキュメントに含まれる文字列及び各ドキュメント識別子を格納するインデックストライであり得る。一致トライに記憶された文字列の集合に含まれる文字列は通常、電子データベース又は情報検索システムに永続的に記憶され、及び/又は電子データベース又は情報検索システム内のエントリを表す。
上述した論理積のように、結果トライが取得される。結果トライ内の各ノードの子ノードの集合は、一致トライ内の対応するノードの子ノードの集合と、ストレージトライ内の対応するノードの子ノードの集合との論理積であり、同じキーが異なるトライのノードに関連付けられている場合、異なるトライのノードは互いに対応する。通常、一致トライ、ストレージトライ、及び結果トライは、同じ構造又はフォーマットを有する。このセクションにおいて別段のことが記される場合を除き、上述したトライへの論理積演算の全ての態様は、ファジーサーチの状況でのトライの論理積にも当てはまる。
上述したように、トライは1つ又は複数のノードを含み、各子ノードにはキー部分が関連付けられ、ルートノードからトライ内の別のノードへのパスは、ノードに関連付けられたキーを定義し、キーは、パス上のノードに関連付けられたキー部分を連結したものである。トライは、上述したトライデータ構造を使用して実施することができる。しかしながら、上述した例とは異なり、一致トライは通常、無向サイクルである。これは、一致トライ内の子ノードが2つ以上の親ノードを有し得ることを意味する。無向サイクルの例は図48B〜図48Eに提供され、詳細に後述する。これとは対照的に、ストレージトライ及び結果トライ内の各子ノードは通常、1つのみの親ノードを有する。
本発明によるファジーサーチは、一致トライが、ストレージトライとの一致トライの論理積中、動的に生成される仮想トライであるそれ、特に効率的である。「遅延評価」と呼ばれることもある、ストレージトライとの一致トライの論理積に必要な仮想トライの部分のみが(動的に)生成される。このセクションにおいて別段のことが記される場合を除き、上述した仮想トライの全ての態様は、ファジーサーチの状況での仮想一致トライの使用にも当てはまる。
ファジーサーチの出力として、文字列及び/又は結果トライのノードの結果集合に関連付けられたドキュメント識別子等の他のデータ項目が提供される。通常、一致トライは一致ノードの集合を含み、各一致ノードには、近似文字列の集合からの文字列の1つに対応する1つ又は複数のキーが関連付けられる。この場合、ノードの結果集合は、一致トライ内の一致ノード(結果トライのノードに関連付けられたキーが、一致トライのノードに関連付けられたキーと同一である場合、結果トライのノードは一致トライのノードに対応する)の集合に対応する結果トライのノードの集合であり得る。これは、一致トライの一致ノードに対応する結果トライのノードに関連付けられた、ドキュメント識別子のような文字列データ項目のみが出力として提供されることを意味する。
図48A〜図48Eを参照して、サーチ文字列及び/又はサーチ文字列の変形を含む近似文字列の集合を格納する(仮想)一致トライをいかに生成することができるかについてこれより説明する。一致トライは、近似文字列の集合を表す有限オートマトンから導出される。まず、近似文字列の集合を表す非決定性有限オートマトンが構築される。非決定性オートマトンでは、2つの状態間のあらゆる遷移には通常、サーチ文字列に含まれる特定の文字、又はワイルドカード文字、又は空文字列が関連付けられる。非決定性有限オートマトンから、近似文字列の集合を表す決定性有限オートマトンも導出することができ、決定性有限オートマトンの2つの状態間の遷移には通常、サーチ文字列に含まれる特定の文字又はワイルドカード文字が関連付けられる。次に、一致トライが決定性有限オートマトンから導出される。
図48Aは、レーベンシュタインオートマトンとも呼ばれる、最大編集距離2を有するサーチ文字列「abc」に一致する非決定性有限オートマトン(NFA)を示す。当業者には既知のように、有限オートマトンは、状態と、状態間の遷移とを含む。参照番号0001で記された状態は開始状態であり、状態0006は0編集の場合の一致終了状態であり、状態0007は1編集の場合の状態であり、状態0008は2編集の場合の状態である。より大きな編集距離では、追加の状態行を上に追加する必要があり、より大きな文字列は右に追加の状態を生成する。
状態0002は、一致する最初の文字(「a」)の状態遷移である。入力として「abc」の場合、最終状態0006に達する。状態0003は、例えば、「xabc」がオートマトンに提供される場合、冒頭に挿入された文字の状態遷移である。状態遷移0004は文字置換を反映し、例えば、「ybc」をオートマトンに提供する。最後に、遷移0005は文字削除を反映し、例えば、「bc」をオートマトンに提供する。
見て分かるように、図48Aのオートマトンは非決定性である。例えば、最初の入力文字として「a」を提供すると、状態01、11、10、12、21、22、及び32が生じる。「abc」は、「a」にするために2つの文字を削除する必要があるため、状態のこの集合は一致状態(32、参照番号0008)を含む。
NFAは、例えば、いわゆる冪集合構築法を使用して決定性有限オートマトン(DFA)に変換することができる。レーベンシュタインオートマトンDFAを効率的に作成する他の方法は、Klaus Schulz及びStoyan Mihovによって提案されたものを含む。図48Bは、編集距離1で「abc」を照合して、例での状態数を低減するそのようなDFAを示す。参照番号1001で記された状態は開始状態である。参照番号1002は、特定の文字(「b」)の遷移を指す。参照番号1003は、任意の他の文字(ワイルドカード)の遷移を指す。1005と記された状態のようなグレー状態は一致状態である。
好ましい実施形態では、一致トライ及びストレージトライ内の親ノードは、ビットマップを含み、トライ内の子ノードのキー部分の値は、ビットが子ノードに関連付けられた子ノードの親ノードに含まれるビットマップ内の(設定)ビットの値によって決まる。そのようなトライデータ構造は、上記例において説明されている。一致トライの子ノードとストレージトライの子ノードとの論理積は、論理積演算を使用して各子ノードのビットマップを結合することによって達成することができるため、特に効率的な論理積演算が可能になる。
そのようなデータ構造を有する一致トライは、特定の文字又は遷移に関連付けられたワイルドカード文字の符号化により有限オートマトンの状態間の遷移を関連付けることにより、拡張有限オートマトンを得ることによって(決定性)有限オートマトンから導出することができ、符号化は、長さ及び/又はフォーマットが一致トライの親ノードに含まれるビットマップに等しい1つ又は複数のビットマップからなり、又はビットマップを表す。特定の文字の符号化の場合、符号化に含まれるか、又は符号化によって表されるビットマップのそれぞれにおいて、厳密に1ビットが設定される。ワイルドカード文字の符号化の場合、全ての有効文字符号化のビットが、符号化に含まれるか、又は符号化によって表されるビットマップにおいて設定され、それにより、全ての有効文字符号化(又は遷移元の状態に関連付けられた特定の文字の符号化を除く全ての有効文字符号化のビット)を「マスキング」する。換言すれば、ワイルドカードの符号化は、全ての有効文字符号化(又は遷移元の状態に関連付けられた特定の文字の符号化を除く全ての有効文字符号化)のビットマップのOR結合である。
図48Cは、図48BのDFAの遷移のそのような拡張を示し、図21を参照に上述したユニコード文字及びユニコード文字の文字列の符号化方式が使用される。読みやすさのために、10ビットユニコード文字符号化のみが使用される。これらの符号化は、それぞれ64ビットの2つのビットマップを使用する。上述したように、これらのビットマップのそれぞれにおいて厳密に1ビットが設定されるため、それぞれ6ビット(26=64)を符号化することが可能である。
符号化2001は、2つの6ビット値1(「000001」)及び33(「10001」)として符号化される「a」を表し、ビット位置当たりの符号化は、
である。
0000=0、0001=1、0010=2、0011=3、…、1111=Fである十六進数表現では、これは0x0000000000000002及び0x0000000200000000に対応する。
符号化2003は、2つの6ビット値1(「000001」)及び34(「10010」)として符号化された「b」を表し、ビット位置当たりの符号化は、
十六進数表現では、これは0x0000000000000002及び0x0000000400000000に対応する。
ワイルドカードの場合、許された全ての文字−この場合、完全なユニコード英字−の符号化のビットは設定される。例えば、符号化2002は、全ての10ビット符号化ユニコード文字、すなわち、6ビット値「000000」…「001111」及び「000000」…「111111」を表すように設定されたビットを有し、ビット位置当たりの符号化は、
である。
十六進数表現では、これは0x000000000000FFFF及び0xFFFFFFFFFFFFFFFFに対応する。
符号化2004及び2005は同じ文字「b」を示し、一方は非最終の場合であり、一方は一致状態、すなわち、「b」が入力文字列の最後の文字である場合のものである。符号化2006及び2007は、ワイルドカード文字のアナログの場合を示す。2008及び2009は、文字「c」及びワイルドカードの最終一致状態の場合を示す。
非一致状態に繋がる全てのユニコード文字の完全なワイルドカードマスク(図21を参照して先に説明したように、10ビット、15ビット、及び21ビット符号化)は:
である。
一致状態に繋がる全てのユニコード文字の完全なワイルドカードマスクは:
である。
図48Dは、2つのキー部分によって表される各10ビットユニコード文字を有する、結果として生成された一致トライの上部を示す。トライへのブールAND演算子はまず、ビットマップを必要とし、後に一致する子に降下するため、特定の文字は1ビットとして符号化され、ワイルドカードは、全ての有効文字符号化で設定されたビットを有するビットマップとして符号化される。
そのような一致トライは、上述した任意の有限オートマトンから、特に拡張有限オートマトンから直接導出することができる。しかしながら、一致トライ、ストレージトライ、又は結果トライに格納された文字が、各トライのM>1個のキー部分により、すなわち、2つ以上のレベルのノードによって符号化される場合、一致トライは好ましくは、近似文字列の集合を表す完全有限オートマトンから導出される。好ましくは、Mは2〜4である。
有限オートマトンの2つの状態間の遷移、好ましくはあらゆる遷移により、又は有限オートマトンの1つの状態間の遷移、好ましくはあらゆる遷移を、M−1子の中間状態を介して2つの状態をリンクするM個の遷移の1つ又は複数のシーケンスで置換又は関連付けることにより、好ましくは上述した決定性有限オートマトンから、より好ましくは拡張有限オートマトンからの完全有限オートマトン。したがって、完全な文字列に関連付けられていない状態は有限オートマトンに追加される。
例えば、図48B及び図48Cの有限オートマトンでは、状態0に発端し、状態1で終わる遷移がある。完全有限オートマトンでは、図48Dから明らかになるように、この遷移は、中間状態110と、状態1と状態110との間の遷移及び状態110と状態1との間の別の遷移を含む一連の遷移とで置換される。別の例として、図48B及び図48Cの有限オートマトンでは、状態0に発端し、状態10で終わる遷移がある。完全有限オートマトンでは、この遷移は、中間状態110と、状態1と状態110との間の遷移及び状態110と状態10との間の別の遷移を含む一連の遷移とによって置換される。第3の例として、図48B及び図48Cの有限オートマトンでは、状態0に発端し、状態14で終わる遷移がある。完全有限オートマトンでは、この遷移は、中間状態110及び111と、2つの遷移シーケンスとによって置換される。第1の遷移シーケンスは、状態1と状態110との間の遷移及び状態110と状態14との間の別の遷移を含む。第2の遷移シーケンスは、状態1と状態111との間の遷移及び状態111と状態14との間の別の遷移を含む。
シーケンス内のM個の遷移のそれぞれには、長さ及び/又はフォーマットが一致トライの親ノードに含まれるビットマップに等しいビットマップからなるか、又はビットマップを表す中間符号化が関連付けられ、一致トライは完全有限オートマトンから導出される。符号化は、全体文字の符号化の一部のみ、図48Dの一致トライを導出することができる完全有限オートマトンの例では、全体文字の符号化の半分を表すため、本明細書では「中間」と呼ばれる。
例えば、図48Dの一致トライを導出することができる完全有限オートマトンでは、状態0と状態110との間の遷移には、以下のビットマップからなるか、又は以下のビットマップを表す符号化が関連付けられる。
十六進数表現では、これは0x0000000000000002に対応する。状態0と状態110との間の遷移とのこの符号化の関連付けは、符号化2001その遷移間の上部破線矢印で示される。この矢印が指す「1」は、図48Dの一致トライの親ノード0に含まれるビットマップ内のビット番号1(2番目のビット)を表す。
別の例として、図48Dの一致トライを導出することができる完全有限オートマトンでは、状態0と状態111との間の遷移には、以下のビットマップからなるか、又は以下のビットマップを表す符号化が関連付けられる。
十六進数表現では、これは0x000000000000FFFFに対応する。状態0と状態111との間の遷移とのこの符号化の関連付けは、符号化2002その遷移間の上部破線矢印で示される。この矢印が指す「0,2,…,63」は、図48Dの一致トライの親ノード0に含まれるビットマップ内のビット番号0、2、…、63(1番目、3番目、…、64番目のビット)を表す。
有限オートマトンの2つの状態間の遷移に特定の文字が関連付けられる場合、シーケンスのM個の遷移に関連付けられた中間符号化に含まれるか、又は表されるビットマップを連結したものは、特定の文字の符号化であり、各ビットマップにおいて厳密に1ビットが設定される。
図48B及び図48Cの有限オートマトンの例では、状態0と状態1との間の遷移には文字「a」が関連付けられる。したがって、図48Dの一致トライを導出することができる完全有限オートマトンでは、状態0と状態1との間の(状態110を介した)2つの遷移に関連付けられた中間符号化に含まれるか、又は表されるビットマップを連結したものは、文字「a」の符号化であり、各ビットマップにおいて厳密に1ビットが設定される。この符号化は以下である。
十六進数表現では、これは0x0000000000000002及び0x0000000200000000に対応する。
有限オートマトンの2つの状態間の遷移にワイルドカード文字が関連付けられる場合、シーケンスのM個の遷移に関連付けられた中間符号化に含まれるか、又は表されるビットマップを連結したものは、符号化に含まれるか、若しくは表されるビットマップにおいて全ての有効文字符号化のビットが設定されるか、又は遷移元の状態に関連付けられた特定の文字の符号化を除く全ての有効文字符号化のビット 符号化を含む。
図48B及び図48Cの有限オートマトンの例では、状態0と状態14との間の遷移にはワイルドカード文字が関連付けられる。したがって、図48Dの一致トライを導出することができる完全有限オートマトンでは、状態0と状態14との間の(状態111を介した)2つの遷移に関連付けられた中間符号化のシーケンスの1つに含まれるか、又は表されるビットマップを連結したものは、ワイルドカード文字の符号化である。この符号化は以下である:
十六進数表現では、これは0x000000000000FFFF及び0xFFFFFFFFFFFFFFFFに対応する。
更に、有限オートマトンの2つの状態間の遷移にワイルドカード文字が関連付けられる場合、シーケンスのM個の遷移に関連付けられた中間符号化に含まれるか、又は表されるビットマップを連結したものは通常、特定の文字の符号化の1つ又は複数の部分と、符号化に含まれるか、若しくは表されるビットマップにおいて全ての有効文字符号化のビットが設定されるか、又は遷移元の状態に関連付けられた特定の文字の符号化を除く全ての有効文字符号化のビット符号化の1つ又は複数の部分とを含む1つ又は複数の符号化を含む。
例えば、図48Dの一致トライを導出することができる完全有限オートマトンでは、状態0と状態14との間の(状態110を介した)2つの遷移に関連付けられた中間符号化のシーケンスの1つに含まれるか、又は表されるビットマップを連結したものは、文字「a」の符号化の第1の部分(これは、文字「b」の符号化の第1の部分でもある)と、ワイルドカード文字の符号化の第2の部分とを含む符号化である。この符号化は以下である:
十六進数表現では、これは0x0000000000000002及び0xFFFFFFFFFFFFFFFFに対応する。
拡張有限オートマトン又は完全有限オートマトンはそれぞれ、各行が拡張有限オートマトン又は完全有限オートマトンの1つの状態を表す幾つかの行と、それぞれが遷移に関連付けられた符号化及び遷移が終わる状態への参照を含む、状態を発端とする各遷移のタプルとを含むデータ構造により表し、又は格納することができる。図48Eは、特に効率的に図48Dの一致トライを導出することができる完全有限オートマトンの状態を表すのに使用することができる、1つ又は複数の配列としてそのようなデータ構造を示す。そのようなデータ構造は、好ましくは状態への各参照におけるビットとして符号化される、遷移が終わる各状態について、この状態が一致状態であるか否かについての情報を含むことができる。データ構造は通常、遷移元の拡張有限オートマトン又は完全有限オートマトンのそれぞれの各状態に行を含む。
この(仮想)一致トライ手法に伴う恩恵は、複雑な状態マシン等を使用する必要がないため、効率的な実行に繋がる実装の簡易性に起因するとともに、好ましい実施形態においてAND演算子がビットマップに対して機能する方法にも起因した良好な性能である。
インデックス手法及び性能測定
本発明の様々な実施形態による範囲クエリの性能を測定するために、実験を行い、その結果について図53〜図70を参照して以下に考察する。一例として、空間クエリを用いるジオロケーション用途を使用した。サンプルデータは、欧州領域のOpenStreetMapデータから導出し、これはhttp://download.geofabrik.de/europe.htmlから取得することができる。一例のデータベース内の各エントリは、10桁のID、各経度及び緯度の少数点以下7桁を有する値、並びに通りの名称及び家屋番号を表す文字列を含んだ。
第1の実験は、インデックスサイズ(索引付けられるレコードの量)が一定結果サイズのクエリ処理性能にいかに影響するかを調べるために行った。データベースに問い合わせて、ミュンヘン地域内の小さな矩形(図49に示されるように、経度11.581981+/−0.01及び緯度48.135125+/−0.01)内の全てのロケーションのIDを返した。データベースは合計で約2850万のレコードを含み、そのうち3,143個が一致した。
第1の測定シリーズでは、一致レコードがまずデータベースにロードされ、次に、約2850万個の他のレコードがデータベースに追加された。これらの他のレコードを図50において陰影付きエリアとして示す。100,000個のレコードが追加される都度、追加後、クエリを行い、その実行時間を測定した。明らかに、あらゆるクエリは3,143の一致を返した。
第2の測定シリーズでも、まず矩形内の一致レコードをデータベースにロードするが、残りのレコードは、一致する経度又は緯度の「帯」内のレコードなしでロードした。第2の測定シリーズでロードした残りのレコードを図51に示す。
第1の実験を索引付け及びジオロケーションクエリの5つの異なる手法で実行した。
本明細書では「従来技術による索引付け」と呼ばれる従来技術による手法では、経度及び緯度を含む空間索引付けをサポートするApache Lucene 6.0.1データベースエンジンのSpatialPrefixTreeを使用した(https://lucene.apache.org, package org.apache.lucene.spatial.prefix.tree)。SpatialPrefixTreeはトライではなく、空間クエリに最適化された逆インデックスの作成に使用された。したがって、ここでとられる手法の良好なベンチマークを提供した。
指定された矩形内の全てのロケーションを問い合わせるために、範囲クエリを両次元で実行した。クエリはそれぞれ、カーソルベースの反復子によって収集されて暫定結果集合を作成した、指定された経度帯又は緯度帯に配置されたレコードを表すIDの集合を返した。暫定結果集合を論理積演算して、最終結果集合を取得した。これを図52に示し、図52では、陰影付きエリアは指定された経度及び緯度の帯(暫定結果集合)を記し、黒色エリアは指定された矩形(最終結果集合)を記す。SpatialPrefixTreeはトライではなく、空間クエリに最適化された逆インデックスの作成に使用される。クエリ性能は、図58〜図60を参照して以下に説明するトライの可変精度索引付けと同様に、解像度の幾つかのレベルで幾つかのインデックスを作成することにより改善した。
図53は、従来技術による手法の測定結果を示す。x軸はデータベースにロードされたレコード数を示し、y軸は、対数尺度での毎秒当たり実行されたクエリ数を示す。一致した帯をデータベースにロードした場合及びしない場合で、クエリ性能は、データベース内のレコード数の増大に伴って低下することを観察することができる。この性能挙動は、アクセス時間がインデックスの充填レベルに依存する従来技術によるデータベースに典型的である。
上述したトライの好ましい実施形態を使用してジオロケーションを索引付け問い合わせる第1の手法を行い、これを本明細書では「標準索引付け」と呼ぶ。経度に1つのインデックスが好ましい実施形態の第1の二次元トライによって作成され、緯度に別のインデックスが好ましい実施形態の第2の二次元トライによって作成された。換言すれば、各二次元インデックストライは2つの項目、すなわち、(経度,ID)又は(緯度,ID)をそれぞれ格納した。二次元インデックストライは、図44のトライにおいて先に示したように、非インタリーブ様式で格納され、経度/緯度が第1のキー部を形成し、IDが第2のキー部を形成した。抽象的な視点から、これにより、全ての経度/緯度を含むトライが生成され、各リーフノードは、図54に示すように、各経度/緯度を有する全てのロケーションのIDを含むトライのルートである。
第1のキー部(経度/緯度)にわたる範囲クエリは、一致した経度/緯度を有するロケーションのIDのトライルートを返した。トライインターフェースを用いてこれらの結果を届けるために、図55に示すように、トライインターフェースを提供するマルチOR演算子を使用してトライルートのリストを結合した。したがって、図56に示すように、本発明による標準索引付けは2つのインデックストライ5601、5603を使用し、各インデックストライは2つのキー部(経度,ID)又は(緯度,ID)を有した。トライの第1のキー部について、仮想経度/緯度トライ5602、5604を使用して範囲クエリを実行した。マルチOR演算子5605、5606を使用して各範囲クエリの結果を結合した。AND演算子5607を使用して2つのマルチOR演算子の結果を結合し、最終結果を届けた。
図57は、標準索引付けの測定結果を示す。一致レコードをデータベースにロードしない場合、クエリ処理時間は一定であり、これは、トライが一定のアクセス時間を有する、すなわち、充填レベルから独立することによることを観察することができる。クエリ処理時間はまた、従来技術による手法を使用した場合の約1/10であり、LuceneデータベースエンジンのSpatialPrefixTreeが空間クエリに最適化されることを考慮して、これは注目に値する。
一致レコードをデータベースにロードする場合、標準索引付けのクエリ性能は低下し、これは、独立した経度クエリ及び緯度クエリのますます多くの結果を結合する必要があったためである。一致レコードを用いての標準索引付けの性能は、ノード(ID)の長いリストが生じるため、あまりよくない。性能を改善するために、OR演算によって結合する必要があるノードの量を低減する必要がある。
本明細書において「可変精度索引付け」と呼ばれる手法では、OR演算する必要があるノードの量は、可変精度を有する複数のインデックスを維持し、階層を作成することによって劇的に低減することができる。これは、上述した従来技術によるデータベースエンジンにおいて幾つかの解像度レベルの幾つかのインデックスを作成することの概念と同等である。例えば、2桁十進数を格納するトライにおいて範囲を使用することにより、プレフィックスを表す各レベルにインデックスを有することができる。
−0, 1, 2, ... 9
−00, 01, 02, ..., 09, 10, ... 99
例として、第1レベルのX値(最初のキー部)のインデックスを図58に示し、X値の第2レベルのインデックスを図59に示し、2番目のキー部(Y項目)はIDであることができる。図58に示される第1レベルのインデックス内のエントリ(最初のキー部又はX項目のリーフ)は、各プレフィックス範囲内のX値の全てのID(2番目のキー部のトライ)を含む。10〜53のX値のクエリは、図58のインデックスへの範囲1、…、4のクエリの結果(破線矩形で記された2つのヒット)と、図59のインデックスへの範囲50、…、53のクエリの結果(破線矩形で記された1つのヒット)とを結合する。これにより、図59のインデックストライのみを使用する場合の5つのノードの代わりに、続くマルチOR演算で結合する必要があるノードは3つのみである。
本発明者が行った実際の実験は、各精度ステップに6ビットを使用した。精度長はキーの最初のバイトに格納された。トライは11のレベルを有し、トライ内のノードは、ルートレベルで最高で16個の子ノードを有し、10の後続レベル(リーフノードを含む)で最高で64個の子ノードを有した。これは、ルートレベルにおいて最大で16−2個のノード及びトライの左右の部分での次のレベルで2*(64−1)個のノードをOR演算する必要があったことを意味する。これにより、OR演算する必要がある上限は16−2+2*(64−1)*10=1274個のトライになる。範囲クエリを受けるあらゆるキー値は、11個の精度レベルで格納した。上述した仮想範囲トライに基づく範囲クエリを使用して、クエリを実行した。必要とされるノードを選択するのに必要な全てのキーのリストを作成した。
図60は、可変精度索引付けの測定結果を示す。一致帯がロードされない場合、クエリ実行は非常に高速(標準索引付けを使用する場合よりも約10倍高速)であり、一定時間を有する。一致レコードがデータベースにロードされる場合であっても、クエリ性能は略一定である。しかしながら、以下に示すように、可変精度索引付けは、メモリ需要及び索引付け性能に関して高価である。
本明細書では「二次元索引付け」と呼ばれるジオロケーションを索引付け問い合わせる別の手法は、標準索引付けよりも高速であるが、可変精度索引付けの欠点がない解決策あることを示した。図61に示すこの手法では、データベースエントリの経度/緯度及びIDは、例えば、図32及び図46を参照して上述した構造を有するインタリーブトライに格納された。標準索引付けと同様に、経度及び緯度は、2つの異なるトライであるトライ6110(経度,ID)及びトライ6120(緯度,ID)で別個に索引付けられた。
矩形を問い合わせるために、経度範囲を指定する仮想範囲トライ6130及び緯度範囲を指定する仮想範囲トライ6140を作成した。経度インデックスが経度範囲トライと論理積演算され、同時に、緯度インデックスが緯度範囲トライと論理積演算される場合、論理積の中間結果は、以下に説明するように結合された。
最初のステップにおいて、図61において矢印6151で示されるように、ビット単位AND演算を経度インデックストライ6110のルートノード6111のビットマップと、経度範囲トライ6130のルートノードとの間で実行する。同様に、図61において矢印6152で示されるように、ビット単位AND演算を緯度インデックストライ6120のルートノード6121のビットマップと、緯度範囲トライ6130のルートノードとの間で実行する。
図61におけるノード6112及び6122は、インデックストライ6110及び6120のレベル2におけるノードを表す。レベル2におけるこれらのノードのそれぞれは、インデックス内のIDキー部のルートノードである。したがって、経度インデックストライ6110のルートノード6111のビットマップと、経度範囲トライ6130のルートノードとの間のビット単位AND演算は、指定された経度範囲を有するロケーションに属するIDの第1のキー部分を生成し、緯度インデックストライ6120のルートノード6121のビットマップと、緯度範囲トライ6140のルートノードとの間ビット単位AND演算は、指定された緯度範囲を有するロケーションに属するIDの第1のキー部分を生成する。
2番目のステップにおいて、指定された経度範囲及び緯度範囲の両方に入るロケーションに属さないインデックストライ内のキーは以下のようにフィルタリングされて除外される:最初のステップによって生成された経度/緯度インデックストライ6110/6120のノードのビットマップは、ビット単位OR演算によって結合され、図61において矢印6153で示されるように、ビット単位OR演算の結果間でビット単位AND演算を実行する。
図61におけるノード6113及び6123は、インデックストライ6110及び6120のレベル3におけるノードを表す。レベル3におけるこれらの各ノードは、インデックストライに格納された経度/緯度キー部の第2のキー部分を格納する。3番目のステップにおける演算は、2番目のステップにおいてフィルタリングされて除外されなかったキーに属するレベル3におけるノードを用いて続く。ビット単位AND演算が、図61において矢印6154、6155で示されるように、これらのノードのビットマップと、各範囲トライ6130、6140の対応するノード(レベル2における)との間で実行される。
図61におけるノード6114及び6124は、インデックストライ6110及び6120のレベル4におけるノードを表す。レベル4におけるこれらの各ノードは、インデックストライに格納されたIDキー部の第2のキー部分を格納する。4番目のステップにおける演算は、3番目のステップにおけるビット単位AND演算の結果として生成されたレベル4におけるノードを用いて続く。2番目のステップと同様に、同じ親ノードを有する最初のステップにより生成された経度/緯度インデックストライ6110/6120のノードのビットマップは、ビット単位OR演算によって結合され、図61において矢印6156で示されるように、ビット単位AND演算が、ビット単位OR演算の対応する結果間で実行される。
演算は、インデックストライのリーフノードに達するまで、同じように続けられた。まとめると、一次元(x)のみを有するインデックスが交互になった「ビュー」を返すマッチャーを使用して2つのインデックスを結合した。第2の次元は、マッチャーの出力において抑制された。
図62は、二次元索引付けの測定結果を示す。ここでも、一致帯がデータベースにロードされない場合、クエリ時間は一定であった。一致帯がデータベースにロードされる場合、クエリ性能は標準索引付けと比較して有意に改善した。
次元を照合し抑制する戦略は原理上、3つ以上の次元に適用することができる。しかしながら、これは、ノードの大きな連鎖を生じさせる:x次元の各ノードはy次元の64個の子を有し得、y次元の64個の子はここでも、64個の子を有し得、合計で既に4096個の子を有し得る
本明細書では「シングルインデックス索引付け」と呼ばれるジオロケーションを索引付け問い合わせる最後の手法では、1つのみの多次元インデックスが作成され、多次元インデックスは、例えば、図32及び図46を参照して上述したように、経度及び緯度の両方を1つのインタリーブトライに格納する。このインデックストライの概略を図63に示す。図63では、経度及び緯度を表す第1及び第2のキー部X及びYはインタリーブ様式で格納され、ロケーションのIDを表す第3のキー部は、X/Yトライのリーフに従属するサブトライに格納される。各サブトライに格納されたIDは、同じ経度及び緯度を有するロケーションの集合に属する。
矩形を問い合わせるために、例えば、図40を参照して上述したように次元範囲クエリを実行した。図64に示されるように、経度の範囲は、第1の一次元仮想範囲トライ6402によって指定され、緯度の範囲は、第2の一次元仮想範囲トライ6403によって指定された。両一次元範囲トライは、インタリーブ演算子6404によって結合されて、インタリーブ二次元範囲トライを形成する。一致する経度及び緯度に属するIDサブトライの集合を得るために、AND演算子6405は、二次元範囲トライとインデックストライ6401のX/Y部分との間で論理積を実行する。
図65は、シングルインデックス索引付けの測定結果を示す。シングルインデックス索引付けが完全なスケーラビリティを提供し、一致帯がロードされた場合であっても、クエリ性能がデータベース内のレコード数に著しく依存しないことを観察することができた。なお、性能における急な山は、Java仮想マシンガベージコレクションによって生じた。
図66は、結果サイズの増大に伴ってクエリ性能(毎秒当たりのクエリ数)を測定した第2の実験の結果を示す。クエリ矩形は、緯度及び経度で+/−0.01度から+/−0.20度に増大した。2850万レコードをまず、データベースにロードした。可変精度索引付けが、より大きな結果で最良にスケーリングされる(なお、メモリ制約に起因して、可変精度索引付けでは部分データのみをロードすることができた)ことを観察することができた。シングルインデックス索引付けも良好な性能を提供する。これは特に、緯度及び経度に加えて、IDもインタリーブ様式で格納される場合、当てはまる。三重インタリーブインデックス結果の性能利得が、増大した数の共通プレフィックスパスから生じると考えられ、これは、より小さなメモリフットプリント(46.01バイト/ポイント対44.76バイト/ポイント)によっても証明される。ツリー内の分岐数が少なく、ツリーをトラバースする再帰ステップ数の減少に繋がり得るため、性能はより良好であり得る。
Luceneデータベースを使用した従来技術による索引付けは、全ての結果サイズで略一定の結果を届けたが、シングルインデックス索引付けよりも低い性能レベルであった。標準索引付け(インタリーブされない2つのインデックス)及び二次元索引付け(インタリーブされた2つのインデックス)の性能は、小さな結果サイズでのLuceneデータベースを使用した従来技術による索引付けよりも良好であったが、大きな結果サイズでは性能が低下した。図67は、図66と同じであるが、x軸に対数尺度を有する結果を示す。この表現では、本発明によるインデックスのクエリ性能が、結果サイズが増大する場合、直線で低下することが分かる。これは、特に2つのシングルインデックス手法が線形スケーラビリティを有し、すなわち、結果サイズが2倍になると、クエリ時間も2倍になることを意味する。
第3の実験では、索引付け性能(毎秒当たり索引付けされるエントリ数)を測定した。2850万個のレコードをロードし、100,000個の追加レコード毎に時間を測定した。従来技術によるインデックス及び全てのトライベースの手法は、インデックスの増大に伴って実際に一定の性能を提供することを観察することができる。結果を図68にまとめる。上述したように、可変精度索引付けの性能は、2x11個のインデックスエントリをレコード毎に作成する必要があるであるため、あまりよくない。可変精度索引付けと同様の手法である従来技術によるインデックス(Lucene)の性能は更に悪かった。トライベースの標準索引付け及び二次元索引付けは両方ともレコード毎に2つのインデックスエントリを作成し、したがって、同様の索引付け性能を有する。シングルインデックス索引付けは、レコード毎に1つのみのインデックスを作成し、性能が最良である。なお、トライベースの手法では、黒色列は非圧縮トライの結果を表し、明るい列はビットマップ圧縮を使用したトライの結果を表す。
図69は、索引付けられたロケーション当たりの異なるインデックスによって必要とされるメモリ空間を比較する。従来技術によるLuceneインデックスは、ビットマップ圧縮を用いた(明るい列)トライベースの標準索引付け及び二次元索引付けよりも多くの空間を使用し、ビットマップ圧縮を用いない場合であっても、シングルインデックス索引付けよりも多くの空間を使用した。トライベースの可変精度索引付けは、任意の他の手法よりもはるかに多くの空間を必要とした。
標準索引付けが、低又は中基数を有する属性で十分に良好に機能すると結論付けることができる。例えば、製品価格は通常、連続値を有さず、3.99、4.49、4.89等の離散値を有する。ミリ秒精度を有するタイムスタンプとして注文日のような何かを格納する代わりに、値空間を「より」離散させるという要件を満たすために、日精度又は時間精度で格納することで十分であり得る。連続値空間を用いて列を索引付けるために、可変精度索引付けは、特に多次元クエリで使用される場合、より良好な性能を提供する。しかしながら、遅い索引付け及び高いメモリ需要に起因して、可変精度索引付けの使用は、静的用途且つ十分なメモリが利用可能な場合でのみ推奨することができる。密に結びついた次元の場合、シングルインデックス索引付けが、予期される結果サイズが中程度である場合、最良の解決策である。
多次元インデックスは、空間クエリの状況で本明細書に提示されたが、トライベースの範囲クエリは、多くの他の状況、例えば、グラフデータベースに適用することもできる。プロパティグラフデータベースは、エッジで結ばれたノードに基づき、ノード及びエッジは両方ともプロパティを有する。ノード及びエッジがそれぞれ一意のIDで表される場合、ノード−エッジ−ノードの三つ組みを表し、これらの3つのIDを次元として使用して問い合わせることができる。なお、同じことは、リソース記述フレームワーク(RDF)用語で三つ組みと呼ばれる主語−述語−目的語表現を用いるRDFの状況にも当てはまる。
上述したように、本発明は、生じた各言葉及びドキュメントIDを2つのキー部(文字列,長)として格納することにより、フルテキストサーチ用途にも容易に使用することができる。本発明はプレフィックスツリーに基づくため、プレフィックスツリーの文字列サーチ機能を受け継ぐ。例えば、ファジー(類似性)サーチの効率的な実施に使用することができる。
実際に、本発明者により実行された測定は、情報検索用途での競争力のある性能を示す。本願の優先日の少し前に実行された実験では、500,000の英語Wikipedia記事を索引付けた。図70Aは、文字数/秒単位でのLucene情報検索ソフトウェアライブラリと比較した本発明の実施形態の平均索引付け性能を示す。本発明のシステムが、長整数の配列が使用された場合(黒色列)のみ、わずかに低い索引付け性能を届けたことが分かる。予期されたように、バイトの配列を用いたビットマップ圧縮が使用された場合(明るい列)、索引付け性能はいくらか低かった。
図70Bはインデックスサイズ(%単位でのインデックスサイズ/テキストサイズ)を比較する。驚くことに、長整数の配列に基づくメモリモデル(黒色列)であってもLuceneと同等であった−位置合わせ損失があったが。バイトの配列を用いたビットマップ圧縮に基づくメモリモデル(明るい列)は、Luceneよりも必要とする空間が少なかった。
図70Cはクエリ性能(クエリ数/秒)を示す。この実験での用語クエリは、「from」と組み合わせて単語「which」又は「his」を含む全てのドキュメントをサーチして、いくらかの複雑性及び量を提供した。複数の同時スレッドを用いて、本発明のシステムの性能は、Luceneよりも最高で7倍高い。
この実験でのファジークエリは、「chica」と同様の単語を含むドキュメントをサーチした。類似性は、編集距離1(レーベンシュタイン距離)により、すなわち、最大で1文字の削除、挿入、及び置換を用いて定義される。この規律では、本発明のシステムは、Luceneよりも4倍〜6倍高速であることが証明された。Lucene及び本発明のシステムの両方が厳密に同量の結果ドキュメントを届けたことに留意することに価値がある:用語クエリでは319,809、ファジークエリでは30,994。
上述した実験を本願の出願日の少し前、すなわち、約1年後に繰り返した。繰り返した実験の結果は図70D〜図70Fに見ることができる。
図70Dにおいて見て取ることができるように、索引付け性能はここで、先の実験よりも低かった。本発明のシステムでは、メモリ管理がここで、いくらかの性能を犠牲にして完全に実施されたため、低かった。Luceneシステムでは、Lucene索引付けが1スレッド/CPUコアのみで実行されたため、低かった。これは、本発明によるシステムも1スレッド/CPUコアのみを用いて実施されたため、よりよい比較性を得るために行われた。なお、本発明のシステムによる索引付けは、並列化することもできるが、これは本発明者によってまだ実施されていない。
図70Eは、インデックスサイズが先の実験と比較して実際に同じままであることを示す。
図70Fは、本発明のシステムのクエリ性能が、特にファジーサーチにおいて先の実験と比較して改善したことを示す。先の実験では、図48Cに示すように、完全文字列に関連付けられた状態に対応するノードのみを含むDFAのみが前もって生成された。図48Dに示される中間状態(完全文字列に関連付けられていない有限オートマトンの状態)は、文字の符号化が2つ以上のキー部分を必要とすることに起因して存在し、論理積演算中、オンザフライで動的に特定された。これとは対照的に、後の実験では、状態及び遷移の完全な集合を有する有限オートマトンが前もって生成され、図48Eに示されるように、複数の配列(マトリックス)の配列として格納された。この手法は、約2倍のクエリ性能の改善2もたらした。Luceneシステムは、先の実験と比較して同様の倍数で改善し、この改善は、本願の優先日と出願日との間にLuceneシステムで行われた特定の最適化に起因する。