tsubomiライブラリのAPIの仕様とサンプルプログラム

先日公開したtsubomiのAPI仕様とサンプルプログラムについて書いておく。

参考:
CSAを使った全文検索ライブラリtsubomiを公開してみる - EchizenBlog-Zwei


APIは現時点で必要最低限なものだけ用意してある。必要になり次第足していく予定。
APIはsearcherというインタフェース用のクラスによって実現している。searcherの派生クラスであれば何でも使える。現在はbasic_seacher(普通のSuffixArray)とcompressor(CompressedSuffixArray)の二つを用意している。
basic_seacherを使うにはtsubomi_basic_searcher.hを、compressorを使うにはtsubomi_compressor.hをインクルードする。

[tsubomi::sa_index]
テキスト上の位置を監理する変数。
searcher::get_line()で用いる。

[tsubomi::sa_range]
sa_indexの範囲を管理する変数。
2つのsa_index型変数のペアによって範囲を扱う。
sa_range::firstで範囲の最初の値が
sa_range::secondで範囲の最後の値が得られる。
searcher::search()で用いる。

[tsubomi::searcher]
- tsubomi::sa_range tsubomi::searcher::search(const char *key)
    key: 検索するキーワード
keyの出現位置をファイルから検索する。
結果はsa_range型の変数に入る。
keyがファイルに出現しない場合にはsa_range::fisrtに-1が入る。
この結果はget_line()で利用される。

- bool tsubomi::searcher::get_line(tsubomi::sa_index pos,
                                   char *buf,
                                   tsubomi::sa_index size,
                                   tsubomi::sa_index *pkeypos=NULL)
    pos: search()で取得したkeyの出現位置を指定する。
    buf: 結果を入れる変数。
    size: bufのサイズ。
    pkeypos: keyのbuf中の出現位置が返る。不要な場合はNULLを入れる。
search()で取得した位置情報から実際にキーワードが含まれる
テキストを一行取得する。
bufが一行より小さい場合はfalseを返す。
この場合、size-2バイト分だけが取得されbuf[size-1]に'\0'が入る。

[tsubomi::basic_searcher]
- tsubomi::basic_searcher::basic_searcher(const char *filename)
    filename: tsubomi_mkary済みのファイル
    (filenameおよびfilename.aryが必要)
コンストラクタ。
普通のSuffixArrayによる検索をする場合に使う。

[tsubomi::compressor]
- tsubomi::compressor::compressor(const char *filename)
    filename: tsubomi_mkcsa済みのファイル
    (filename.csaが必要)
コンストラクタ。
CompressedSuffixArrayによる検索をする場合に使う。

以上。ちなみにtsubomiライブラリ内で発生した例外はすべて文字列リテラルによるエラーメッセージが返る。

以下、サンプル。たぶんこっちをみたほうがわかり易い。

#include <iostream>
#include "tsubomi_basic_searcher.h"

int main(int argc, char **argv) {
  try {
    if (argc < 3) { throw "[USAGE] sample filename keyword"; }
    const char *filename = argv[1];
    const char *keyword  = argv[2];

    tsubomi::searcher *psearcher = 
      new tsubomi::basic_searcher(filename);

    tsubomi::sa_range r = psearcher->search(keyword);
    if (r.first != -1) {
      char              buf[1024];
      tsubomi::sa_index pos;
      for (tsubomi::sa_index i = r.first; i <= r.second; i++) {
        if (psearcher->get_line(i, buf, 1024, &pos) == false) {
          throw "buffer is smaller than line";
        }
        std::cout << buf << "\t" << pos << std::endl;
      }
    }
  } catch (const char *err) {
    std::cerr << err << std::endl;
    return 1;
  }
  return 0;
}

これをsample.ccなどとして保存する。コンパイルは以下のようにする。インクルードパスに/usr/local/includeを、ライブラリパスに/usr/local/libを追加しておくこと。

$$ g++ sample.cc -ltsubomi -o sample

実行は以下のとおり。インデックスファイルは前回の記事を参考につくっておくこと。

$$ ./sample var/test.txt 麻布
東京都港区麻布十番 15
東京都港区麻布台   15
...
東京都港区西麻布   18