IP Force 特許公報掲載プロジェクト 2022.1.31 β版

知財求人 - 知財ポータルサイト「IP Force」

▶ 三水 明男の特許一覧

(19)【発行国】日本国特許庁(JP)
(12)【公報種別】特許公報(B1)
(11)【特許番号】
(24)【登録日】2024-07-24
(45)【発行日】2024-08-01
(54)【発明の名称】検索装置、検索方法、及びプログラム
(51)【国際特許分類】
   G06F 16/901 20190101AFI20240725BHJP
【FI】
G06F16/901
【請求項の数】 17
(21)【出願番号】P 2024040635
(22)【出願日】2024-03-15
【審査請求日】2024-03-15
【早期審査対象出願】
(73)【特許権者】
【識別番号】521416409
【氏名又は名称】三水 明男
(74)【代理人】
【識別番号】100103894
【弁理士】
【氏名又は名称】家入 健
(72)【発明者】
【氏名】三水 明男
【審査官】松尾 真人
(56)【参考文献】
【文献】特開平03-122766(JP,A)
【文献】特開昭62-095628(JP,A)
【文献】特開昭62-154134(JP,A)
【文献】特開平05-173759(JP,A)
【文献】米国特許出願公開第2021/0132902(US,A1)
(58)【調査した分野】(Int.Cl.,DB名)
G06F 16/00-16/958
(57)【特許請求の範囲】
【請求項1】
可変長の登録文字列と、複数のノードから構成されるデータツリーとを格納する格納部であって、前記ノードは、前記登録文字列を指し示す直列文字列情報と、当該ノードの下位の遷移先に関するブランチ情報とを含む、格納部と、
前記ノードの前記直列文字列情報及び前記ブランチ情報に基づいて、検索文字列を含む前記登録文字列を検索する検索部と、
を備え、
前記ブランチ情報は、前記直列文字列情報が指し示す登録文字列に続く複数のブランチ文字と、前記複数のブランチ文字のそれぞれに対応する遷移先情報と、を含み、
前記ノードは、前記登録文字列及び前記検索文字列における前記ブランチ文字の位置を示すブランチ位置を含み、
前記直列文字列情報は、前記遷移先情報が指し示す複数の登録文字列に共通する文字列と終端同士が一致する前記登録文字列が存在する場合、前記登録文字列を単独で指し示し
前記直列文字列情報は、前記遷移先情報が指し示す複数の登録文字列に共通する文字列と終端同士が一致する前記登録文字列が存在しない場合、当該ノードの前記遷移先情報指し示す遷移先の前記登録文字列を、前記遷移先情報と共に指し示し
前記検索部は、前記ノードに含まれる前記直列文字列情報が指し示す登録文字列と前記検索文字列との比較範囲を、前記ノードに含まれる前記ブランチ位置と前記データツリーにおける前記ノードの直前のノードに含まれる前記ブランチ位置との差に基づいて動的に決定する、
検索装置。
【請求項2】
前記ノードは、前記直列文字列情報が前記登録文字列を単独で指し示すか否かを示すフラグを含む、
請求項1に記載の検索装置。
【請求項3】
前記検索部は、前記ノードに含まれる前記直列文字列情報が指し示す登録文字列及び前記検索文字列の比較結果と、前記ノードに含まれる前記フラグとに基づいて、前記検索を行う、
請求項2に記載の検索装置。
【請求項4】
前記検索部は、前記ノードに含まれる前記直列文字列情報が指し示す登録文字列と前記検索文字列とを、並列処理可能なデータ単位で比較する、
請求項1乃至3のいずれか一項に記載の検索装置。
【請求項5】
前記検索部は、前記ノードに含まれる前記直列文字列情報が指し示す登録文字列と前記検索文字列とを、SIMD(Single Instruction/Multiple Data)命令により比較する、
請求項4に記載の検索装置。
【請求項6】
前記遷移先情報は、前記複数のブランチ文字の後に連続して格納される、
請求項1乃至3のいずれか一項に記載の検索装置。
【請求項7】
前記検索部は、前記ノードに含まれる前記複数のブランチ文字と前記検索文字列における前記ブランチ位置に対応する文字とを、並列処理可能なデータ単位で比較する、
請求項1乃至3のいずれか一項に記載の検索装置。
【請求項8】
前記検索部は、前記ノードに含まれる前記複数のブランチ文字と前記検索文字列における前記ブランチ位置に対応する文字とを、SIMD命令により比較する、
請求項に記載の検索装置。
【請求項9】
新たに登録する前記登録文字列に基づいて前記ノードを割り当て、前記割り当てたノードに前記直列文字列情報及び前記ブランチ情報を設定する登録部を備える、
請求項1乃至3のいずれか一項に記載の検索装置。
【請求項10】
前記登録部は、前記データツリーを構成している前記ノードに含まれる前記直列文字列情報が指し示す登録文字列と前記新たに登録する登録文字列とを、並列処理可能なデータ単位で比較前記比較した結果に基づいて、前記割り当てたノードに前記直列文字列情報及び前記ブランチ情報を設定する、
請求項に記載の検索装置。
【請求項11】
前記登録部は、前記データツリーを構成している前記ノードに含まれる前記直列文字列情報が指し示す登録文字列と前記新たに登録する登録文字列とを、SIMD命令により比較前記比較した結果に基づいて、前記割り当てたノードに前記直列文字列情報及び前記ブランチ情報を設定する、
請求項10に記載の検索装置。
【請求項12】
前記登録文字列は、数値データを含み、
前記登録部は、前記数値データに含まれる符号あり固定小数点数値の先頭ビットを反転して、符号なし固定小数点数値に変換し、前記変換後の数値を前記格納部に格納する、
請求項に記載の検索装置。
【請求項13】
前記登録文字列は、数値データを含み、
前記登録部は、前記数値データに含まれる浮動小数点数値の符号ビットが0の場合は前記符号ビットを反転して、前記反転後の数値を前記格納部に格納し、前記浮動小数点数値の符号ビットが1の場合は全ビットを反転して、前記反転後の数値を前記格納部に格納する、
請求項に記載の検索装置。
【請求項14】
前記登録文字列は、可変長の文字列と前記数値データを組み合わせた複合キーである、
請求項12に記載の検索装置。
【請求項15】
前記登録部は、前記登録文字列に含まれるリトルエンディアン形式のデータをビックエンディアン形式のデータに変換し、前記変換後のデータを前記格納部に格納する、
請求項に記載の検索装置。
【請求項16】
検索装置により実行される検索方法であって、
可変長の登録文字列と、複数のノードから構成されるデータツリーとを格納し、前記ノードは、前記登録文字列を指し示す直列文字列情報と、当該ノードの下位の遷移先に関するブランチ情報とを含み、
前記ノードの前記直列文字列情報及び前記ブランチ情報に基づいて、検索文字列を含む前記登録文字列を検索し、
前記ブランチ情報は、前記直列文字列情報が指し示す登録文字列に続く複数のブランチ文字と、前記複数のブランチ文字のそれぞれに対応する遷移先情報と、を含み、
前記ノードは、前記登録文字列及び前記検索文字列における前記ブランチ文字の位置を示すブランチ位置を含み、
前記直列文字列情報は、前記遷移先情報が指し示す複数の登録文字列に共通する文字列と終端同士が一致する前記登録文字列が存在する場合、前記登録文字列を単独で指し示し
前記直列文字列情報は、前記遷移先情報が指し示す複数の登録文字列に共通する文字列と終端同士が一致する前記登録文字列が存在しない場合、当該ノードの前記遷移先情報指し示す遷移先の前記登録文字列を、前記遷移先情報と共に指し示し
前記検索では、前記ノードに含まれる前記直列文字列情報が指し示す登録文字列と前記検索文字列との比較範囲を、前記ノードに含まれる前記ブランチ位置と前記データツリーにおける前記ノードの直前のノードに含まれる前記ブランチ位置との差に基づいて動的に決定する、
検索方法。
【請求項17】
可変長の登録文字列と、複数のノードから構成されるデータツリーとを格納し、前記ノードは、前記登録文字列を指し示す直列文字列情報と、当該ノードの下位の遷移先に関するブランチ情報とを含み、
前記ノードの前記直列文字列情報及び前記ブランチ情報に基づいて、検索文字列を含む前記登録文字列を検索し、
前記ブランチ情報は、前記直列文字列情報が指し示す登録文字列に続く複数のブランチ文字と、前記複数のブランチ文字のそれぞれに対応する遷移先情報と、を含み、
前記ノードは、前記登録文字列及び前記検索文字列における前記ブランチ文字の位置を示すブランチ位置を含み、
前記直列文字列情報は、前記遷移先情報が指し示す複数の登録文字列に共通する文字列と終端同士が一致する前記登録文字列が存在する場合、前記登録文字列を単独で指し示し
前記直列文字列情報は、前記遷移先情報が指し示す複数の登録文字列に共通する文字列と終端同士が一致する前記登録文字列が存在しない場合、当該ノードの前記遷移先情報指し示す遷移先の前記登録文字列を、前記遷移先情報と共に指し示し
前記検索では、前記ノードに含まれる前記直列文字列情報が指し示す登録文字列と前記検索文字列との比較範囲を、前記ノードに含まれる前記ブランチ位置と前記データツリーにおける前記ノードの直前のノードに含まれる前記ブランチ位置との差に基づいて動的に決定する、
処理をコンピュータに実行させるためのプログラム。
【発明の詳細な説明】
【技術分野】
【0001】
本発明は、検索装置、検索方法、及びプログラムに関する。
【背景技術】
【0002】
近年のIT(Information Technology)技術の発達及び世界的な普及に伴い、コンピュータにおけるデータ処理は、企業の競争力をも左右する最も重要な要素に成っている。特にIoT(Intern et of Things)の推進や5Gの普及等により、全世界のデータ量はさらに爆発的に増加すると予測されている。このため、データ処理技術の飛躍的な向上が望まれている。
【0003】
データ処理技術として、例えば、データ検索に関連する技術として、特許文献1、非特許文献1~4が知られている。特許文献1には、Patricia-Treeを用いた情報検索方法が記載されている。非特許文献1には、Trie(Prefix-Tree)による効率的なインデックス作成方法が記載されている。非特許文献2には、VAST木を用いたSIMD命令(Single Instruction/Multiple Data)による大規模データ探索方法が記載されている。非特許文献3には、Trieの高さを最適化する方法が記載されている。非特許文献4には、SIMD命令を使用してツリーベースのインデックス構造の処理を高速化する方法が記載されている。
【先行技術文献】
【特許文献】
【0004】
【文献】特開2001-357070号公報
【非特許文献】
【0005】
【文献】Matthias Boehm, Benjamin Schlegel, Peter Benjamin Volk, Ulrike Fischer, Dirk Habich, Wolfgang Lehner, "Efficient In-Memory Indexing with Generalized Prefix Trees", Datenbanksysteme fur Business, Technologie und Web (BTW), pp. 227-246, 2011年3月, [令和5年12月18日検索], インターネット<URL:https://dl.gi.de/bitstreams/4acd192a-e10b-4fa5-bb29-af8907b0a1ae/download>
【文献】山室 健, 鬼塚 真, 日高 東潮, 山室 雅司, "VAST木: 木構造索引の圧縮を用いたSIMD命令による大規模データ探索の高速化", 情報処理学会論文誌データベース, Vol.8,No.2,pp.30-42, 2015年6月, [令和5年12月18日検索], インターネット<URL:https://db-event.jpn.org/deim2011/proceedings/pdf/e2-1.pdf>
【文献】Robert Binna, Eva Zangerle, Martin Pichl, Gunther Specht, Viktor Leis, "HOT: A Height Optimized Trie Index for Main-Memory Database Systems", SIGMOD '18: Proceedings of the 2018 International Conference on Management of Data, 2018年5月, pp.521-534, [令和5年12月18日検索], インターネット<URL:https://15721.courses.cs.cmu.edu/spring2020/papers/07-oltpindexes2/p521-binna.pdf>
【文献】Steffen Zeuch, Frank Huber, Johann-Christoph Freytag, "Adapting Tree Structures for Processing with SIMD Instructions", 17th International Conference on Extending Database Technology(EDBT), p.97-108, 2014年3月, [令和5年12月18日検索], インターネット<URL:https://openproceedings.org/2014/conf/edbt/ZeuchFH14.pdf>
【発明の概要】
【発明が解決しようとする課題】
【0006】
しかしながら、上記のような関連する技術では、可変長の文字列を検索することが考慮されていないため、効率よく検索することができない場合がある。
【0007】
本発明は、このような事情に鑑みてなされたものであって、効率よく文字列を検索することが可能な検索装置、検索方法、及びプログラムを提供することを目的とする。
【課題を解決するための手段】
【0008】
本発明に係る検索装置は、可変長の登録文字列と、複数のノードから構成されるデータツリーとを格納する格納部であって、前記ノードは、前記登録文字列の少なくとも一部の文字列を示す直列文字列情報と、当該ノードの下位の遷移先に関するブランチ情報とを含む、格納部と、前記ノードの前記直列文字列情報及び前記ブランチ情報に基づいて、検索文字列を含む前記登録文字列を検索する検索部と、を備え、前記直列文字列情報は、前記直列文字列情報が示す文字列と終端同士が一致する前記登録文字列が存在する場合、前記登録文字列の実体を保持し、前記直列文字列情報が示す文字列と終端同士が一致する前記登録文字列が存在しない場合、当該ノードの前記ブランチ情報が示す遷移先の前記登録文字列を共用参照するものである。
【0009】
本発明に係る検索方法は、可変長の登録文字列と、複数のノードから構成されるデータツリーとを格納し、前記ノードは、前記登録文字列の少なくとも一部の文字列を示す直列文字列情報と、当該ノードの下位の遷移先に関するブランチ情報とを含み、前記ノードの前記直列文字列情報及び前記ブランチ情報に基づいて、検索文字列を含む前記登録文字列を検索し、前記直列文字列情報は、前記直列文字列情報が示す文字列と終端同士が一致する前記登録文字列が存在する場合、前記登録文字列の実体を保持し、前記直列文字列情報が示す文字列と終端同士が一致する前記登録文字列が存在しない場合、当該ノードの前記ブランチ情報が示す遷移先の前記登録文字列を共用参照するものである。
【0010】
本発明に係るプログラムは、可変長の登録文字列と、複数のノードから構成されるデータツリーとを格納し、前記ノードは、前記登録文字列の少なくとも一部の文字列を示す直列文字列情報と、当該ノードの下位の遷移先に関するブランチ情報とを含み、前記ノードの前記直列文字列情報及び前記ブランチ情報に基づいて、検索文字列を含む前記登録文字列を検索し、前記直列文字列情報は、前記直列文字列情報が示す文字列と終端同士が一致する前記登録文字列が存在する場合、前記登録文字列の実体を保持し、前記直列文字列情報が示す文字列と終端同士が一致する前記登録文字列が存在しない場合、当該ノードの前記ブランチ情報が示す遷移先の前記登録文字列を共用参照する、処理をコンピュータに実行させるためのプログラムである。
【発明の効果】
【0011】
本発明によれば、効率よく文字列を検索することが可能な検索装置、検索方法、及びプログラムを提供することができる。
【図面の簡単な説明】
【0012】
図1】実施の形態1に係るデータツリーの構成例を示す構成図である。
図2】実施の形態1に係るデータツリーの具体例を示す図である。
図3】実施の形態1に係る検索装置を示す構成図である。
図4A】実施の形態1に係る完全一致検索処理の動作例を示すフローチャートである。
図4B】実施の形態1に係る完全一致検索処理の動作例を示すフローチャートである。
図5】実施の形態1に係る完全一致検索処理の具体例を説明するための図である。
図6A】実施の形態1に係る直列文字列比較処理の動作例を示すフローチャートである。
図6B】実施の形態1に係る直列文字列比較処理の動作例を示すフローチャートである。
図7】実施の形態1に係るブランチバイト列比較処理の動作例を示すフローチャートである。
図8】実施の形態1に係る差異位置インデックス取得処理の動作例を示す図である。
図9】実施の形態1に係る一致位置インデックス取得処理の動作例を示す図である。
図10A】実施の形態1に係る検索区間インデックス取得処理の動作例を示す図である。
図10B】実施の形態1に係る検索区間インデックス取得処理の動作例を示す図である。
図11】実施の形態1に係るバイト最上位ビット集約処理の動作例を示す図である。
図12】実施の形態1に係るノードデータのメモリ配置例を示す図である。
図13A】実施の形態2に係る前方一致検索処理の動作例を示すフローチャートである。
図13B】実施の形態2に係る前方一致検索処理の動作例を示すフローチャートである。
図14】実施の形態2に係る前方一致検索処理の具体例を説明するための図である。
図15A】実施の形態2に係る反復取得処理の動作例を示すフローチャートである。
図15B】実施の形態2に係る反復取得処理の動作例を示すフローチャートである。
図16】実施の形態2に係る反復取得処理の具体例を説明するための図である。
図17】実施の形態3に係る検索装置を示す構成図である。
図18A】実施の形態3に係る登録処理の動作例を示すフローチャートである。
図18B】実施の形態3に係る登録処理の動作例を示すフローチャートである。
図19】実施の形態3に係る登録処理の具体例を説明するための図である。
図20】実施の形態3に係る登録処理の具体例を説明するための図である。
図21】実施の形態3に係る登録処理の具体例を説明するための図である。
図22】実施の形態3に係る登録処理の具体例を説明するための図である。
図23】実施の形態3に係る登録処理の具体例を説明するための図である。
図24】実施の形態3に係る登録処理の具体例を説明するための図である。
図25】実施の形態3に係る登録処理の具体例を説明するための図である。
図26】実施の形態4に係るデータ変換規則例の表を示す図である。
図27】実施の形態4に係る符号なし整数値の比較結果を示す図である。
図28】実施の形態4に係る符号付き整数値の比較結果を示す図である。
図29】実施の形態4に係る浮動小数点数値のフォーマット例を示す図である。
図30】実施の形態4に係る2つのエンディアンのデータ例を示す図である。
図31】実施の形態5に係るマルチキーの構成例の構成例を示す図である。
図32】一般的なマルチキーの比較回数を説明するための図である。
図33】実施の形態5におけるマルチキーの比較回数を説明するための図である。
【発明を実施するための形態】
【0013】
以下、図面を参照して本発明の実施の形態について説明する。ただし、本発明が以下の実施の形態に限定される訳ではない。また、説明を明確にするため、以下の記載および図面は、適宜、省略、および簡略化がなされている。なお、各図面において、同一の要素には同一の符号が付されており、必要に応じて重複説明は省略されている。
【0014】
(関連する技術の検討)
実施の形態の理解を助けるため、コンピュータにおけるデータ処理について説明する。コンピュータの中で扱うデータには、様々なものが存在するが、その基本は、固定小数点(Int)や浮動小数点(Float)などの数値データと、文字コードを連結した文字列になる。イメージや音声などのデータは、この両者のハイブリッド的な位置付で、数値データを連結した数値列と考えることができる。
【0015】
この中の数値データのサイズは8bit,16bit,32bit,64bitなどの固定サイズで構成される。一方、現在のコンピュータの処理サイズは64bit化が進んでいる。このため、64bit(8バイト)以下である数値型のデータはCPU(Central Processing Unit)の持つ命令(Instruction Set)を使い、一つのデータに対し、論理演算(And,Or,Notなど)や算術演算(Add,Sub,Mul,Divなど)を一回の命令操作で完結することが出来る。このことから、数値データはコンピュータにとって、扱うのが容易なデータ形式と言える。
【0016】
これに対し、文字列は、氏名や、会社名、商品名、住所、説明文など最短1バイトから長いものでは数千バイトを超えるものもあり、これら長さの異なるデータを一つの文字列データとして扱う必要がある。このように、文字列は可変サイズで、多くの場合、64bit(8バイト)より大きなサイズになるため、その操作は、CPUによる一回の命令操作では完結せず、長さやサイズに合わせて、複数の命令を組み合わせて行うことになる。このことから、文字列データは数値データに比べると、処理に手間がかかるデータ形式と言える。
【0017】
しかしながら、文字列は人間が直接認識できる文字の組み合わせで構成され、アルファベットや数字、さらには漢字やひらがななども自由に連結して構成できるため、商品コードや、各種分類コード、商品名、住所表記などのように、数値データに比べ、様々なデータの表現に幅広く利用される。このように、文字列は前記のように様々な意味を持つデータに使われ、その応用範囲も広い。従ってデータベースシステムにおいても、最も基本的なデータ型の一つ(一般にはVarCharと呼ばれる場合が多い。)として扱われる。
【0018】
コンピュータシステム上で文字列を扱う場合、基本操作として、文字列データの登録、削除ならびに検索の機能が必要になる。数値データのような、単独のデータと異なり、文字列は複数の文字を繋げた一連のデータを一つのデータとして扱う。このため、文字列に対する検索の種類は複数あり、大きく分けて完全一致検索、前方一致検索、範囲検索(大小検索)、後方一致検索、中間一致検索の5つがある。
【0019】
完全一致検索は、その名の通り、検索キーと対象データが完全に一致したものを検索する。前方一致検索は、対象データの先頭側が検索キーと一致したものを検索する。この場合、対象の文字列の検索キーより後の部分は何であっても良い。
【0020】
範囲検索(大小検索)は、文字列を辞書順の並びとした場合に、開始位置と終了位置の文字列を与え、その区間に該当するものを検索する。開始位置や終了位置は、完全一致、前方一致のいずれかの検索キーを使うことが出来る。また、検索キーの指定は、開始位置、終了位置のいずれか一方のみでも良い。
【0021】
後方一致検索は前方一致の逆で、対象データの後方側が検索キーと一致したものを検索する。この場合、対象の文字列の検索キーより前の部分は何であっても良い。中間一致検索は対象データのいずれかの位置に検索キーと一致した文字列が存在するものを検索する。
【0022】
発明者は、文字列の検索を効率よく行うため、データ検索に関連する技術について検討した。コンピュータ上で扱うデータ量は近年のBigDataの流れもあり、非常に多くなっている。しかし、単純にデータを入力順に格納し、その格納済みデータを先頭から順次チェックしていく方式では、データの検索に多大な時間とコストがかかってしまう。このため、大量データを効率よく扱うための技術は従来から様々な手法が提案されている。特に、「コンピュータに大量のデータを登録し、その中から所定のデータを高速に検索する技術」はデータを扱う上での重要な機能で、関連する技術として、特許文献1、非特許文献1~4などの様々な処理方式が提案されている。
【0023】
Patricia-Treeは、広く知られた2分ツリー探索の1種であり、例えば、特許文献1に記載されている。Patricia-Treeを用いてデータを検索する場合、ツリーの上位から、比較位置のビットの0,1により、2分木の0と1に対応するノードに遷移を繰り返し、最終的にリーフにたどり着いた場合に、検索キーと検索データの比較を行う。これにより、検索キー全体の比較を、実質1回に抑えることができるため、効率よく検索が出来る。
【0024】
一方、Trieも広く知られたツリー構造である。TrieはPatricia-Treeの元となる考え方であり、このTrieをベースとした処理方式も様々なものが提案されている。非特許文献1の4.1には、先行するゼロ部分の長さに従って、Trieの検索開始位置を途中から開始することで、ツリーの遷移回数を減らす"Bypass Jumper Array"と呼ぶ方式が示されている。非特許文献2にも、ツリーにおける対象データを非可逆圧縮した、VAST(Vector Advanced Structure)と呼ぶツリー構造を使った方式が示されている。また、非特許文献3には、ツリーの高さを最適化するために、キーの分岐に使うビット(スパンビット)の長さを可変にすることで、Trieのツリーにおける分岐数を確保し、ツリーの高さを抑えることで、検索を効率化しうる処理方式が示されている。さらに、非特許文献4にも、SIMD命令を使った効率化の手法として、B-TreeをベースとしたSeg-Treeならびに、TrieをベースにしたSeg-Trieを使った処理方式が示されている。
【0025】
これらの関連する技術によれば、いずれの処理方式もビット単位やバイト単位による遷移を活用することで、データサイズが小さい数値系のデータに対しては効率よく動作を行うことが出来る。しかしながら、文字列のように、データの長さが1~1000バイト以上にも及ぶ大きな変化を伴い、かつ、そのサイズ自体も大きくなるものを対象とした検索に対しては、効率良く処理できない場合が有る。
【0026】
そこで、実施の形態では、バイナリデータを含む可変長の文字列に対する効率的な検索処理を可能とする。
【0027】
(実施の形態の概要)
次に、実施の形態の概要について説明する。実施の形態では、例えば、可変長文字列を対象とした完全一致検索、前方一致検索、または、範囲検索を行う検索装置を提供する。
【0028】
検索装置では、マルチノードツリー構造を使用して、可変長文字列を登録し、検索可能とする。マルチノードツリー構造を構成するノードは、可変長文字列の部分一致文字列となる直列文字列と、それに続く、次の1バイトを持つブランチの集合と、それに一致した場合の遷移先情報を一組として格納する。例えば、ノードの直列文字列は、文字列の終端が一致する登録文字列が存在する場合は、その文字列の実体を保持し、存在しない場合は、該当ノードより下の登録文字列のいずれかを共用参照してもよい。これにより、可変長の文字列を適切にノードに保持あるいはノードから参照できるため、効率よく文字列を検索することが可能となる。
【0029】
また、検索装置は、マルチノードツリー構造のノードにおいて、直列文字列部分が検索文字列の一部と一致し、次の1バイトがブランチのいずれかに一致した場合、ブランチに対応する次のノードへの遷移を繰り返してもよい。
【0030】
また、検索装置は、ノードの直列文字列と検索文字列の一部を比較する際、比較するバイト数がSIMDのサイズ(256bit,128bit)以上の部分については、SIMD命令を使い、SIMDのサイズ以下の部分については、サイズに応じた一般命令(64bit,32bit,16bit,8bit)を組み合わせて使うことで、長い文字列に対して少ない比較回数で同一判定を行ってもよい。
【0031】
また、検索装置は、ノードのブランチの集合から検索文字列の該当する文字と一致する同値のブランチの位置検出を、CPUのパイプライン処理を乱すループや条件分岐によらず、SIMD命令による並列比較と、その結果に対するビット操作を含む計算処理で実施してもよい。また、ブランチ数が一回のSIMDの処理できるバイト数より多くなる場合、SIMDによる範囲特定と、特定した範囲におけるSIMDを使った同値検出に分けて行うことで、一回のSIMDの処理できるバイト数より多くのブランチに対する同値検出を行ってもよい。この場合、一回目のSIMDによる範囲特定のために、ブランチの中からSIMDのバイト数の倍数位置のブランチを抽出したスーパーIndexをノードに持たせてもよい。
【0032】
また、ノードのデータ構造において、ノードにおけるブランチの集合(例えば1~256個のバイト列)の後にブランチに対応する遷移先情報を詰めて格納することで、ブランチの数がSIMDの基本サイズである128bitや256bitのサイズに満たない場合にメモリ参照違反を起こさず、メモリ容量を削減するとともに、次にアクセスする遷移先情報のキャッシュヒット確立を高めてもよい。
【0033】
また、検索装置は、可変長文字列を含むデータを登録し格納する際、特定の変換規則に従って変換したデータを格納してもよい。例えば、符号あり/符号なしの固定小数点数値(8bit,16bit,32bit,64bit)、並びに、浮動小数点数値(32bit,64bit)を文字列と同じロジックで処理できるように、データを変換し格納してもよい。また、検索装置は、このように変換されたデータを含む、文字列、固定小数点、浮動小数点を任意の順序で結合した複合キーに対して、キー境界を意識せずに、文字列と同様なロジックを使って処理を行ってもよい。
【0034】
例えば、数値の場合は大きくても64bit程度、非特許文献4に示すSeg-Trieに展開しても8バイトにしかならない、一方、文字列は商品名などの名称については20~100バイト程度、住所や説明文などでは、100から1000文字以上に成る場合も有る。対象が可変長で、このように多くのバイトで構成される場合は、関連する技術では効率的な処理ができない。
【0035】
実施の形態では、関連する技術であるSeg-Trieと異なり、ノードが直列文字列と並列ブランチをペアで持っている。直列文字列と並列ブランチをペアで持つことにより、“株式会社”や“Corporation”のような固定ワードに対応する複数文字の並びを、直列文字列を使って、効率よく表すことができる。また、直列文字列を使うことで、長さの異なる文字列を一つのツリーの中で表すことができる。更に、数値キーについても、種類に従った変換を行うことで、キーの一部に数値データを取り込むことが出来、この拡張により、文字列と数値データを連結した複合キーについても、同じ処理方式で扱うことが可能となる。
【0036】
実施の形態では、関連する技術であるVASTやB-Treeに基づいたツリー構造による検索と異なり、大小比較による対象区間の絞り込みではなく、同一値(ブランチ)検索による一致位置の検出によりツリーの下降を行う。そして、この同一値の検出にSIMDを使い、その比較結果を、ビットマスク変換とビットスキャン命令を使ってインデックスに変換する。これにより、同一値のブランチが無い場合は、その時点で検索の失敗を検出できる。また、実施の形態では、ブランチバイト数は、固定サイズではなく、ノードごとに1~256までの異なったサイズでもよい。更に、実施の形態では、事前に全データを用意し、固定的なインデックス構造を作ってから検索を行う形態をとらず、動的にデータの追加を行いつつ、検索が可能なインデックス構造を生成してもよい。
【0037】
(実施の形態1)
次に、実施の形態1について説明する。本実施の形態では、マルチノードツリー構造を用いて、完全一致検索を行う例について説明する。
【0038】
<データツリーの構成例>
図1は、本実施の形態に係るデータツリー111の構成例を示している。データツリー111は、マルチノードツリー構造であり、ツリー状に連結される複数のノード(ノード情報)200と、ノード200から参照される文字列(文字列情報)300を含む。文字列300は、データツリー111に登録される文字列(登録文字列)であり、検索時に検索対象となる文字列である。文字列300は、1バイト~数1000バイト以上に及ぶ可変長の文字列である。なお、文字列は終端にターミネータ(0x00)を持つ。
【0039】
図1に示すように、ノード200は、ブランチサイズ201、allocサイズ202、実体フラグ203、ブランチ位置204、直列文字列205、ブランチバイト列206、遷移先情報207を含む。本実施の形態では、直列文字列205(縦方向)とブランチバイト列206(横方向)の対で一つのノード200を構成する。
【0040】
ブランチサイズ201、allocサイズ202は、ノード200の管理情報である。ブランチサイズ201は、ブランチバイト列206に格納したブランチバイト(ブランチ文字)の数である。また、ブランチサイズ201は、ノード200から分岐した(ノード200の配下(下位)に連結された)ブランチの数でもある。なお、ノード200から分岐(遷移)するブランチは、ノード200または文字列300(リーフ)のいずれかが混在した形に成る。
【0041】
allocサイズ202は、アロケート済みブランチの数を示す。allocサイズ202は、ノード200がブランチを格納するためにアロケートしたサイズを示す。例えば、allocサイズ202は、4,8,16,32・・・256個である。
【0042】
実体フラグ203、ブランチ位置204、直列文字列205は、ノード200のヘッダ情報である。実体フラグ203は、当該ノード200の持つ直列文字列205が実体を参照(保持)するか否かを示すフラグである。実体フラグ203は、直列文字列205の終端で丁度終了する文字列300が存在する場合、すなわち、直列文字列205の終端と直列文字列205が参照する文字列300の終端が一致する場合、ONにセットされる。実体フラグ203は、直列文字列205の終端と直列文字列205が参照する文字列300の終端が一致しない場合、OFFにセットされる。
【0043】
ブランチ位置204は、ノード200が保持するブランチバイト(ブランチ文字)の文字列の先頭からのオフセット位置を示す。換言すると、ブランチ位置204は、検索する文字列のどの位置のバイトとブランチバイトを照合するかの位置を示す。
【0044】
直列文字列205(直列文字列情報)は、登録される文字列300のうち当該ノード200が参照(保持)する文字列を示す。直列文字列205は、文字列300を指し、この文字列のブランチ位置204の前までの部分を使って、ツリーにおける同一文字列部分(一種類)を示す。さらに、実体フラグ203がONの場合、すなわち、直列文字列205の終端と文字列300の終端が一致する場合、直列文字列205は、登録された文字列300の実体を保持(実体保持)する。実体保持とは、格納部(データベース)に格納されている文字列300を単独で指し示すことである。換言すると、実体フラグがONの場合は、直列文字列の指す文字列が、登録済みの文字列として単独で存在することを示す。一方、実体フラグ203がOFFの場合、直列文字列205は、当該ノード200より下位に位置する、いずれかの文字列300を参照(共用参照)する。共用参照とは、当該ノード200の遷移先情報207が示す遷移先のいずれかの文字列300を、直列文字列205が共用して参照することである。
【0045】
ブランチバイト列206は、ノード200から分岐するブランチのブランチバイト(ブランチ文字)を含む。ブランチバイト列206は、複数のブランチ文字を含むブランチ文字の集合でもある。ブランチバイトは、直列文字列205に続く文字の1バイトの値を示し、ブランチ位置204における分岐先(多種類)を決めるキーになる。ブランチバイトの要素サイズは1バイトで、値の範囲は0~255までの256種類になる。従って、ブランチバイト列206は、1~256個までのブランチバイトを格納する可変長配列に成る。そして、ブランチバイト列206は、このブランチバイトを符号なし整数の昇順に格納する。
【0046】
ブランチバイト列206及び遷移先情報207は、当該ノード200の下位の遷移先に関するブランチ情報でもある。遷移先情報207は、ブランチバイト列206の各ブランチバイトに対応した遷移先(ブランチ先)を示す情報である。遷移先情報207は、遷移先のノード/リーフ(文字列)の別と、その位置(アドレス)を示す。
【0047】
<データツリーの具体例>
図2は、本実施の形態に係るデータツリー111の具体例を示している。図2の例では、文字列300-1~300-5が、ノード200-1~200-2を含むデータツリー111に登録されている。
【0048】
文字列300-1~300-5では、0~1文字目の“DG”が共通する。このため、最初のノード200-1の直列文字列205は“DG”となる。そして、“DG”を持つ実際の文字列300-1が存在するため、ノード200-1の実体フラグ203はONになる。
【0049】
ノード200-1のブランチ位置204は、“DG”の次である2を指し、文字列300-2~300-5から、その位置におけるユニークな値は“H”,“K”,“L”の3文字(バイト)となる。このため、ノード200-1のブランチバイト列206には、それらの3文字(バイト)がブランチバイトとして格納され、ブランチサイズ201には、3が入る。
【0050】
ノード200-1の遷移先情報207には、ブランチバイト列206の“H”,“K”,“L”に対応する遷移先が格納される。文字列300-2,300-3より、“H”,“K”の下には各々該当する文字列がそれぞれ1つしかないため、ノード200-1の遷移先情報207は、“H”,“K”の遷移先としてリーフ(各々の文字列300-2,300-3)を指す。一方、文字列300-4,300-5より、“L”の下には複数の文字列があるため、ノード200-1の遷移先情報207は、“L”の遷移先としてノード200-2を指す。
【0051】
文字列300-4~300-5では、“L”の次の3文字目の“E”が共通する。このため、ノード200-2では、直列文字列205は、“E”となる。この場合“E”を終端とする文字列の実体が存在しないため、ノード200-2の直列文字列205は、下位のリーフの文字列300-4~300-5のいずれか一つを共用参照し、ノード200-2の実体フラグ203はOFFとなる。この例では、ノード200-2の直列文字列205は、文字列300-5を指す。ノード200-2のブランチ位置204は、“E”の次である4を指し、文字列300-4~300-5から、その位置におけるユニークな値は“A”,“B”の2文字(バイト)となる。このため、ノード200-2のブランチバイト列206には、それらの2文字(バイト)がブランチバイトとして格納され、ブランチサイズ201には、2が入る。
【0052】
ノード200-2の遷移先情報207には、ブランチバイト列206の“A”,“B”に対応する遷移先が格納される。文字列300-4,300-5より、“A”,“B”の下には各々該当する文字列が1つしかないため、ノード200-2の遷移先情報207は、“A”,“B”の遷移先としてリーフ(各々の文字列300-4,300-5)を指す。
【0053】
ノード200-1及び200-2のallocサイズ202は、2つのノードのブランチサイズ201が、いずれも4以下のため、アロケートサイズの最小である4が入る。
【0054】
<検索装置の構成>
図3は、本実施の形態に係る検索装置100の構成例を示している。検索装置100は、データツリー111ならびに登録文字列112から文字列を検索する。検索装置100は、完全一致検索、前方一致検索、範囲検索(大小検索)のいずれかの検索を行ってもよい。ここでは、一例として、完全一致検索を行う例について説明する。なお、後方一致検索については、文字を後端から、前方一致と同様の方式により検索を行うことで対応することが出来る。この場合、マルチノードのデータツリー111のみを後方一致用に作成し、登録文字列112の持つ文字列300、例えば文字列300-1~300-5は共用しても良い。
【0055】
図3に示すように、検索装置100は、データベース110、入力部120、検索部130、出力部140を備えている。なお、後述の本実施の形態に係る動作が可能であれば、その他の構成でもよい。
【0056】
データベース110は、検索装置100が検索する検索対象のデータを格納する格納部である。データベース110は、検索対象として、上記のマルチノードツリー構造のデータツリー111と、登録文字列112を格納する。登録文字列112には登録された文字列300を格納する。
【0057】
入力部120は、検索装置100の処理に必要な情報等を入力する。例えば、入力部120は、ユーザが入力可能なキーボード等の入力装置でもよい。例えば、入力部120には、ユーザから検索する検索文字列(検索キーとなる入力文字列)が入力される。入力部120は、データツリー111から検索する検索文字列を取得する取得部でもある。
【0058】
検索部130は、入力部120に入力された検索文字列をデータツリー111から検索する検索処理を実行する。例えば、検索部130は、完全一致検索を行い、データツリー111と登録文字列112から検索文字列と完全一致する文字列を検索する。完全一致検索は、検索文字列と全く同じ文字列を検索する処理の一例である。
【0059】
例えば、検索部130は、検索制御部131、文字列比較部132、ブランチ比較部133を含む。検索制御部131は、データツリー111のノード200をルートから順に選択し、選択したノード200の情報と検索文字列の比較結果に基づいて、検索処理を制御する。検索制御部131は、文字列比較部132による直列文字列比較の結果及びブランチ比較部133によるブランチバイト列比較の結果に基づいて、検索結果の判定やノードの遷移制御を行う。検索制御部131は、直列文字列比較の結果及びブランチバイト列比較の結果に応じて、選択されたノード200が示すブランチノードを、遷移先のノード(次に比較を行うノード)として選択する選択部(第1の選択部)でもある。実体フラグ203のON/OFFにより直列文字列205が文字列の実体を保持するか否か分かるため、検索制御部131は、直列文字列比較の結果及び実体フラグ203に基づいて、検索結果の判定等を行ってもよい。
【0060】
文字列比較部(第1の文字列比較部)132は、選択されたノード200の直列文字列205と検索文字列とを比較する直列文字列比較処理を行う。文字列比較部132は、リーフの文字列が選択された場合、リーフの文字列と検索文字列とを比較する。直列文字列比較処理では、SIMD命令並びに一般命令により2つの文字列を比較する。なお、SIMD命令は、並列処理可能な所定のデータ単位で比較処理を行う命令の一例であり、同様に処理可能ならば、その他の命令を組み合わせて使用してもよい。以下のブランチバイト列比較処理でも同様である。
【0061】
ブランチ比較部(第1のブランチ比較部)133は、選択されたノード200のブランチバイト列206のブランチバイトと、検索文字列のブランチ位置204における文字を比較するブランチバイト列比較処理を行う。ブランチ比較部133は、ブランチバイト列比較処理により、ブランチバイト列206から、検索文字列のブランチ位置204における文字と一致するブランチバイト(ブランチ文字)を特定する。ブランチバイト列比較処理では、SIMD命令ならびに一般命令によりブランチバイト列206と検索文字列の該当する文字を比較する。
【0062】
出力部140は、検索装置100の処理結果等を出力する。例えば、出力部140は、液晶ディスプレイ等の表示装置でもよい。出力部140は、検索部130により検索処理の結果を表示してもよい。例えば、出力部140は、検索成功または検索失敗、検索文字列と一致した文字列等を表示してもよい。出力部140は、データベース110に格納されているデータツリー111のツリー構造や登録文字列112を表示してもよい。
【0063】
<完全一致検索処理の動作例>
図4A及び図4Bは、本実施の形態に係る検索装置100における完全一致検索処理の動作例を示している。なお、完全一致検索では、検索成功した場合、常に1件の文字列のみが該当する文字列となる(S132、S151)。
【0064】
図4A及び図4Bに示すように、検索制御部131は、データが未登録か否か、すなわち、初期状態か否か判定する(S101)。入力部120に入力文字列(検索文字列)が入力されると、検索制御部131は、データベース110を参照し、データベース110のデータツリー111にデータ(文字列)が登録されているか否か判定する。S101においてデータが未登録であると判定された場合、検索制御部131は、検索結果を検索失敗として処理を終了する(S120)。
【0065】
S101においてデータが登録されていると判定された場合、検索制御部131は、バイトチェック位置に0をセットし、カレントノードにデータツリー111のルートノードをセットする(S102)。この結果、カレントノードには、ノード200またはリーフ(文字列300)のいずれかがセットされる。
【0066】
続いて、検索制御部131は、カレントノードが文字列か否か、すなわち、リーフに到達したか否か判定する(S103)。検索制御部131は、カレントノードがノード200と文字列300のいずれであるかを判定する。
【0067】
S103においてカレントノードが文字列であると判定された場合、文字列比較部132は、直列文字比較を行う(S130)。この場合、直列文字列比較では、カレントノードであるリーフ文字列と、入力文字列のうちバイトチェック位置から入力文字列終端までの文字列とを比較し、同一か否かチェックする。
【0068】
続いて、検索制御部131は、直列文字列比較の結果、比較した2つの文字列に差異があるか、または、2つの文字列のサイズが違うか否か判定する(S131)。S131において、比較した2つの文字列に差異がある、または、2つの文字列のサイズが違うと判定された場合、検索制御部131は、検索結果を検索失敗として処理を終了する(S133)。
【0069】
S131において、比較した2つの文字列が一致し、かつ、2つの文字列が同じであると判定された場合、検索制御部131は、検索結果を検索成功(入力文字列とリーフ文字列が同一である)として処理を終了する(S132)。
【0070】
S103においてカレントノードが文字列ではない、すなわちノードであると判定された場合、検索制御部131は、比較サイズに“min(カレントノードのブランチ位置,入力文字列長+1)-バイトチェック位置”の結果をセットする(S104)。すなわち、検索制御部131は、カレントノードであるノード200のブランチ位置204と入力文字列にターミネータ1バイト分を加えた長さのうち小さい方の値から、バイトチェック位置を差し引いた値を比較サイズとする。ここでは、入力文字列長に1を加えてターミネータまでを比較範囲に含めることで、入力文字列がカレントノードのブランチ位置より短い場合、最長でも入力文字列のターミネータ位置で差異を検出するよう設定している。
【0071】
続いて、文字列比較部132は、直列文字比較を行う(S105)。この場合、直列文字列比較では、カレントノードであるノード200の直列文字列205と、入力文字列のうちバイトチェック位置から比較サイズ分の文字列とを比較し、同一か否かチェックする。
【0072】
続いて、検索制御部131は、直列文字列比較の結果、比較した2つの文字列に差異があるか否か判定する(S106)。S106において、比較した2つの文字列に差異があると判定された場合、検索制御部131は、検索結果を検索失敗として処理を終了する(S140)。
【0073】
S106において、比較した2つの文字列が一致すると判定された場合、検索制御部131は、バイトチェック位置にカレントノードであるノード200のブランチ位置204をセットする(S107)。
【0074】
続いて、検索制御部131は、バイトチェック位置が入力文字列長以上か、すなわち、入力文字チェックが完了したか否か判定する(S108)。S108において、バイトチェック位置が入力文字列長以上であると判定された場合、検索制御部131は、カレントノードであるノード200の直列文字列205が実体であり(実体フラグがON)、かつ、入力文字列と直列文字列205のサイズが同じか否か判定する(S150)。
【0075】
S150において、カレントノードであるノード200の直列文字列205が実体であり(実体フラグがONであり)、かつ、入力文字列と直列文字列205のサイズが同じであると判定された場合、検索制御部131は、検索結果を検索成功(入力文字列とカレントノードの直列文字列205が同一である)として、処理を終了する(S151)。
【0076】
S150において、カレントノードであるノード200の直列文字列205が実体ではなく(実体フラグがOFFである)、または、入力文字列と直列文字列205のサイズが異なると判定された場合、検索制御部131は、検索結果を検索失敗として処理を終了する(S152)。
【0077】
S108において、バイトチェック位置が入力文字列長より小さいと判定された場合、ブランチ比較部133は、ブランチバイト列比較を行う(S109)。この場合、ブランチバイト列比較では、カレントノードであるノード200のブランチバイト列206と入力文字列[バイトチェック位置]とを比較し、カレントノードのブランチバイト列206に入力文字列[バイトチェック位置]と同じ値があるかチェックする。なお、入力文字列におけるバイトチェック位置のバイト(文字)を“入力文字列[バイトチェック位置]”と示す場合がある。
【0078】
続いて、検索制御部131は、ブランチバイト列比較の結果、カレントノードであるノード200のブランチバイト列206に同じ値があるか否か判定する(S110)。S110において、カレントノードであるノード200のブランチバイト列206に同じ値がないと判定された場合、検索制御部131は、検索結果を検索失敗として処理を終了する(S160)。
【0079】
S110において、カレントノードであるノード200のブランチバイト列206に同じ値があると判定された場合、検索制御部131は、バイトチェック位置に1を加え、更に、カレントノードに一致したブランチバイトに対応する遷移先情報207をセットする(S111)。その後、S103以降の処理を繰り返す。
【0080】
<完全一致検索処理の具体例>
図5を用いて、図4A及び図4Bの完全一致検索処理の具体例について説明する。図5の例では、文字列300-1~300-8が、ノード200-1~200-4を含むデータツリー111に登録されている。この例では、図5のデータツリー111から完全一致検索で入力文字列“DGHKPS”(6文字)を検索する場合の動作について説明する。なお、図5に示すノード200の表記は、以降の具体例を示す各図でも同様である。
【0081】
(1)初回ループ
検索制御部131は、最初にデータツリー111のデータ登録を確認し(S101)、図5のようにデータが登録されているため、初期化に進む。初期化では、検索制御部131は、バイトチェック位置に0をセットし、カレントノードにルートノードをセットする(S102)。この場合、カレントノードは、最上位のノード200-1を指すようになる。
【0082】
続いて、1回目のループとして、検索制御部131は、カレントノードであるノード200-1が文字列(リーフ)か否かチェックし(S103)、文字列ではないため、ループ処理を続行する。
【0083】
続いて、検索制御部131は、比較サイズを計算する(S104)。この場合、比較サイズは、カレントノードであるノード200-1のブランチ位置204=1と入力文字列“DGHKPS”の文字列長+1=7の小さい方の値である1から、バイトチェック位置である0を減算し、結果は1となる。
【0084】
続いて、文字列比較部132は、直列文字列比較を行う(S105)。この場合、直列文字列比較では、カレントノードであるノード200-1の直列文字列205の指す文字列“DBXPN”と入力文字列“DGHKPS”とを使い、バイトチェック位置である0バイト目から比較サイズである1バイト分の文字列が同一か否かをチェックする。直列文字列比較の結果、2つの文字列の0バイト目はいずれも“D”であり、文字列に差異はないため(S106)、検索制御部131は、ループ処理を続行する。
【0085】
続いて、検索制御部131は、バイトチェック位置にカレントノードであるノード200-1のブランチ位置204である1をセットする(S107)。
【0086】
続いて、検索制御部131は、バイトチェック位置である1が入力文字列長である6以上、つまり入力文字チェックが完了したか否かをチェックし(S108)、バイトチェック位置が入力文字列長を超えていないため、ループ処理を続行する。
【0087】
続いて、ブランチ比較部133は、ブランチバイト列比較を行う(S109)。この場合、ブランチバイト列比較では、カレントノードであるノード200-1のブランチバイト列206=(“B”,“G”,“R”)の中に、入力文字列“DGHKPS”のバイトチェック位置=1の文字である“G”と同じ値があるか否かをチェックする。ブランチバイト列比較の結果、ノード200-1のブランチバイト列206のインデックス1番目に同じ値があるため(S110)、検索制御部131は、ループ処理を続行する。
【0088】
続いて、検索制御部131は、バイトチェック位置である1に、1を加えて2とし、カレントノードに、一致したブランチバイト列206のインデックス1番目=“G”に対応する遷移先情報207をセットする(S111)。この場合、カレントノードは、上位から2番目のノード200-2を指すようになる。
【0089】
(2)2回目ループ
2回目のループでも同様に、検索制御部131は、カレントノードであるノード200-2が文字列(リーフ)でないため(S103)、比較サイズを計算する(S104)。この場合、比較サイズは、カレントノードであるノード200-2のブランチ位置204=2と入力文字列“DGHKPS”の文字列長+1=7の小さい方の値である2から、バイトチェック位置である2を減算し、結果は0となる。
【0090】
続いて、文字列比較部132は、直列文字列比較を行う(S105)。この場合、直列文字列比較では、カレントノードであるノード200-2の直列文字列205の指す文字列“DG”と入力文字列“DGHKPS”とを比較し、バイトチェック位置である2バイト目から比較サイズである0バイト分の文字列が同一か否かをチェックする。直列文字列比較の結果、比較サイズが0のため差は検出されず(S106)、検索制御部131は、ループ処理を続行する。
【0091】
続いて、検索制御部131は、バイトチェック位置にカレントノードであるノード200-2のブランチ位置204である2をセットする(S107)。
【0092】
続いて、検索制御部131は、バイトチェック位置である2が入力文字列長である6以上、つまり入力文字チェックが完了したかどうかをチェックし(S108)、入力文字チェックが完了していないため、ループ処理を続行する。
【0093】
続いて、ブランチ比較部133は、ブランチバイト列比較を行う(S109)。この場合、ブランチバイト列比較では、カレントノードであるノード200-2のブランチバイト列206=(“H”,“K”,“L”)の中に、入力文字列“DGHKPS”のバイトチェック位置=2の文字である“H”と同じ値があるか否かをチェックする。ブランチバイト列比較の結果、ノード200-2のブランチバイト列206のインデックス0番目に同じ値があるため(S110)、検索制御部131は、ループ処理を続行する。
【0094】
続いて、検索制御部131は、バイトチェック位置である2に、1を加えて3とし、カレントノードに、一致したブランチバイト列206のインデックス0番目=“H”に対応する遷移先情報207をセットする(S111)。この場合、カレントノードは、上位から3番目の左側のノード200-3を指すようになる。
【0095】
(3)3回目ループ
3回目ループでも同様に、検索制御部131は、カレントノードであるノード200-3が文字列(リーフ)でないため(S103)、比較サイズを計算する(S104)。この場合、比較サイズは、カレントノードであるノード200-3のブランチ位置204=5と入力文字列“DGHKPS”の文字列長+1=7の小さい方の値である5からバイトチェック位置である3を減算し、結果は2となる。
【0096】
続いて、文字列比較部132は、直列文字列比較を行う(S105)。この場合、直列文字列比較では、カレントノードであるノード200-3の直列文字列205の指す文字列“DGHKP”と入力文字列“DGHKPS”とを比較し、バイトチェック位置である3バイト目から比較サイズである2バイト分の文字列が同一かをチェックする。直列文字列比較の結果、2つの文字列のうち3バイト目から2バイト分の文字列はいずれも“KP”であり、同一のため(S106)、検索制御部131は、ループ処理を続行する。
【0097】
続いて、検索制御部131は、バイトチェック位置にカレントノードであるノード200-3のブランチ位置204である5をセットする(S107)。
【0098】
続いて、検索制御部131は、バイトチェック位置である5が入力文字列長である6以上、つまり入力文字チェックが完了したかどうかをチェックし(S108)、入力文字チェックが完了していないため、ループ処理を続行する。
【0099】
続いて、ブランチ比較部133は、ブランチバイト列比較を行う(S109)。この場合、ブランチバイト列比較では、カレントノードであるノード200-3のブランチバイト列206=(“S”)の中に、入力文字列“DGHKPS”のバイトチェック位置=5の文字である“S”と同じ値があるか否かをチェックする。ブランチバイト列比較の結果、ノード200-3のブランチバイト列206のインデックス0番目に同じ値があるため(S110)、検索制御部131は、ループ処理を続行する。
【0100】
続いて、検索制御部131は、バイトチェック位置である5に、1を加えて6とし、カレントノードに、一致したブランチバイト列206のインデックス0番目=“S”に対応する遷移先情報207をセットする(S111)。この場合、カレントノードは、文字列300-4(リーフ)である“DGHKPS”を指すようになる。
【0101】
(4)4回目(終了)ループ
4回目ループでは、検索制御部131は、カレントノードである文字列300-4が文字列であり、リーフにたどり着いたため(S103)、ループを抜け、最終判定に移る。
【0102】
最終判定では、まず、文字列比較部132は、直列文字比較を行う(S130)。この場合、直列文字列比較では、リーフの文字列“DGHKPS”と入力文字列“DGHKPS”とを比較し、バイトチェック位置の6バイト目から入力文字列の終端までの文字列が同一か否かチェックする。
【0103】
直列文字列比較の結果、入力文字列は既に終端に達しているため、差異は検出されない。リーフの文字列と入力文字列は、差異が無く、文字列サイズも同じであるため(S131)、完全一致と判断され、検索制御部131は、結果の返却に移る。結果の返却では、検索制御部131は、最終結果として、検索成功(リーフ文字列同一)をリターンして処理を終了する(S132)。
【0104】
<直列文字列比較処理の動作例>
図6A及び図6Bは、本実施の形態に係る直列文字列比較処理の動作例を示している。図6A及び図6Bは、図4のS105及びS130の直列文字列比較処理の動作例である。直列文字列比較処理では、直列文字列と入力文字列、または、リーフ文字列と入力文字列を比較し、2つの文字列の差異位置のインデックスを取得する。
【0105】
図6A及び図6Bに示すように、文字列比較部132は、オフセットを0に初期化する(S201)。この例では、オフセットの単位はバイトである。
【0106】
続いて、文字列比較部132は、オフセットに16を加えた値が比較サイズ以下であるか否か判定する(S202)。S202において、オフセットに16を加えた値が比較サイズ以下であると判定された場合、文字列比較部132は、オフセット位置を指定して差異位置インデックス取得を行う(S220)。差異位置インデックス取得では、SIMD命令を使用して、直列文字列と入力文字列、または、リーフ文字列と入力文字列と比較し、差異のあるインデックス位置を取得する。すなわち、比較する文字列のサイズがSIMDサイズ以上の場合、SIMD命令を使用して16バイト分の文字列を一挙に比較する。
【0107】
続いて、文字列比較部132は、差異位置インデックス取得の結果、2つの文字列に違いが見つかったか否か判定する(S221)。S221において、2つの文字列が同じであると判定された場合、文字列比較部132は、オフセットに16を加えて(S222)、S202以降の処理を繰り返す。
【0108】
S221において、2つの文字列に違いが見つかったと判定された場合、文字列比較部132は、オフセットにS220で取得した差異位置インデックスを加えて、求めた値を差異位置にセットし(S223)、セットした差異位置をリターンして、処理を終了する(S224)。
【0109】
S202において、オフセットに16を加えた値が比較サイズより大きいと判定された場合、文字列比較部132は、オフセットに8を加えた値が比較サイズ以下であるか否か判定する(S203)。すなわち、比較する文字列のサイズがSIMDサイズより小さい場合、S203以降で、比較する文字列のサイズに応じた通常の命令を使用して文字列を比較する。S203において、オフセットに8を加えた値が比較サイズ以下であると判定された場合、文字列比較部132は、uint64_t型(符号なし64ビット整数型)でオフセット位置をxor(exclusive or)比較する(S204)。
【0110】
続いて、文字列比較部132は、2つの文字列のxor比較結果が0以外か否か判定する(S205)。S205において、2つの文字列のxor比較結果が0である、すなわち、2つの文字列が同じであると判定された場合、文字列比較部132は、オフセットに8を加える(S206)。
【0111】
S203において、オフセットに8を加えた値が比較サイズより大きいと判定された場合、または、S206を経由して、オフセットに8を加えた後、文字列比較部132は、オフセットに4を加えた値が比較サイズ以下であるか否か判定する(S207)。
【0112】
S207において、オフセットに4を加えた値が比較サイズ以下であると判定された場合、文字列比較部132は、uint32_t型(符号なし32ビット整数型)でオフセット位置をxor比較する(S208)。
【0113】
続いて、文字列比較部132は、2つの文字列のxor比較結果が0以外か否か判定する(S209)。S209において、2つの文字列のxor比較結果が0である、すなわち、2つの文字列が同じであると判定された場合、文字列比較部132は、オフセットに4を加える(S210)。
【0114】
S207において、オフセットに4を加えた値が比較サイズより大きいと判定された場合、または、S210を経由して、オフセットに4を加えた後、文字列比較部132は、オフセットに2を加えた値が比較サイズ以下であるか否か判定する(S211)。
【0115】
S211において、オフセットに2を加えた値が比較サイズ以下であると判定された場合、文字列比較部132は、uint16_t型(符号なし16ビット整数型)でオフセット位置をxor比較する(S212)。
【0116】
続いて、文字列比較部132は、2つの文字列のxor比較結果が0以外か否か判定する(S213)。S205、S209、S213において、2つの文字列のxor比較結果が0以外である、すなわち、2つの文字列に差異があると判定された場合、文字列比較部132は、比較結果から先頭のONビット位置を取得する(S230)。具体的には、_BitScanForward(比較結果)を実行し、xor比較結果から先頭のONビット位置を求める。
【0117】
続いて、文字列比較部132は、オフセット(バイト位置)に先頭のONビット位置を3ビット右シフトすることでバイト位置に変換した値を加えて、求めた値を差異位置にセットし(S231)、セットした差異位置をリターンして、処理を終了する(S232)。
【0118】
S213において、2つの文字列のxor比較結果が0である、すなわち、2つの文字列が同じであると判定された場合、文字列比較部132は、オフセットに2を加える(S214)。
【0119】
S211において、オフセットに2を加えた値が比較サイズより大きいと判定された場合、または、S214を経由して、オフセットに2を加えた後、文字列比較部132は、オフセットが比較サイズより小さいか否か判定する(S215)。
【0120】
S215において、オフセットが比較サイズより小さいと判定された場合、文字列比較部132は、uint8_t型(符号なし8ビット整数型)でオフセット位置を比較する(S216)。
【0121】
続いて、文字列比較部132は、2つの文字列の比較結果で差異があるか否か判定する(S217)。S217において、2つの文字列の比較結果で差異があると判定された場合、文字列比較部132は、差異位置にオフセットをセットし(S240)、セットした差異位置をリターンして、処理を終了する(S241)。一方、S215において、オフセットが比較サイズ以上と判定された場合、ならびに、S217において、2つの文字列の比較結果で差異がないと判定された場合、文字列比較部132は、差異なしをリターンして、処理を終了する(S218)。
【0122】
<ブランチバイト列比較処理の動作例>
図7は、本実施の形態に係るブランチバイト列比較処理の動作例を示している。図7は、図4のS109のブランチバイト列比較処理の動作例である。ブランチバイト列比較処理では、ノード200のブランチバイト列206と比較バイトとを比較し、ブランチバイト列206から比較バイトと一致する位置のインデックスを取得する。
【0123】
図7に示すように、ブランチ比較部133は、ノード200のブランチサイズ201(ブランチ数)が16以下であるか否か判定する(S301)。S301において、ブランチサイズ201が16以下であると判定された場合、ブランチ比較部133は、ブランチバイト列を指定して一致位置インデックス取得を行う(S302)。一致位置インデックス取得では、SIMD命令を使用して、ブランチバイト列206の中から比較バイトと一致する文字の位置を示すインデックスを取得する。
【0124】
続いて、ブランチ比較部133は、一致位置インデックス取得の結果、ブランチバイト列206の中から比較バイトと一致する一致位置が見つかったか否か判定する(S303)。S303において、ブランチバイト列206の中から比較バイトと一致する一致位置が見つからなかったと判定された場合、ブランチ比較部133は、一致なしをリターンして、処理を終了する(S306)。
【0125】
S303において、ブランチバイト列206の中から比較バイトと一致する一致位置が見つかったと判定された場合、ブランチ比較部133は、一致位置を示すインデックスを、一致位置にセットし(S304)、セットした一致位置をリターンして、処理を終了する(S305)。
【0126】
S301において、ブランチサイズ201が16より大きいと判定された場合、ブランチ比較部133は、まず、ブランチバイト列を指定して検索区間インデックス取得を行う(S307)。ブランチバイト列の並びは、図1で示したように、符号なし整数の昇順に配置されているため、検索区間インデックス取得では、SIMDのサイズ(16バイト)の整数倍位置のバイトを抽出し、比較バイトがその抽出したバイト群のどこに位置するかを調べることで、次の一致判定で使う16バイトの検索区間(比較位置)を特定する。なお、ブランチバイトは1バイトのため、その種類は最大でも256となり、長さも最長で256バイトとなる。従って、256÷16=16となり、この検索区間の特定操作は16バイトのSIMDを使って、一回処理するだけで、目的とする検索区間を絞り込むことが出来る。
【0127】
続いて、ブランチ比較部133は、検索区間インデックス取得の結果、ブランチバイト列206の中から検索区間が見つかったか否か判定する(S308)。S308において、ブランチバイト列206の中から検索区間が見つからなかったと判定された場合、ブランチ比較部133は、一致なしをリターンして、処理を終了する(S306)。
【0128】
S308において、ブランチバイト列206の中から検索区間が見つかったと判定された場合、ブランチ比較部133は、検索区間を指定して一致位置インデックス取得を行う(S309)。一致位置インデックス取得では、S302同様、SIMD命令を使用して、ブランチバイト列206の検索区間の中から比較バイトと一致する一致位置を示すインデックスを取得する。
【0129】
続いて、ブランチ比較部133は、一致位置インデックス取得の結果、ブランチバイト列206の検索区間の中から比較バイトと一致する一致位置が見つかったか否か判定する(S310)。S310において、ブランチバイト列206の検索区間の中から比較バイトと一致する一致位置が見つからなかったと判定された場合、ブランチ比較部133は、一致なしをリターンして、処理を終了する(S306)。
【0130】
S310において、ブランチバイト列206の検索区間の中から比較バイトと一致する一致位置が見つかったと判定された場合、ブランチ比較部133は、検索区間の先頭位置に一致位置を示すインデックスを加えた値を、ブランチバイト全体におけるインデックスとして、一致位置にセットし(S311)、セットした一致位置をリターンして、処理を終了する(S312)。
【0131】
<差異位置インデックス取得処理の動作例>
図8は、本実施の形態に係る差異位置インデックス取得処理の動作例を示している。図8は、図6のS220の差異位置インデックス取得処理の動作例である。差異位置インデックス取得処理では、直列文字列と入力文字列、または、リーフの文字列と入力文字列を比較して、2つの文字列の違いをチェックし、差異のあるインデックス位置を取得する。図8の例では、比較対象文字数は16(SIMD128bitサイズ)である。なお、この例(図9から図11を含む)では、X86アーキテクチャのSIMD命令を例に、SIMDのデータサイズは128bit(16Byte)としているが、これに限らず、256bit(32Byte)やそれ以上のSIMD命令を使うことで、更に広いデータ幅に対して同様の処理を行ってもよい。
【0132】
図8に示すように、比較する2つの文字列が、16バイトのSIMDレジスタSrc1及びSrc2にそれぞれ格納されている。差異位置インデックス取得処理では、まず、文字列比較部132は、SIMD命令を使用して、Src1とSrc2を比較する(S401)。具体的には、「C=_mm_cmpeq_epi8(Src1,Src2)」を実行し、Src1とSrc2に対し、SIMDバイト単位同値比較を行って、比較結果を16バイトの変数Cにセットする。_mm_cmpeq_epi8では、16バイトのデータをまとめて1度にバイト単位比較を行い、同じ値のバイトには“FF”、異なる値のバイトには“00”がセットされる。この例では、Src1及びSrc2の6バイト目の文字と11バイト目の文字が異なるため、変数Cの6バイト目と11バイト目が“00”となり、その他の各バイトが“FF”となる。
【0133】
続いて、文字列比較部132は、SIMD命令を使用して、比較結果がセットされた変数Cのビットを集約する(S402)。具体的には、「D=_mm_movemask_epi8(C)」を実行し、16バイトの変数Cに対し、各バイトの最上位ビットを集約してint16型(符号付き16ビット整数型)の変数Dにセットする。_mm_movemask_epi8では、16バイトのデータをアセンブラの一つの命令のみで集約し、16ビットに変換する。この例では、変数Dの6ビット目と11ビット目が“0”となり、その他の各ビットが“1”となる。
【0134】
続いて、文字列比較部132は、比較結果を集約した変数Dの全ビットを反転する(S403)。具体的には、「E=~D」を実行し、変数Dの全ビット反転した結果を、int16型の変数Eにセットする。この例では、変数Eの6ビット目と11ビット目が“1”となり、その他の各ビットが“0”となる。
【0135】
続いて、文字列比較部132は、全ビット判定した変数Eをもとに、Src1とSrc2に違いが見つかったか否かを判定する(S404)。具体的には、「if(E!=0)」を実行し、変数Eが0以外か否か判定する。この例では、変数Eが0以外であるため、違いが見つかったと判定される。
【0136】
続いて、文字列比較部132は、Src1とSrc2に違いが見つかったと判定された場合、変数Eから差異のある最初のインデックス位置を取得する(S405)。具体的には、「diff_idx=_BitScanForward(E)」を実行し、変数Eから先頭のONビット位置を取得し、取得したビット位置を変数diff_idxにセットし、差異のあるインデックス位置を特定する。この例では、差異のあるインデックス位置は、“6”となる。最初の差異位置が求まったため、文字列の辞書順でのキーの大小結果は、この差異位置[6]の1バイトを符号なし数値として比較することで得られる。なお、_BitScanForward()は、コンパイルの結果CPUの持つアセンブラ命令である、ビット位置インデックス取得命令(BSFやCLZ)にインラインで直接展開されるため、関数コールなどのオーバーヘッドなしに高速に実行される(_BitScanReverse()も同様)。
【0137】
<一致位置インデックス取得処理の動作例>
図9は、本実施の形態に係る一致位置インデックス取得処理の動作例を示している。図9は、図7のS302、S309の一致位置インデックス取得処理の動作例である。一致位置インデックス取得処理では、ノード200のブランチバイト列206、または、ブランチバイト列206の検索区間の中から比較バイトと同じバイト値のものがあるかチェックし、一致位置を示すインデックスを取得する。
【0138】
図9の例では、検索文字(比較バイト)は“E”であり、各バイトの値はASCII表記で表され、検索対象文字数は7文字であり、“?”は不定値を示し、ブランチバイト列アロケートサイズは8である。
【0139】
図9に示すように、検索対象(ブランチバイト列、または、ブランチバイト列の検索区間)の文字列が、16バイトのSIMDレジスタSrc1に格納されている。この例では、ブランチバイト列のアロケートサイズが8バイトであり(図9(a))、Scr1の0バイト目から6バイト目にブランチ文字が格納されている。残りの7バイト目から15バイト目までの値は不定となる。例えば、残りのバイトには、後述のように、遷移先情報が格納される(図9(b))。
【0140】
一致位置インデックス取得処理では、まず、ブランチ比較部133は、SIMD命令を使用して、検索文字(比較バイト)を展開した文字列を生成する(S501)。具体的には、「A=_mm_set1_epi8('E')」を実行し、検索文字“E”を16バイトの変数Aの全バイトに展開する。
【0141】
続いて、ブランチ比較部133は、図8のS401と同様、SIMD命令を使用して、検索対象のSrc1と検索文字の変数Aを比較する(S502)。具体的には、「C=_mm_cmpeq_epi8(Src1,A)」を実行し、Src1とAに対し、SIMDバイト単位同値比較を行って、比較結果を16バイトの変数Cにセットする。この例では、Src1の4バイト目が検索文字“E”であるため、変数Cの0バイト目から3バイト目が“00”、4バイト目が“FF”、5バイト目から6バイト目が“00”、7バイト目~15バイト目が不定となる。
【0142】
続いて、ブランチ比較部133は、図8のS402と同様、SIMD命令を使用して、比較結果がセットされた変数Cのビットを集約する(S503)。具体的には、「D=_mm_movemask_epi8(C)」を実行し、16バイトの変数Cに対し、各バイトの最上位ビット集約を行って、集約したビットをint16型の変数Dにセットする。
この例では、変数Dの0ビット目から3ビット目が“0”、4ビット目が“1”、5ビット目から6ビット目が“0”、7ビット目から15ビット目が不定となる。
【0143】
続いて、ブランチ比較部133は、比較結果を集約した変数Dの不定ビットをクリアする(S504)。例えば、図9に示すように、有効文字数に合わせたマスクとして、mask[0]~[16]を用意しておく。そして、「E=D&mask[有効文字数]」を実行し、変数Dに対し有効文字数に合わせたマスクをかけて、有効文字数以外のビットをクリアした結果を、変数Eにセットする。この例では、検索対象文字数は7文字であるため、0ビット目から6ビット目までのビットが“1”のmask[7]を使用して、7ビット目から15ビット目の不定ビットを“0”にクリアする。
【0144】
続いて、ブランチ比較部133は、図8のS404と同様、不定ビットをクリアした変数Eから、検索文字が見つかったか否か判定する(S505)。具体的には、「if(E!=0)」を実行し、変数Eが0以外か否か判定する。この例では、変数Eが0以外であるため、検索文字が見つかったと判定される。
【0145】
続いて、ブランチ比較部133は、検索文字が見つかったと判定された場合、図8のS405と同様、変数Eから検索文字のあるインデックス位置を取得する(S506)。具体的には、「match_idx=_BitScanForward(E)」を実行し、変数Eから先頭のONビット位置を取得し、取得したビット位置を変数match_idxにセットし、検索文字と同値のインデックス位置を特定する。この例では、検索文字のあるインデックス位置は、“4”となる。
【0146】
<検索区間インデックス取得処理の動作例>
図10A及び図10Bは、本実施の形態に係る検索区間インデックス取得処理の動作例を示している。図10A及び図10Bは、図7のS307の検索区間インデックス取得処理の動作例である。
【0147】
ブランチバイトの数は最大で256個になるため、16バイトを超えるブランチサイズの場合は、最初に検索区間インデックス取得処理を行う。検索区間インデックス取得処理では、16より大きいサイズのブランチバイト列206の中から、検索区間を取得する。その結果を使ってさらに、上記の一致位置インデックス取得を行うことで、最終的な一致位置を確定する。
【0148】
図10A及び図10Bの例では、検索文字は、0x6d(ASCII“m”)であり、各バイトの値はHex表記で表され、検索対象文字数は71であり、“?”は不定値を示す。
【0149】
図10Aに示すように、検索対象(ブランチバイト列)の文字列が80バイト([0]~[79])であり、この文字列を16バイト毎に5つのセグメントに分割する。セグメント[0]は、0バイト目から15バイト目の文字列、セグメント[1]は、16バイト目から31バイト目の文字列、セグメント[2]は、32バイト目から47バイト目の文字列、セグメント[3]は、48バイト目から63バイト目の文字列、セグメント[4]は、64バイト目から79バイト目の文字列となる。また、71バイト目から79バイト目の値は不定となる。
【0150】
検索区間インデックス取得処理では、まず、ブランチ比較部133は、各セグメントの先頭バイトの文字を取得する(S601)。具体的には、「A=_mm_setr_epi8(16の倍数位置のバイト)」を実行し、検索対象からSIMDの処理幅毎に先頭バイトを検索対象文字数までロードし、16バイトの変数Aにセットする。この例では、変数Aの0バイト目に、検索対象の0バイト目の文字がセットされ、変数Aの1バイト目に、検索対象の16バイト目の文字がセットされ、変数Aの2バイト目に、検索対象の32バイト目の文字がセットされ、変数Aの3バイト目に、検索対象の48バイト目の文字がセットされ、変数Aの4バイト目に、検索対象の64バイト目の文字がセットされる。変数Aの5バイト目から15バイト目は不定となる。
【0151】
続いて、ブランチ比較部133は、変数Aを符号あり演算用に変換する(S602)。例えば、全バイトに“80”がセットされた16バイトの変数Nを使用する。具体的には、「A=_mm_xor_si128(A,N)」を実行し、変数Aの各バイトの0~255の値を-128~+127の値に変換する。なお、X86CPUのSIMD整数比較は、符号ありの大なり(gt)比較にのみ対応しているため、符号あり数値への変換を行うが、処理系が異なり、符号なし数値のままSIMD比較できる場合は、変換を行わず、符号なし数値のまま比較を行ってもよい。
【0152】
続いて、ブランチ比較部133は、SIMD命令を使用して、変換された変数Aをバイト単位に符号ありで大なり比較する(S603)。例えば、全バイトに検索文字0x6dをS602と同じ手法で符号あり演算用に変換した“ed”(-19)がセットされた16バイトの変数Bを使用する。具体的には、「C=_mm_cmpgt_epi8(A,B)」を実行し、変数A及びBに対し、SIMDバイト単位符号あり比較を行って、比較結果を16バイトの変数Cにセットする。この例では、変数Aの4バイト目が“f7”(-9)で“ed”(-19)よりも大きいため、0バイト目から3バイト目が“00”、4バイト目が“FF”、5バイト目から15バイト目が不定となる。
【0153】
続いて、ブランチ比較部133は、図8のS402と同様、SIMD命令を使用して、比較結果がセットされた変数Cのビットを集約する(S604)。具体的には、「D=_mm_movemask_epi8(C)」を実行し、16バイトの変数Cに対し、各バイトの最上位ビット集約を行って、集約したビットをint16型の変数Dにセットする。この例では、変数Dの0ビット目から3ビット目が“0”、4ビット目が“1”、5ビット目から15ビット目が不定となる。
【0154】
続いて、ブランチ比較部133は、図8のS403と同様、比較結果を集約した変数Dの全ビットを反転する(S605)。具体的には、「E=~D」を実行し、変数Dの全ビット反転した結果を、int16型の変数Eにセットする。この全ビット反転操作により、大なり比較(gt)の結果を小なりイコール比較(le)の結果に変換する。この例では、変数Eの0ビット目から3ビット目が“1”、4ビット目が“0”、5ビット目から15ビット目が不定となる。
【0155】
続いて、ブランチ比較部133は、検索文字数を元に、図9と同様にマスクを使用して、変数Dの不定ビットをクリアする(S606)。具体的には、「F=E&mask[((71-1)>>4)+1]」を実行し、不定ビットをクリアした結果を変数Fにセットする。検索文字数70から1引いた値を4ビット右にシフトし、シフトした結果に1を加えた値は5となる。従って、0ビット目から4ビット目までの5ビットが“1”の、mask[5]を使用して、5ビット目から15ビット目の不定ビットを“0”にクリアする。
【0156】
続いて、ブランチ比較部133は、図8のS404と同様、不定ビットをクリアした変数Fから、検索区間が見つかったか否か判定する(S607)。具体的には、「if(F!=0)」を実行し、変数Fが0以外か否か判定する。この例では、変数Fが0以外であるため、検索区間が見つかったと判定される。
【0157】
続いて、ブランチ比較部133は、変数Fから検索範囲を特定するインデックス位置を取得する(S608)。具体的には、「segment_idx=_BitScanReverse(F)」を実行し、変数Fから最後尾のONビット位置を取得し、取得した位置である3を変数segment_idxにセットし、検索範囲を特定する。この結果、セグメント[3](48バイト目から63バイト目)が最終的に特定された検索範囲となる。この後、求めた検索範囲[3]のセグメントを使って、上記の一致位置インデックス取得を実行することで、最終インデックス位置の54を確定する。
【0158】
なお、S601のSIMDの処理幅毎に先頭バイトを集める処理は、比較的広範囲のメモリを散発的にアクセスするため、キャッシュ効率の低下を招く。このため、これらの各バイトを事前に集め、ブランチバイト列の先頭16バイトに格納することで、範囲検索用のインデックス(スーパーインデックス)を配置してもよい。
<バイト最上位ビット集約処理の動作例>
【0159】
図11は、本実施の形態に係るバイト最上位ビット集約のエミュレーションの例を示している。図11は、図8のS402、図9のS503、図10BのS604のバイト最上位ビット集約(_mm_movemask_epi8(a))のエミュレーションの例である。バイト最上位ビット集約命令はX86系以外のCPUでは利用できないため、図11に示すように、同等な機能をエミュレーションする。図11は、水平加算を使ったArmCPUにおける例である。例えば、文字列比較部132またはブランチ比較部133に含まれるエミュレータが図11の動作を実行する。
【0160】
図11の例では、集約対象を16バイトの変数aとする。変数aの各バイトには、上記のように、比較結果の0xFFまたは0x00がセットされている。この例では、6バイト目と11バイト目が00、その他の各バイトがFFである。
【0161】
図11に示すように、まず、エミュレータは、集約対象の変数aから、ビットマスクを使用してビットを抽出する(S701)。例えば、0x01、0x02、0x04、0x08、0x10、0x20、0x40、0x80と、バイトごとに、1ビットずつ左にシフトした値を持つビットマスクMを使用する。具体的には、「B=vandq_u8(a,M)」を実行し、変数aとビットマスクMとのANDを取ってビットを抽出し、抽出した結果を16バイトの変数Bにセットする。この例では、変数Bの6バイト目と11バイト目が0となり、その他の各バイトがビットマスクMの値となる。
【0162】
続いて、エミュレータは、変数Bを2つに分割し、分割した8バイトのデータを8ビットのデータに変換する(S702)。例えば、変数Bを0バイト目から7バイト目と、8バイト目から15バイト目の2つ(上下)に分けて水平加算する。具体的には、「CL=vaddv_u8(vget_Low_u8(B))」を実行し、変数Bの0バイト目から7バイト目の各バイトを水平加算し、水平加算した結果を8ビットの変数CLにセットする。この例では、変数CLの6ビット目が0、その他のビットが1となる。同様に「CH=vaddv_u8(vget_high_u8(B))」を実行し、変数Bの8バイト目から15バイト目の各バイトを水平加算し、水平加算した結果を8ビットの変数CHにセットする。この例では、変数CHの3ビット目が0、その他のビットが1となる。
【0163】
続いて、エミュレータは、変換した2つの8ビットのデータを結合する(S703)。具体的には、「Res=CL | (CH<<8)」を実行して、変数CLと、変数CHを8ビット左にシフトした値とを結合(上下を結合)し、結合した結果を変数Resにセットし、集約完了する。この例では、6ビット目と11ビット目が0、その他の各ビットが0となる。
【0164】
<ノードデータのメモリ配置例>
図12は、本実施の形態に係るノード200のデータのメモリ配置例を示している。図12に示すように、ノード200の各要素は、実体フラグ203、ブランチ位置204、直列文字列205、ブランチバイト列206、遷移先情報207の順にメモリに配置される。すなわち、ブランチバイト列206の後に連続して遷移先情報207が格納される。本実施の形態では、実体フラグ203、ブランチ位置204、直列文字列205に対して、通常の命令を使用して参照し、次に、ブランチバイト列206に対して、SIMD命令を使用して参照し、次に、遷移先情報207に対して、通常命令を使用して参照する。
【0165】
ブランチバイト列は1バイトから最大で256バイトまで可変のサイズを取る。一方SIMDによる処理は、SIMDのサイズ(128bit=16Byte、256bit=32Byte)に従った連続するメモリアドレスに対して行われる。このため、一般にはSIMDのサイズに満たないデータを扱う場合、データの後ろ側にメモリ参照違反を避けるために緩衝用のメモリエリアを設ける。しかしながら、この方法では、ブランチバイトが少ない場合に、緩衝用のメモリのための無駄が増え、特に近年のキャッシュの効果が大きいCPUでは性能劣化を同時に招くことに成る。このため、本実施形態ではブランチバイト列(図9(a))の直後に遷移先情報(図9(b))を詰めて配置することで、アロケート数が4や8のようなノードの場合でも緩衝用のメモリの確保によるメモリ使用効率の低下を起こさないようにするとともに、ブランチバイトのアクセス直後に使う遷移先情報が、事前にキャッシュに読み込まれる確率を上げている。
【0166】
<効果>
以上のように、本実施の形態では、マルチノードツリーのノード情報は、文字列情報の参照による直列文字列と、それに続く、次の1バイトの値を示すブランチバイトのバイト列と、そのブランチバイトに対応した遷移先情報を一組として格納する。更に、ノード情報にはこの情報を補完する情報として、直列文字列の指す文字列が、文字列の実体であることを示す実体フラグと、文字列のどの位置のバイトとブランチバイトを照合するかを示す、ブランチ位置の情報を持つ。
【0167】
本実施の形態では、直列文字列とブランチバイトの対を持つノードと、文字列情報であるリーフをマルチノードのツリーとして構成し、更に、直列文字列とブランチバイトの双方の操作に並列比較(SIMD命令)を組み合わせることで、可変長の文字列を効率よく検索することができる。
【0168】
本実施の形態では、完全一致検索を行う際、入力文字列に対し、直列文字列比較、ブランチバイト列比較の2つの比較操作を使いながら、ノードを上位からたどることで、検索を行っていく。文字列は“株式会社”や“Corporation”、更には“Carifornia”などの特定の単語や地名などの結合と組み合わせで構成されることが多いため、同一の文字列が長く出現するような状態では、内部でSIMDによる広範囲比較を行う、直列文字列比較の効果が大きくなる。同様に、文字列自体の長さが100バイトや1000バイトを超えるようなケースでもSIMDを使った広範囲比較により、比較回数の削減効果を期待できる。また、上記の例では説明を簡潔にするため、ブランチバイトの数を数個としているが、この部分は最大の場合、256個に成るため、個数が多くなると、ブランチバイト列比較の内部におけるSIMDを使った並列比較操作とインデクス変換の効果が大きくなる。
【0169】
また、近年のCPUは命令を複数段に分けて順次実行するパイプライン動作を行うことで、命令の処理時間の短縮を図っている。しかしながら、このパイプライン動作は条件分岐を行うことで乱れが生じ、処理効率が低下する。このため、本実施の形態では、直列文字列比較及びブランチバイト列比較で、差異位置インデックス取得、一致位置インデックス取得、及び検索区間インデックス取得を行う際に、SIMD命令を使用するとともに、各々の処理シーケンスの中で条件分岐は各一回しか使わない(図8図9図10Bのif文)。これにより、条件分岐を行うことによる、CPU内部のパイプラインの乱れを抑え、効率的な処理を行える。
【0170】
更に近年のCPUでは、その動作速度が、一般的に主記憶に使われるDRAMのメモリアクセス速度に足を引っ張られないように、比較的大きなキャッシュメモリを持っている。本実施の形態では、ノードにおけるブランチバイト列の後にブランチに対応するノード/リーフの遷移先情報を格納することで、ブランチの数がSIMDの基本サイズである128bitや256bitのサイズに満たない場合にSIMDによるメモリ参照違反を起こさず、メモリ利用効率を上げるともに、次にアクセスする遷移先情報を同時にキャッシュに読み込むことで、キャッシュヒット率を上げ処理の効率化を図っている。
なお、同じ値が登録済みかを調べる検索処理については、検索ノードのツリーを下降する際の直列文字列の比較にかかわる処理(S105~S106)を省略し、最終のリーフ文字列との同一チェック(S130)ならびに、直列文字列の同一チェック(S150)の際に該当文字列と入力文字列の全体が一致するかを判定してもよい。ただし、以降で説明する(実施の形態3)の登録処理においては、この省略はできない。
【0171】
(実施の形態2)
次に、実施の形態2について説明する。本実施の形態では、実施の形態1で示した検索装置100において、前方一致検索を行う例について説明する。検索装置100の構成は、実施の形態1と同様である。
【0172】
<前方一致検索の動作例>
図13A及び図13Bは、本実施の形態に係る検索装置100における前方一致検索処理の動作例を示している。図13A及び図13Bの前方一致検索処理では、図4A及び図4Bの完全一致検索処理に対して、S131、S150、S151の処理が異なる。
【0173】
完全一致検索の場合、入力文字列とリーフ文字列の比較結果を判定するS131で、入力文字列とリーフ文字列における内容及び長さが同一の場合に検索成功と判定する。これに対し、前方一致検索の場合、S131aで、入力文字列の長さ分の文字がリーフ文字列と同じであるか否か判定し、入力文字列の長さ分の文字がリーフ文字列と同じであれば、以降の文字列の内容は問わずに検索成功と判定する。なお、S132では、リーフで一致となるため、文字列1件のみが返却される。
【0174】
また、完全一致検索の場合、ノードの途中でループを外れるS150、S151では、当該ノードの直列文字列のみが検索結果となる。これに対し、前方一致検索の場合、S150a、S151aでは、該当ノードの下位にある複数のリーフ文字列すべてが検索結果に該当する。このため、S150aで、反復取得(イテレータ)に必要な初期化を行う。具体的には、スタックレベルに0をセットし、スタック[0].ノードにカレントノードをセットし、スタック[0].ブランチ番号に-1をセットする。続いて、S151aで反復取得(イテレータ)に向けた情報をリターンする。
【0175】
<前方一致検索処理の具体例>
図14を用いて、図13A及び図13Bの前方一致検索処理の具体例について説明する。図14の例では、図5と同様、文字列300-1~300-8が、ノード200-1~200-4を含むデータツリー111に登録されている。この例では、図14のデータツリー111から前方一致検索で入力文字列“DG”(2文字)を検索する場合の動作について説明する。
【0176】
(1)初回ループ
検索制御部131は、最初にデータツリー111のデータ登録を確認し(S101)、図14のようにデータが登録されているため、初期化に進む。初期化では、検索制御部131は、バイトチェック位置に0をセットし、カレントノードにルートノードをセットする(S102)。この場合、カレントノードは、最上位のノード200-1を指すようになる。
【0177】
続いて、1回目のループとして、検索制御部131は、カレントノードであるノード200-1が文字列(リーフ)か否かチェックし(S103)、文字列ではないため、ループ処理を続行する。
【0178】
続いて、検索制御部131は、比較サイズを計算する(S104)。この場合、比較サイズは、カレントノードであるノード200-1のブランチ位置204=1と入力文字列“DG”の文字列長+1=3の小さい方の値である1から、バイトチェック位置である0を減算し、結果は1となる。
【0179】
続いて、文字列比較部132は、直列文字列比較を行う(S105)。この場合、直列文字列比較では、カレントノードであるノード200-1の直列文字列205の指す文字列“DBXPN”と入力文字列“DG”とを使い、バイトチェック位置である0バイト目から比較サイズである1バイト分の文字が同一か否かをチェックする。直列文字列比較の結果、2つの文字列の0バイト目はいずれも“D”であり、文字列に差異はないため(S106)、検索制御部131は、ループ処理を続行する。
【0180】
続いて、検索制御部131は、バイトチェック位置にカレントノードであるノード200-1のブランチ位置204である1をセットする(S107)。
【0181】
続いて、検索制御部131は、バイトチェック位置である1が入力文字列長である2以上、つまり入力文字チェックが完了したか否かをチェックし(S108)、バイトチェック位置が入力文字列長を超えていないため、ループ処理を続行する。
【0182】
続いて、ブランチ比較部133は、ブランチバイト列比較を行う(S109)。この場合、ブランチバイト列比較では、カレントノードであるノード200-1のブランチバイト列206=(“B”,“G”,“R”)の中に、入力文字列“DG”のバイトチェック位置=1の文字である“G”と同じ値があるか否かをチェックする。ブランチバイト列比較の結果、ノード200-1のブランチバイト列206のインデックス1番目に同じ値があるため(S110)、検索制御部131は、ループ処理を続行する。
【0183】
続いて、検索制御部131は、バイトチェック位置である1に、1を加えて2とし、カレントノードに、一致したブランチバイト列206のインデックス1番目=“G”に対応する遷移先情報207をセットする(S111)。この場合、カレントノードは、上位から2番目のノード200-2を指すようになる。
【0184】
(2)2回目ループ
2回目のループでも同様に、検索制御部131は、カレントノードであるノード200-2が文字列(リーフ)でないため(S103)、比較サイズを計算する(S104)。この場合、比較サイズは、カレントノードであるノード200-2のブランチ位置204=2と入力文字列“DG”の文字列長+1=3の小さい方の値である2から、バイトチェック位置である2を減算し、結果は0となる。
【0185】
続いて、文字列比較部132は、直列文字列比較を行う(S105)。この場合、直列文字列比較では、カレントノードであるノード200-2の直列文字列205の指す文字列“DG”と入力文字列“DG”とを比較し、バイトチェック位置である2バイト目から比較サイズである0バイト分の文字が同一か否かをチェックする。直列文字列比較の結果、比較サイズが0のため差は検出されず(S106)、検索制御部131は、ループ処理を続行する。
【0186】
続いて、検索制御部131は、バイトチェック位置にカレントノードであるノード200-2のブランチ位置204である2をセットする(S107)。
【0187】
続いて、検索制御部131は、バイトチェック位置である2が入力文字列長である2以上、つまり入力文字チェックが完了したかどうかをチェックし(S108)、バイトチェック位置が入力文字列長以上となったため、ループを脱出する。
【0188】
(3)ループ終了
S108でループを抜けた場合、リーフでない位置で検索処理が終了することになる。この場合、検索制御部131は、次に説明する反復取得(イテレータ)に向けた情報をリターンし、その後、改めて反復取得(イテレータ)を使うことで、ノード以下の複数のリーフ文字列を順次出力する。具体的には、反復取得(イテレータ)用に、スタックレベルを0に初期化し、先頭のスタックのノードに現在のノード(上位から2番目のノード200-2)をセットし、ブランチ番号に-1をセットする(S150a)。続いて、検索制御部131は、反復取得(イテレータ)に向けた情報を返却する(S151a)。
【0189】
<反復取得処理の動作例>
図15A及び図15Bは、本実施の形態に係る反復取得処理の動作例を示している。図15A及び図15Bは、図13BのS151aで返却された反復取得(イテレータ)情報を利用した、反復出力処理の動作例である。
【0190】
反復取得を昇順に行う場合(イテレータ)、登録済みデータを、特定の文字列から反復取得し、結果は、文字列の辞書順に得られる。昇順の場合、ノード内を、直列文字列(実体)、ブランチリーフ(小さいほうから)の順に取得し、ブランチがノードを指している場合は、そのノードに移り同様の手順を繰り返す。
【0191】
反復取得を降順に行う場合、昇順の動作から、取得方向を逆順にして処理する。降順の場合、ノード内を、ブランチリーフ(大きいほうから)、直列文字列(実体)の順に取得し、ブランチがノードを指している場合は、そのノードに移り同様の手順を繰り返す。
【0192】
反復取得の処理を、ソート、範囲検索へ応用してもよい。反復取得は指定のノードから、順番にリーフノードを返却できるため、最上位のノードを対象にすることで、登録データ全体を昇順(降順)に取得できる。これは登録データを辞書順にソートした結果と同様になる。また、検索などの手段により、任意のノードを開始位置として反復取得を行うことで昇順(降順)の範囲検索や指定個数のデータ取得にも応用できる。
【0193】
図15A及び図15Bは、反復取得を昇順に行う場合の動作例である。図15A及び図15Bに示すように、検索制御部131は、出力リストをクリアする(S801)。続いて、検索制御部131は、出力リストに空きがあり、かつ、スタックレベルが0以上であるか否か判定する(S802)。S820において、出力リストに空きがない、または、スタックレベルが0より小さいと判定された場合、検索制御部131は、現在の結果リストをリターンし(S820)、処理を終了する。
【0194】
S820において、出力リストに空きがあり、かつ、スタックレベルが0以上であると判定された場合、検索制御部131は、カレントノードにスタック[スタックレベル].ノードをセットし、カレントブランチにスタック[スタックレベル].ブランチ番号をセットする(S803)。
【0195】
続いて、検索制御部131は、カレントブランチがカレントノードのブランチサイズ201以上か、すなわち、全ブランチ処理済みか否か判定する(S804)。S804において、カレントブランチがカレントノードのブランチサイズ201以上であると判定された場合、検索制御部131は、スタックレベルをデクリメントし(S810)、S802以降の処理を繰り返す。
【0196】
S804において、カレントブランチがカレントノードのブランチサイズ201より小さいと判定された場合、検索制御部131は、スタック[スタックレベル].ブランチ番号をインクリメントする(S805)。
【0197】
続いて、検索制御部131は、カレントブランチが-1であるか否か、すなわち直列文字列位置であるかチェックする(S806)。S806において、カレントブランチが-1であると判定された場合、検索制御部131は、カレントノードの直列文字列が実体か否か判定する(S821)。
【0198】
S821において、カレントノードの直列文字列が実体ではないと判定された場合、検索制御部131は、S802以降を繰り返す。S821において、カレントノードの直列文字列が実体であると判定された場合、出力リストにカレントノードの直列文字列を追加し(S822)、S802以降を繰り返す。
【0199】
S806において、カレントブランチが-1ではないと判定された場合、検索制御部131は、カレントブランチが指すのがノードか否か判定する(S807)。S807において、カレントブランチが指すのはノードではないと判定された場合、検索制御部131は、出力リストにカレントブランチに対応するリーフの文字列を追加し(S823)、S802以降を繰り返す。
【0200】
S807において、カレントブランチが指すのはノードであると判定された場合、検索制御部131は、スタックレベルをインクリメントする(S808)。続いて、検索制御部131は、スタック[スタックレベル].ノードにカレントブランチが指すノードをセットし、スタック[スタックレベル].ブランチ番号に-1をセットし(S809)、S802以降の処理を繰り返す。
【0201】
<反復取得処理の具体例>
図16を用いて、図15A及び図15Bの反復取得処理の具体例について説明する。図16の例では、図14と同様、文字列300-1~300-8が、ノード200-1~200-4を含むデータツリー111に登録されている。この例では、図14と同様にデータツリー111から前方一致検索で入力文字列“DG”(2文字)を検索し、出力リスト格納容量3個で“DG”より下の集合を取得(昇順)する場合の動作について説明する。
【0202】
なお、図14で説明したように、反復取得処理の前に、前方一致検索のS150aで、スタックレベルに0をセットし、スタック[0].ノードにカレントノード(ノード200-2)をセットし、スタック[0].ブランチ番号に-1がセットされている。
【0203】
(1)初回ループ
検索制御部131は、最初に出力リストをクリアして初期化する(S801)。続いて、1回目のループとして、検索制御部131は、出力リストの空き及びスタックレベルをチェックし(S802)、出力リストに空きがあり、かつ、スタックレベルが0であるため、処理を続行する。
【0204】
続いて、検索制御部131は、前方一致検索のS150aで初期セットされた、スタックレベル=0のスタック[0]から、ノード(ノード200-2)とブランチ番号=-1を取り出し、カレントノードとカレントブランチにセットする(S803)。
【0205】
続いて、検索制御部131は、カレントブランチとカレントノードのブランチサイズ201を比較し(S804)、カレントブランチ=-1はカレントノードのブランチサイズ201=3より小さいため、そのまま処理を続行する。続いて、検索制御部131は、スタックレベル=0のスタック[0]のブランチ番号である-1をインクリメントし、0にする(S805)。
【0206】
続いて、検索制御部131は、カレントブランチが-1であるか否かをチェックする(S806)。この場合、カレントブランチが-1であるため、検索制御部131は、カレントノード(ノード200-2)の直列文字列205=“DG”が実体か否かチェックする(S821)。そして、カレントノードの直列文字列205は実体であるため、検索制御部131は、カレントノードの直列文字列205=“DG”(文字列300-2)を出力リストに追加し(S822)、次のループに移る。
【0207】
(2)2回目ループ
2回目のループとして、検索制御部131は、出力リストの空き及びスタックレベルをチェックし(S802)、出力リストの格納数はまだ1であり、格納容量=3より小さく、かつ、スタックレベルが0であるため、処理を続行する。
【0208】
続いて、検索制御部131は、スタックレベル=0のスタック[0]からノード(ノード200-2)とブランチ番号=0を取り出し、カレントノードとカレントブランチにセットする(S803)。
【0209】
続いて、検索制御部131は、カレントブランチとカレントノードのブランチサイズ201を比較し(S804)、カレントブランチは0であり、カレントノードのブランチサイズ201=3より小さいため、そのまま処理を続行する。続いて、検索制御部131は、スタックレベル=0のスタック[0]のブランチ番号である0をインクリメントし、1にする(S805)。
【0210】
続いて、検索制御部131は、カレントブランチが-1であるか否かチェックし(S806)、カレントブランチは0であり、-1と異なるため、そのまま処理を継続する。続いて、検索制御部131は、カレントブランチが指すのがノードか否かチェックし(S807)、カレントブランチの0が指すのは、ノードのため、処理を続行する。
【0211】
続いて、検索制御部131は、スタックレベルである0をインクリメントして、1にする(S808)。続いて、検索制御部131は、スタックレベル=1のスタック[1]に対し、ノードとして、カレントブランチの0に対応する遷移先のノード情報(ノード200-3)をセットし、ブランチ番号として-1をセットして(S809)、次のループに移る。
【0212】
(3)3回目ループ
以降では、前記と同様な動作を行う部分が多いため、記述を少々簡略化する。なお、動作は検索制御部131において行われる。
3回目のループとして、出力リストの格納数がまだ1で、格納可能数=3より小さく、かつ、スタックレベルが1であるため、処理を続行する(S802)。
【0213】
続いて、スタックレベル=1のスタック[1]からノード(ノード200-3)とブランチ番号=-1を取り出し、カレントノードとカレントブランチにセットする(S803)。
【0214】
続いて、カレントブランチが-1であり、カレントノードのブランチサイズ201=1より小さいため、そのまま処理を続行し(S804)、続いて、スタックレベル=1のスタック[1]のブランチ番号である-1をインクリメントし、0にする(S805)。
【0215】
続いて、カレントブランチが-1であるかチェックし(S806)、カレントブランチが-1であるため、続いてカレントノード(ノード200-3)の直列文字列205=“DGHKP”が実体か否かチェックする(S821)。その結果、カレントノードの直列文字列205は実体であるため、カレントノードの直列文字列205=“DGHKP”(文字列300-3)を出力リストに追加し(S822)、次のループに移る。
【0216】
(4)4回目ループ
4回目のループとして、出力リストの格納数はまだ2であり、格納可能数=3より小さく、かつ、スタックレベルが1であるため、処理を続行する(S802)。
【0217】
続いて、スタックレベル=1のスタック[1]からノード(ノード200-3)とブランチ番号=0を取り出し、カレントノードとカレントブランチにセットする(S803)。
【0218】
続いて、カレントブランチとカレントノードのブランチサイズ201を比較し(S804)、カレントブランチは0であり、カレントノードのブランチサイズ201=1より小さいため、そのまま処理を続行する。続いて、スタックレベル=1のスタック[1]のブランチ番号である0をインクリメントし、1にする(S805)。
【0219】
続いて、カレントブランチが-1であるか否かをチェックし(S806)、カレントブランチは0であり、-1と異なるため、そのまま処理を継続する。続いて、カレントブランチが指すのがノードか否かチェックし(S807)、カレントブランチの0が指すのは、ノードではなく、文字列のため、カレントブランチの0に対応するリーフの文字列“DGHKPS”(文字列300-4)を出力リストに追加し(S823)、次のループに移る。
【0220】
(5)5回目ループ
5回目のループとして、出力リストの空き及びスタックレベルをチェックし(S802)、出力リストの格納数が3であり、格納可能数に達したため、ループを脱出し、現在の出力リストの内容(“DG”,“DGHKP”,“DGHKPS”の3要素)を返却し(S820)、処理を終了する。
【0221】
(6)6回目ループ
データ取得の継続として、再度、反復取得がコールされる。すると、検索制御部131は、最初に出力リストをクリアして初期化する(S801)。
【0222】
続いて、6回目のループとして、出力リストの空き及びスタックレベルをチェックし(S802)、出力リストに空きがあり、かつ、スタックレベルが1であるため、処理を続行する。
【0223】
続いて、スタックレベル=1のスタック[1]からノード(ノード200-3)とブランチ番号=1を取り出し、カレントノードとカレントブランチにセットする(S803)。
【0224】
続いて、カレントブランチとカレントノードのブランチサイズ201を比較し(S804)、カレントブランチは1であり、カレントノードのブランチサイズ201=1と同じであるため、カレントノードの処理が終了したことになり、検索制御部131は、スタックレベルの1をデクリメントして、0とし(S810)、次のループに移る。
【0225】
(7)7回目ループ
7回目のループとして、出力リストの格納数はまだ0であり、格納可能数=3より小さく、かつ、スタックレベルが0であるため、処理を続行する(S802)。
【0226】
続いて、スタックレベル=0のスタック[0]からノード(上位から2番目のノード200-2)とブランチ番号=1を取り出し、カレントノードとカレントブランチにセットする(S803)。
【0227】
続いて、カレントブランチとカレントノードのブランチサイズ201を比較し(S804)、カレントブランチは1であり、カレントノードのブランチサイズ201=3より小さいため、そのまま処理を続行する。続いて、スタックレベル=0のスタック[0]のブランチ番号である1をインクリメントし、2にする(S805)。
【0228】
続いて、カレントブランチが-1であるか否かチェックし、(S806)、カレントブランチは1であり、-1と異なるため、そのまま処理を継続する。続いて、カレントブランチが指すのがノードか否かチェックする(S807)。この場合、カレントブランチの1が指すのは、ノードではなく、文字列のため、カレントブランチに対応するリーフの文字列“DGK”(文字列300-5)を出力リストに追加し(S823)、次のループに移る。
【0229】
(8)8回目ループ
8回目のループとして、出力リストの格納数はまだ1であり、格納可能数=3より小さく、かつ、スタックレベルが0であるため、処理を続行する(S802)。
【0230】
続いて、スタックレベル=0のスタック[0]からノード(ノード200-2)とブランチ番号=2を取り出し、カレントノードとカレントブランチにセットする(S803)。
【0231】
続いて、カレントブランチとカレントノードのブランチサイズ201を比較し(S804)、カレントブランチは2であり、カレントノードのブランチサイズ201=3より小さいため、そのまま処理を続行する。続いて、検索制御部131は、スタックレベル=0のスタック[0]のブランチ番号である2をインクリメントし、3にする(S805)。
【0232】
続いて、カレントブランチが-1であるか否かチェックし(S806)、カレントブランチは2であり、-1と異なるため、そのまま処理を継続する。続いて、カレントブランチが指すのがノードか否かチェックし(S807)、カレントブランチの2が指すのは、ノードのため、処理を続行する。
【0233】
続いて、スタックレベルである0をインクリメントして、1にする(S808)。続いて、スタックレベル=1のスタック[1]に対し、ノードとして、カレントブランチの2に対応する遷移先のノード情報(ノード200-4)をセットし、ブランチ番号として-1をセットして(S809)、次のループに移る。
【0234】
(9)9回目ループ
9回目のループとして、出力リストの格納数はまだ1であり、格納可能数=3より小さく、かつ、スタックレベルが1であるため、処理を続行する(S802)。
【0235】
続いて、スタックレベル=1のスタック[1]からノード(ノード200-4)とブランチ番号=-1を取り出し、カレントノードとカレントブランチにセットする(S803)。
【0236】
続いて、カレントブランチとカレントノードのブランチサイズ201を比較し(S804)、カレントブランチは-1であり、カレントノードのブランチサイズ201=2より小さいため、そのまま処理を続行する。続いて、スタックレベル=1のスタック[1]のブランチ番号である-1をインクリメントし、0にする(S805)。
【0237】
続いて、カレントブランチが-1であるか否かチェックし(S806)、カレントブランチが-1であるため、カレントノード(200-4)の直列文字列205=“DGLEBG”が実体か否かチェックする(S821)。この場合、カレントノードの直列文字列205は実体ではないため、文字列を出力リストに追加せず、次のループに移る。
【0238】
(10)10回目ループ
10回目のループとして、出力リストに空きがあり、かつ、スタックレベルが1であるため、処理を続行する(S802)。
【0239】
続いて、スタックレベル=1のスタック[1]からノード(ノード200-4)とブランチ番号=0を取り出し、カレントノードとカレントブランチにセットする(S803)。
【0240】
続いて、カレントブランチとカレントノードのブランチサイズ201を比較し(S804)、カレントブランチは0であり、カレントノードのブランチサイズ201=2より小さいため、そのまま処理を続行する。続いて、スタックレベル1のスタック[1]のブランチ番号である0をインクリメントし、1にする(S805)。
【0241】
続いて、カレントブランチが-1であるか否かをチェックし(S806)、カレントブランチは0であり、-1と異なるため、そのまま処理を継続する。続いて、カレントブランチが指すのがノードか否かチェックする(S807)。この場合、カレントブランチの0が指すのは、ノードではなく、文字列のため、カレントブランチの0に対応するリーフの文字列“DGLEA”(文字列300-6)を出力リストに追加し(S823)、次のループに移る。
【0242】
(11)11回目ループ
11回目のループとして、出力リスト格納数が2で、まだ空きがあり、かつ、スタックレベルが1であるため、処理を続行する(S802)。
【0243】
続いて、スタックレベル=1のスタック[1]からノード(ノード200-4)とブランチ番号=1を取り出し、カレントノードとカレントブランチにセットする(S803)。
【0244】
続いて、カレントブランチとカレントノードのブランチサイズ201を比較し(S804)、カレントブランチは1であり、カレントノードのブランチサイズ201=2より小さいため、そのまま処理を続行する。続いて、スタックレベル=1のスタック[1]のブランチ番号である1をインクリメントし、2にする(S805)。
【0245】
続いて、カレントブランチが-1であるか否かチェックし、(S806)、カレントブランチは1であり、-1と異なるため、そのまま処理を継続する。続いて、カレントブランチが指すのがノードか否かチェックし(S807)、カレントブランチの1が指すのは、ノードではなく、文字列のため、カレントブランチの1に対応するリーフの文字列“DGLEBG”(文字列300-7)を追加し(S823)、次のループに移る。
【0246】
(12)12回目ループ
12回目のループとして、出力リストの空き及びスタックレベルをチェックし(S802)、出力リストの格納数が3であり、格納可能数に達したため、ループを脱出し、現在の出力リストの内容(“DGK”,“DGLEA”,“DGLEBG”の3要素)を返却し(S820)、処理を終了する。
【0247】
(13)13回目ループ
データ取得の継続として、再度、反復取得がコールされる。すると、検索制御部131は、最初に出力リストをクリアして初期化する(S801)。
【0248】
続いて、13回目のループとして、出力リストの空き及びスタックレベルをチェックし(S802)、出力リストに空きがあり、かつ、スタックレベルが1であるため、処理を続行する。
【0249】
続いて、スタックレベル=1のスタック[1]からノード(ノード200-4)とブランチ番号=2を取り出し、カレントノードとカレントブランチにセットする(S803)。
【0250】
続いて、カレントブランチとカレントノードのブランチサイズ201を比較する(S804)。この場合、カレントブランチは2であり、カレントノードのブランチサイズ201=2と同じであるため、カレントノードの処理が終了したことになり、スタックレベルの1をデクリメントして、0とし(S810)、次のループに移る。
【0251】
(14)14回目ループ
14回目のループとして、出力リストに空きがあり、かつ、スタックレベルが0であるため、処理を続行する(S802)。
【0252】
続いて、スタックレベル=0のスタック[0]からノード(上位から2番目のノード200-2)とブランチ番号=3を取り出し、カレントノードとカレントブランチにセットする(S803)。
【0253】
続いて、カレントブランチとカレントノードのブランチサイズ201を比較する(S804)。この場合、カレントブランチは3であり、カレントノードのブランチサイズ201=3と同じであるため、カレントノードの処理が終了したことになり、スタックレベルの0をデクリメントして、-1とし(S810)、次のループに移る。
【0254】
(15)最終(15回目)ループ
最終(15回目)ループとして、検索制御部131は、出力リストの空き及びスタックレベルをチェックする(S802)。この場合、出力リストに空きはあるが、スタックレベルが-1であるため、ループを脱出し、結果数0(取得データ無し)を返却し(S820)、処理を終了する。
【0255】
以上のように、実施の形態1で示した検索装置100において、完全一致検索と同様に前方一致検索を行ってもよい。前方一致検索を行った場合でも、実施の形態1と同様、可変長の文字列を効率よく検索することができる。また、前方一致や範囲検索、ソートの結果は、返却するデータ数が非常に多くなることがあるため、反復取得に対応することで、任意の取得数に分割して効率よく返却することが出来る。
【0256】
(実施の形態3)
次に、実施の形態3について説明する。本実施の形態では、実施の形態1または2で示した検索装置100において、登録処理を行う例について説明する。
【0257】
<検索装置の構成>
図17は、本実施の形態に係る検索装置100の構成例を示している。図17に示すように、検索装置100は、図3の構成に加えて、さらに登録部150を備えている。なお、検索装置100は、検索部130と登録部150の両方を備えた情報処理装置でもよいし、いずれか一方のみを備えた情報処理装置でもよい。例えば、登録部150のみを備える登録装置を構成してもよい。
【0258】
登録部150は、入力部120に入力された文字列(登録文字列)を、データツリー111に登録する登録処理を実行する。登録部150は、新たに登録する文字列に基づいて、データツリー111を構成しているノード200、あるいは、新規に割り当てる(生成する)ノード200に必要な情報(直列文字列やブランチの情報等)を設定することで、文字列をデータツリー111に登録する。例えば、登録部150は、登録制御部151、文字列比較部152、ブランチ比較部153を含む。
【0259】
登録制御部151は、データツリー111のノード200をルートから順に選択し、選択したノード200の情報と登録文字列の比較結果に基づいて、登録処理を制御する。登録制御部151は、文字列比較部152による直列文字列比較の結果及びブランチ比較部153によるブランチバイト列比較の結果に基づいて、登録文字列の登録やノードの遷移制御を行う。登録制御部151は、直列文字列比較の結果及びブランチバイト列比較の結果に応じて、選択されたノード200が示すブランチノードを、遷移先のノード(次に比較を行うノード)として選択する選択部(第2の選択部)でもある。
【0260】
文字列比較部(第2の文字列比較部)152は、検索部130の文字列比較部132と同様の直列文字列比較処理を行う。文字列比較部152と文字列比較部132は、1つのブロックでもよい。文字列比較部152は、選択されたノード200の直列文字列と登録文字列とを比較する直列文字列比較処理を行う。文字列比較部152は、リーフの文字列が選択された場合、リーフの文字列と登録文字列とを比較する。検索部130の文字列比較部132と同様、直列文字列比較処理では、SIMD命令並びに一般命令により2つの文字列を比較する。
【0261】
ブランチ比較部(第2のブランチ比較部)153は、検索部130のブランチ比較部133と同様のブランチバイト列比較処理を行う。ブランチ比較部153とブランチ比較部133は、1つのブロックでもよい。ブランチ比較部153は、選択されたノード200のブランチバイト列206のブランチバイトと、登録文字列のブランチ位置204における文字を比較するブランチバイト列比較処理を行う。ブランチ比較部153は、ブランチバイト列比較処理により、ブランチバイト列206から、登録文字列のブランチ位置204における文字と一致するブランチバイト(ブランチ文字)を特定する。検索部130のブランチ比較部133と同様、ブランチバイト列比較処理では、SIMD命令並びに一般命令によりブランチバイト列206と登録文字列の該当する文字とを比較する。
【0262】
<登録処理の動作例>
図18A及び図18Bは、本実施の形態に係る検索装置100における登録処理の動作例を示している。図18の登録処理では、図4の完全一致検索処理で検索失敗となる部分(S120、S133、S140、S152、S160)において、各登録処理を行う。各登録処理は、以下に示す初期登録、リーフ分割、ヘッダ分割、直列文字列交換、ブランチ追加の基本5操作を含む。その他の処理は、図4A及び図4Bと同様である。なお、図18A及び図18Bでは、入力文字列は登録する文字列である。
【0263】
(1)初期登録
S101においてデータが未登録であると判定された場合、登録制御部151は、初期登録を行い(S900)、データ登録成功として、処理を終了する(S901)。
【0264】
初期登録(S900)では、登録制御部151は、データツリー111に、入力文字列を最初のリーフ(文字列300)として登録する。登録制御部151は、入力文字列を登録文字列112に新規登録し、その文字列をルートノードにセットする。
【0265】
(2)リーフ分割
S131において、入力文字列のうちバイトチェック位置から入力文字列終端までの文字列と、リーフ文字列に差異がある、または、入力文字列とリーフ文字列のサイズが違うと判定された場合、登録制御部151は、リーフ分割を行い(S910)、データ登録成功として、処理を終了する(S911)。
【0266】
S131において、入力文字列のうちバイトチェック位置から入力文字列終端までの文字列と、リーフ文字列に差異がない(同一である)、かつ、入力文字列とリーフ文字列のサイズが同じであると判定された場合、登録制御部151は、入力文字列は登録済みであるとして、リーフ文字列を返却し、処理を終了する(S912)。
【0267】
リーフ分割(S910)では、登録制御部151は、対象リーフ文字列と入力文字列の比較で差異がある場合は、対象リーフ文字列の上位に新規ノード200を挿入し、対象リーフ文字列を分割する。まず、登録制御部151は、入力文字列を登録文字列112に新規登録し、更に新規ノード200を割り当てる。登録制御部151は、差異位置(差異のある文字の位置)が、既リーフ文字列と入力文字列のいずれかの文字列の終端の場合は、終端に当たる文字列を新規ノード200の直列文字列205に登録するとともに実体フラグ203をONにする。登録制御部151は、もう一方の文字列の差異位置のバイトを新規ノード200のブランチバイト列206にブランチバイトとして登録し、ブランチサイズ201を1にセットする。登録制御部151は、更にその文字列を新規ノード200の遷移先情報207にリーフとして登録する。
【0268】
登録制御部151は、差異位置が、対象リーフ文字列と入力文字列の、いずれにおいても中間位置の場合は、いずれかの文字列(差異の前の部分はどちらでも同じなので、いずれでも良い)を新規ノード200の直列文字列205に登録するとともに実体フラグ203をOFFにする。登録制御部151は、対象リーフ文字列と入力文字列の差異位置から各々のバイトを抽出し、符号なし数値の昇順に新規ノード200のブランチバイト列206にブランチバイトとして登録し、ブランチサイズ201を2にセットする。登録制御部151は、ブランチバイトの登録順に合わせて、該当する2つの文字列を新規ノード200の遷移先情報207にリーフとして登録する。
【0269】
(3)ヘッダ分割
S106において、入力文字列のうちのバイトチェック位置から比較サイズ分の文字列とカレントノード(対象ノード)の直列文字列205に差異があると判定された場合、登録制御部151は、ヘッダ分割を行い(S920)、データ登録成功として、処理を終了する(S921)。
【0270】
ヘッダ分割(S920)では、登録制御部151は、対象ノード200の直列文字列205と入力文字列の比較で差異がある場合、対象ノード200の直列文字列205を差異部分で、新規ノード200と対象ノード200に分割する。その際、対象ノード200が新規ノード200の下位となるように、新規ノード200を追加する。換言すると、データツリー111において対象ノード200の上位に新規ノード200を挿入する。登録制御部151は、入力文字列を登録文字列112に新規登録し、更に新規ノード200を割り当てる。登録制御部151は、差異位置が、入力文字列の終端の場合は、入力文字列を新規ノード200の直列文字列205に登録するとともに実体フラグ203をONにする。登録制御部151は、対象ノード200の直列文字列の差異位置のバイトを新規ノード200のブランチバイト列206にブランチバイトとして登録し、ブランチサイズ201を1にセットする。登録制御部151は、更に対象ノード200を新規ノード200の遷移先情報207にノードとして登録する。
【0271】
登録制御部151は、差異位置が、対象ノード200の直列文字列205と入力文字列の、いずれにおいても中間位置の場合は、いずれかの文字列(差異の前の部分はどちらでも同じなので、いずれでも良い)を新規ノード200の直列文字列205に登録するとともに実体フラグをOFFにする。登録制御部151は、対象ノード200の直列文字列205と入力文字列の差異位置から各々のバイトを抽出し、符号なし数値の昇順に新規ノード200のブランチバイト列206にブランチバイトとして登録し、ブランチサイズ201を2にセットする。登録制御部151は、ブランチバイトの登録順に合わせて、対象ノード200と入力文字列を新規ノード200の遷移先情報207にノードとリーフとして登録する。
【0272】
(4)直列文字列交換
S150において、カレントノード(対象ノード)の直列文字列205が文字列の実体を参照し、かつ、入力文字列と直列文字列205のサイズが同じであると判定された場合、登録制御部151は、入力文字列は登録済みであるとして、直列文字列を返却し、処理を終了する(S932)。
【0273】
S150において、カレントノードの直列文字列205が文字列の実体を参照していない、または、入力文字列と直列文字列205のサイズが異なると判定された場合、登録制御部151は、直列文字列変換を行い(S930)、データ登録成功として、処理を終了する(S931)。
【0274】
直列文字列交換(S930)では、登録制御部151は、対象ノード200の直列文字列205を入力文字列に置き換える。登録制御部151は、入力文字列を登録文字列112に新規登録し、その文字列を、対象ノード200の直列文字列205に登録するとともに実体フラグ203をONにする。
【0275】
(5)ブランチ追加
S110において、カレントノード(対象ノード)のブランチバイト列206に入力文字列のバイトチェック位置と同じ値がないと判定された場合、登録制御部151は、ブランチ追加を行い(S940)、データ登録成功として、処理を終了する(S941)。
【0276】
ブランチ追加(S940)では、登録制御部151は、入力文字列における、対象ノード200のブランチ位置204が指す1バイトが、対象ノード200のブランチバイト列206のいずれとも一致しない場合、対象ノード200に入力文字列に対応したブランチバイトとリーフ(文字列)を挿入する。登録制御部151は、入力文字列を登録文字列112に新規登録する。登録制御部151は、対象ノード200のブランチが満杯の場合は、まず、ブランチバイト列206と遷移先情報207のノード/リーフ格納エリアを拡張する。登録制御部151は、入力文字列から、対象ノード200のブランチ位置204が指す1バイトを抽出し、対象ノード200のブランチバイト列206が符号なし数値の昇順になるように、この1バイトをブランチバイト列206に挿入し、更に、ブランチバイトの挿入位置に対応する遷移先情報207に新規登録した入力文字列をリーフとして挿入する。登録制御部151は、対象ノード200のブランチサイズ201を1カウントアップする。
【0277】
<登録処理の具体例>
図19図25を用いて、図18A及び図18Bの登録処理の具体例について説明する。図19図25は、実施の形態1の図5の文字列300-1~300-7をデータツリー111に登録する例である。なお、図19図25では、文字列およびノードに図5と同じ符号を使用する。
【0278】
(1)初期登録(S900)
図19は、最初に行われる初期登録(S900)の具体例を示している。図19に示すように、データ未登録の状態で、文字列“DGHKP”が入力される。
【0279】
登録制御部151は、データツリー111をチェックし(S101)、初期状態でデータ未登録のため、初期登録を行う(S900)。この場合、登録制御部151は、入力文字列“DGHKP”を登録文字列112に文字列300-3として新規登録し、その文字列をルートノードにセットする。
【0280】
(2)リーフ分割(S910)
図20は、図19の後に行われるリーフ分割(S910)の具体例を示している。図20に示すように、図19で文字列“DGHKP”(文字列300-3)を登録した後、文字列“DGHKPS”が入力される。
【0281】
登録制御部151は、データツリー111をたどって、入力文字列“DGHKPS”と既登録のリーフ文字列“DGHKP”に対し、直列文字列比較を行う(S130)。直列文字列比較の結果、入力文字列“DGHKPS”はリーフ文字列“DGHKP”と異なるため、登録制御部151は、リーフ分割を行う(S910)。
【0282】
この場合、登録制御部151は、入力文字列“DGHKPS”を登録文字列112に文字列300-4として新規登録し、更に新規ノード200-3を割り当てる。ここでは、入力文字列“DGHKPS”とリーフ文字列“DGHKP”の差異位置は5である。
【0283】
登録制御部151は、差異位置=5が既リーフ文字列“DGHKP”の終端のため、既リーフ文字列“DGHKP”を新規ノード200-3の直列文字列205に登録するとともに実体フラグ203をONにする。登録制御部151は、差異位置=5を新規ノード200-3のブランチ位置204にセットし、入力文字列“DGHKPS”の差異位置=5のバイト“S”を新規ノード200-3のブランチバイト列206にブランチバイトとして登録し、新規ノード200-3のブランチサイズ201に1をセットする。
【0284】
登録制御部151は、新規登録した入力文字列“DGHKPS”(文字列300-4)を新規ノード200-3の遷移先情報207にリーフとして登録する。
【0285】
(3)ヘッダ分割(S920)
図21は、図20の後に行われるヘッダ分割(S920)の具体例を示している。図21に示すように、図20で文字列“DGHKPS”(文字列300-4)を登録した後、文字列“DGLEBG”が入力される。
【0286】
登録制御部151は、データツリー111をたどって、入力文字列“DGLEBG”とノード200-3の直列文字列205である“DGHKP”"とに対し、直列文字列比較を行う(S105)。直列文字列比較の結果、入力文字列“DGLEBG”はノード200-3の直列文字列205である“DGHKP”の中間位置で異なるため、登録制御部151は、ヘッダ分割を行う(S920)。
【0287】
この場合、登録制御部151は、入力文字列“DGLEBG”を登録文字列112に文字列300-7として新規登録し、更に新規ノード200-2を割り当てる。ここでは、入力文字列“DGLEBG”と直列文字列“DGHKP”の差異位置は2である。
【0288】
登録制御部151は、差異位置=2が、対象ノード200-3の直列文字列205と入力文字列の、いずれにおいても中間位置に当たるため、いずれかの文字列(例では既ノード200-3の直列文字列205である“DGHKP”)を新規ノード200-2の直列文字列205に登録するとともに実体フラグ203をOFFにする。登録制御部151は、既ノード200-3の直列文字列205である“DGHKP”と入力文字列“DGLEBG”から差異位置=2の各々のバイト(“H”,“L”)を抽出し、符号なし数値の昇順(“H”,“L”の順)に新規ノード200-2のブランチバイト列206にブランチバイトとして登録し、新規ノード200-2のブランチサイズ201を2にセットする。
【0289】
登録制御部151は、新規ノード200-2の遷移先情報207にブランチバイトの登録順に合わせて、既ノード200-3のノード情報と新規登録した入力文字列“DGLEBG”(文字列300-7)を登録する。
【0290】
(4)直列文字列交換(S930)
図22は、図21の後に行われる直列文字列交換(S930)の具体例を示している。図22に示すように、図21で文字列“DGLEBG”(文字列300-7)を登録した後、文字列“DG”が入力される。
【0291】
登録制御部151は、データツリー111をたどって、入力文字列“DG”とノード200-2の直列文字列205である“DG”"とに対し、直列文字列比較を行う(S105)。直列文字列比較の結果、入力文字列“DG”はノード200-2の直列文字列205である“DG”と内容、長さともに一致し、かつ、ノード200-2の実体フラグ203がOFFのため、登録制御部151は、直列文字列交換を行う(S930)。
【0292】
この場合、登録制御部151は、入力文字列“DG”を登録文字列112に文字列300-2として新規登録する。登録制御部151は、新規登録した入力文字列“DG”(文字列300-2)を、対象ノード200-2の直列文字列205に登録(上書き交換)するとともに実体フラグ203をONにする。
【0293】
(5)ブランチ追加(S940)
図23は、図22の後に行われるブランチ追加(S940)の具体例を示している。図23に示すように、図22で文字列“DG”(文字列300-2)を登録した後、文字列“DGK”が入力される。
【0294】
登録制御部151は、データツリー111をたどって、入力文字列“DGK”とノード200-2の直列文字列205である“DG”"とに対し、直列文字列比較を行う(S105)。直列文字列比較の結果、入力文字列“DGK”はノード200-2の直列文字列205である“DG”と差異がないため、登録制御部151は、ノード200-2のブランチバイト列206と入力文字列“DGK”のブランチバイトに対し、ブランチバイト列比較を行う(S109)。ブランチバイト列比較の結果、入力文字列“DGK”はブランチ位置=2のブランチバイト“K”が、ノード200-2のブランチバイト列206(“H”,“L”)に無いため、登録制御部151は、ブランチ追加を行う(S940)。
【0295】
この場合、登録制御部151は、入力文字列“DGK”を登録文字列112に文字列300-5として新規登録する。登録制御部151は、対象ノード200-2のブランチバイト列206に余裕(4-2=2)があるため、ブランチバイト列206と遷移先情報207のノード/リーフ格納エリアの拡張(4、8、16、32・・・、256の順の拡張)は行わない。
【0296】
登録制御部151は、入力文字列“DGK”から、対象ノード200-2のブランチ位置=2が指すバイト“K”を抽出し、対象ノード200-2のブランチバイト列206が符号なし数値の昇順に成るように、この“K”'をブランチバイト列206に挿入し、更に、ブランチバイトの挿入位置に対応する遷移先情報207に新規登録した入力文字列“DGK”(文字列300-5)をリーフとして登録する。登録制御部151は、対象ノード200-2のブランチサイズ201を1カウントアップして、3にする。
【0297】
(6)リーフ分割(S910)
図24は、図23の後に行われるリーフ分割(S910)の具体例を示している。図24に示すように、図23で文字列“DGK”(文字列300-5)を登録した後、文字列“DGLEA”が入力される。
【0298】
登録制御部151は、データツリー111をたどって、入力文字列“DGLEA”と既登録のリーフ文字列“DGLEBG”に対し、直列文字列比較を行う(S130)。直列文字列比較の結果、入力文字列“DGLEA”は既リーフ文字列“DGLEBG”と異なるため、登録制御部151は、リーフ分割を行う(S910)。
【0299】
この場合、登録制御部151は、入力文字列“DGLEA”を登録文字列112に文字列300-6として新規登録し、更に新規ノード200-4を割り当てる。ここでは、入力文字列“DGLEA”と既リーフ文字列“DGLEBG”の差異位置は4である。
【0300】
登録制御部151は、差異位置=4が、既リーフ文字列“DGLEBG”と入力文字列“DGLEA”のいずれにおいても中間位置に当たるため、いずれかの文字列(例では既リーフ文字列“DGLEBG”)を新規ノード200-4の直列文字列205に登録するとともに実体フラグ203をOFFにする。登録制御部151は、差異位置=4を新規ノード200-4のブランチ位置204にセットし、既リーフ文字列“DGLEBG”と入力文字列“DGLEA”から差異位置=4の各々のバイト(“B”,“A”)を抽出し、符号なし数値の昇順(“A”,“B”の順)に、新規ノード200-4のブランチバイト列206に登録し、新規ノード200-4のブランチサイズ201を2にセットする。
【0301】
登録制御部151は、新規ノード200-4の遷移先情報207にブランチバイトの登録順に合わせて、新規登録した入力文字列“DGLEA”(文字列300-6)と既リーフ文字列“DGLEBG”(文字列300-7)を登録する。
【0302】
(7)ヘッダ分割(S920)
図25は、図24の後に行われるヘッダ分割(S920)の具体例を示している。図25に示すように、図24で文字列“DGLEA”(文字列300-6)を登録した後、文字列“DBXPN”が入力される。
【0303】
登録制御部151は、データツリー111をたどって、入力文字列“DBXPN”とノード200-2の直列文字列205である“DG”"とに対し、直列文字列比較を行う(S105)。直列文字列比較の結果、入力文字列“DBXPN”はノード200-2の直列文字列205である“DG”の中間位置で異なるため、登録制御部151は、ヘッダ分割を行う(S920)。
【0304】
この場合、登録制御部151は、入力文字列“DBXPN”を登録文字列112に文字列300-1として新規登録し、更に新規ノード200-1を割り当てる。ここでは、入力文字列“DBXPN”と直列文字列“DG”の差異位置は1である。
【0305】
登録制御部151は、差異位置=1が、対象ノード200-2の直列文字列205と入力文字列の、いずれにおいても中間位置に当たるため、いずれかの文字列(例では新規登録した入力文字列“DBXPN”)を新規ノード200-1の直列文字列205に登録するとともに実体フラグ203をOFFにする。登録制御部151は、既ノード200-2の直列文字列205である“DG”と入力文字列“DBXPN”から差異位置=1の各々のバイト(“G”,“B”)を抽出し、符号なし数値の昇順(“B”,“G”の順)に新規ノード200-1のブランチバイト列206にブランチバイトとして登録し、新規ノード200-1のブランチサイズ201を2にセットする。
【0306】
登録制御部151は、新規ノード200-1の遷移先情報207にブランチバイトの登録順に合わせて、新規登録した入力文字列“DBXPN”(文字列300-1)と既ノード200-2のノード情報を登録する。
【0307】
以上のように、実施の形態1または2で示した検索装置100において、登録処理を行ってもよい。登録処理は、完全一致検索と同様に、SIMD命令を使用して直列文字列比較及びブランチバイト列比較を行うことで実現できる。このため、実施の形態1と同様に、可変長の文字列を効率よく登録することができる。
【0308】
(実施の形態4)
次に、実施の形態4について説明する。本実施の形態では、実施の形態1~3で示した検索装置100において、データを格納する際に数値データを変換し、また、統合型マルチキーを使用する例について説明する。検索装置100の構成は、実施の形態1~3と同様である。
【0309】
一般的には、文字列の比較と数値の比較はそのデータ型に応じた異なる比較操作になる。これに対し、本実施の形態では、固定小数点や浮動小数点などの数値データに対しても、以降で説明する変換を行って格納することで、データ型による内部操作の切り替えオーバーヘッドを無くし、文字列と同じ統一した操作によって効率よく処理を行うことが可能となる。
【0310】
図26の表は、本実施の形態に係る数値データ格納時の変換規則の例を示している。例えば、検索装置100は、データツリー111に数値データを登録し、データベース110に格納する際に、図26の変換規則にしたがって数値データを変換し、変換したデータを登録文字列112に格納する。なお、格納場所は、登録文字列112とは別に格納場所を設け、そこに格納してもよい。
【0311】
図26の例では、対象データのデータ型ごとに、変換条件、データ変換方法、エンディアン変換対象が対応付けられている。検索装置100は、対象データのデータ型を判定し、データ型に対応するデータ変換方法で、対象データを変換する。変換条件が定義されているデータ型(浮動小数点型)の場合、検索装置100は、対象データに応じて変換条件を判断し、判断した結果に対応するデータ変換方法で、対象データを変換する。さらに、検索装置100は、データ変換方法で変換した対象データの各バイトに対し、エンディアン変換を行い、エンディアン変換後のデータを格納する。
【0312】
なお、図26は、Little-Endianアーキテクチャの場合の例であり、Big-Endianアーキテクチャの場合は、エンディアン変換は不要である。また、図26の変換は完全な可逆変換が可能であり、逆の操作を行うことで、簡単に元の値に戻すことが出来る。
【0313】
図26における数値のデータ変換規則は、各データ型において数値を比較したときの大小関係の特性に依存する。すなわち、文字列は基本的にバイトコードの集まりで、大小関係はバイト列を辞書式順序の配列として扱う。この大小関係は、符号なし固定小数点を上位桁から順に配列にした場合と同じになる。一方、数値は、固定小数点や浮動小数点のように内部形式の異なるものが存在する。そして、固定小数点には、符号あり(Signed)と符号なし(Unsigned)の型があり、浮動小数点にも正と負の符号概念が存在する。
【0314】
<符号付き整数値の変換原理>
図27は、符号なし整数値の比較結果の大小関係、図28は、符号付き整数値の比較結果の大小関係を示している。図27図28を比べると、太枠で示した部分で比較結果の大小関係が異なり、その他の部分では比較結果の大小関係は同じである。従って、符号付き整数の比較を符号なし整数の比較に変えるには、次の方法で良いことが判る。
・同値の比較は変更なし。
・大なり、小なりの比較の場合は比較値同士の先頭bitが違う部分で、比較結果を反転させる。
【0315】
この結果から、符号付き固定小数点数値の場合、「データの先頭ビットを反転して、符号なし固定小数点数値に変換して格納」とすることで、文字列の場合と同じ符号なし固定小数点比較に統一して処理することが出来る。例えば、図26に示したように、対象データがsigned int8型の場合、対象データに対し0x80をxor演算することで、先頭ビットを反転させる。
【0316】
<浮動小数点数値の変換原理>
図29は、浮動小数点数値(IEEE754形式)のフォーマットを示している。図29に示すように、浮動小数点数値(IEEE754形式)は、符号ビット(sign)、指数部(exponent)、仮数部(fraction)から構成されているため、一見すると符号なしの固定小数点比較には適用できそうにない。しかし、注意深く観察すると、符号ビットを除いた他のビットの配置は、より上位のビットが立っている数値は、ビットが立っていない数値に対して大きい値になるように設計されていることが判る。
【0317】
更に、先頭の符号ビットの値によって、浮動小数点数値の比較結果は以下のようになる。
・0,0:符号ビットが両方とも0(正)の場合の比較は、intの符号なしの比較と同じ。
・0,1:符号ビットが異なる場合の比較は、符号ビットが0(正)の方が大きい。
・1,1:符号ビットが両方とも1(負)の場合の比較は、intの符号なしの結果を反転させたものと同じ(負の値は、絶対値が小さい方が大きい)。
【0318】
この結果から、浮動小数点数値の場合、次のように格納することで、符号なし固定小数点比較に統一して処理することが出来る。
・符号ビットが0の場合は先頭の符号ビットのみ反転して格納する。
・符号ビットが1の場合は先頭の符号ビットを含め、全ビットを反転して格納する。
【0319】
例えば、図26に示したように、対象データがfloat(32bit)型の場合、対象データに対して0x80000000のマスクをかけて、先頭ビットを判定し、先頭ビットがONの場合、対象データをnot演算することで、全ビット反転させ、先頭ビットがOFFの場合、対象データに対し0x80000000をxor演算することで、先頭ビットを反転させる。
【0320】
<エンディアン(バイトオーダー)変換原理>
コンピュータの扱うデータは文字列や固定小数点、浮動小数点などの種類があるが、これらのデータをコンピュータで扱う場合、その扱いはハードウェアアーキテクチャの一種であるエンディアン(バイトオーダー)の影響を受ける。
【0321】
図30は、Big-EndianとLittle-Endianのアーキテクチャで文字列と数値を格納した場合のメモリ配置の例を示している。例えば、文字列の“ABCDEF”と、4バイト数値の12345678(Hex)をBig-EndianとLittle-Endianのアーキテクチャで格納した場合、図30に示すように、実際のメモリ上での配置は、文字列の配置は同じだが、数値は上位バイトと下位バイトの順序が逆になる。
【0322】
従って、Little-Endianのアーキテクチャでは、複数のバイトで構成する数値の場合は上位と下位のバイトを逆順にして格納することで、文字列の比較順序と同じにできる。TCP/IPなどの通信時には、バイトオーダーを標準規則(Big-Endian)にそろえる必要がある。このため、一般的に、CPUにはこの変換に対応するための命令が用意されており、X86ではBSWAP命令、ArmではREV命令などを使うことで高速に変換できる。図26に示したように、対象データが、16ビットから64ビット型の数値の場合、これらのエンディアン変換用の命令を使用して、対象データを変換する。
【0323】
<統合型マルチキーの構成例>
一般的に、複数のデータを結合したマルチキーに対する検索や大小比較の操作を行う場合には、先頭のキーから順番に一つずつ比較を行い、キーが同一だった場合に、次のキーの比較を行う、という動作を繰り返すことで処理を行う。
【0324】
しかし、この方式では、キーの比較と判定を繰り返すため、マルチキーのすべてのキーが同一かをチェックするような場合には、比較操作と判定操作を、マルチキーを構成するキーの数だけ行うことになり効率が悪い。また、大小比較の場合でも、違いが後方のキーで発生するほどキーの比較回数が増えることになる。
【0325】
これに対し、本実施の形態におけるマルチキーの対応では、最初に一度変換をすることで、全てのデータ型に対し、文字列と同じ符号なしバイト列として統一した処理が可能となる。すなわち、予め上記のように数値データを変換して格納しておく。これにより、検索装置100は、実施の形態1で示した直列文字列比較やブランチバイト列比較を行う際に、マルチキーのキー境界を意識せずに、効率よく比較処理を行うことが出来る。
【0326】
図31は、マルチキーの構成例を示している。図31の例では、マルチキーは、5つのキーを含む32バイトの長さである。図31のマルチキーを比較する場合、一般的には図32に示すように、マルチキーに含まれるキーを先頭から要素ごとに比較する必要がある。例えば、文字列を1バイトずつ比較すると、比較回数は18回となる。これに対し、本実施の形態では、図33に示すように、マルチキーを32バイト一括で比較することができる。例えば、検索装置100では、トータルサイズが32バイトのマルチキーに対し、SIMDによる256bit処理の場合で1回、128bitの場合でも2回の比較動作と判定操作で処理を行うことが出来る。
【0327】
また、上記の数値データ変換で示したように、格納時の変換の効果により、符号なし固定小数点比較による統一した比較操作としながら、元のデータの持つ大小関係は、そのまま保持できるようになっている。従って、マルチキーの大小関係は、キーの境界を気にせず、単純に、差が発生した最初のバイト位置の値を比較することで得ることが出来る。
【0328】
更に、格納するデータの加工は論理操作とバイトオーダーの変更のみで、データの位置やサイズは変化を起こさない。このため、違いが生じたキーについても、差異位置をオリジナルのキー位置(オフセット位置)と照合するだけで、容易に特定することが出来る。
【0329】
以上のように、実施の形態1~3で示した検索装置100において、データを格納する際に、図26のような変換規則でデータを変換してもよい。このように、固定小数点や浮動小数点のデータについて、簡単なデータ変換を行って格納することで、文字列と同様な符号なしバイト列に対するロジックを使って検索することが可能になる。
【0330】
さらに、文字列と数値データを同様に検索できるため、文字列と固定小数点、浮動小数点のデータを任意の順序で連結した、異種データで構成するマルチキーデータに対してもまとめて処理することができ、効率よく検索することが可能となる。
【0331】
なお、本発明は上記実施の形態に限られたものではなく、趣旨を逸脱しない範囲で適宜変更することが可能である。
【0332】
上述の実施形態における各構成は、ハードウェア又はソフトウェア、もしくはその両方によって構成され、1つのハードウェア又はソフトウェアから構成してもよいし、複数のハードウェア又はソフトウェアから構成してもよい。各装置の機能(処理)を、CPUやメモリ等を有するコンピュータにより実現してもよい。例えば、記憶装置に実施形態における方法を行うためのプログラムを格納し、各機能を、記憶装置に格納されたプログラムをCPUで実行することにより実現してもよい。
【0333】
これらのプログラムは、コンピュータに読み込まれた場合に、実施形態で説明された1又はそれ以上の機能をコンピュータに行わせるための命令群(又はソフトウェアコード)を含む。プログラムは、非一時的なコンピュータ可読媒体又は実体のある記憶媒体に格納されてもよい。限定ではなく例として、コンピュータ可読媒体又は実体のある記憶媒体は、random-access memory(RAM)、read-only memory(ROM)、フラッシュメモリ、solid-state drive(SSD)又はその他のメモリ技術、CD-ROM、digital versatile disc(DVD)、Blu-ray(登録商標)ディスク又はその他の光ディスクストレージ、磁気カセット、磁気テープ、磁気ディスクストレージ又はその他の磁気ストレージデバイスを含む。プログラムは、一時的なコンピュータ可読媒体又は通信媒体上で送信されてもよい。限定ではなく例として、一時的なコンピュータ可読媒体又は通信媒体は、電気的、光学的、音響的、またはその他の形式の伝搬信号を含む。
【符号の説明】
【0334】
100 検索装置
110 データベース
111 データツリー
112 登録文字列
120 入力部
130 検索部
131 検索制御部
132 文字列比較部
133 ブランチ比較部
140 出力部
150 登録部
151 登録制御部
152 文字列比較部
153 ブランチ比較部
200 ノード
201 ブランチサイズ
202 allocサイズ
203 実体フラグ
204 ブランチ位置
205 直列文字列
206 ブランチバイト列
207 遷移先情報
300 文字列
【要約】
【課題】効率よく文字列を検索することが可能な検索装置、検索方法、及びプログラムを提供する。
【解決手段】検索装置100は、可変長の登録文字列112と、複数のノード200から構成されるデータツリー111とを格納するデータベース110を備える。ノード200は、登録文字列112の少なくとも一部の文字列を示す直列文字列と、当該ノード200の下位の遷移先に関するブランチ情報とを含む。検索装置100は、ノード200の直列文字列及びブランチ情報に基づいて、検索文字列を含む登録文字列112を検索する検索部130を備える。直列文字列は、直列文字列が示す文字列と終端同士が一致する登録文字列112が存在する場合、登録文字列112の実体を保持し、直列文字列が示す文字列と終端同士が一致する登録文字列112が存在しない場合、当該ノード200のブランチ情報が示す遷移先の登録文字列112を共用参照する。
【選択図】図3
図1
図2
図3
図4A
図4B
図5
図6A
図6B
図7
図8
図9
図10A
図10B
図11
図12
図13A
図13B
図14
図15A
図15B
図16
図17
図18A
図18B
図19
図20
図21
図22
図23
図24
図25
図26
図27
図28
図29
図30
図31
図32
図33