Sennaサンプルコード

Senna C APIのサンプルコードが意外と見つからなかったので、貼り付け。

とりあえずBasic APIを使ってみた。

コード

#include <senna/senna.h>
#include <stdlib.h>
#include <vector>
#include <iostream>
#include <fstream>
#include <cassert>
using namespace std;

static int
do_insert(const string& idxname, const string& type, const string& filename)
{
  sen_rc rc;
  cout << "insert: " << idxname << " << " << filename << endl;

  int flag = SEN_INDEX_NORMALIZE;
  if (type == "ngram")
    flag |= SEN_INDEX_NGRAM;

  sen_index *idx = sen_index_create(idxname.c_str(), 0, flag, 1024, sen_enc_utf8);
  assert(idx != NULL);

  string content;
  ifstream ifs(filename.c_str());
  assert((ifs ? 0 : 1) == 0);
  string line;
  while (getline(ifs, line))
    content += line;

  rc = sen_index_upd(idx, filename.c_str(), NULL, 0, content.c_str(), content.size());
  assert(rc == sen_success);

  rc = sen_index_close(idx);
  assert(rc == sen_success);
}

static int
do_select(const string& idxname, const string& query)
{
  sen_rc rc;
  cout << "select: " << idxname << " << " << query << endl;

  sen_index *idx = sen_index_open(idxname.c_str());
  assert(idx != NULL);

  vector<char> keybuf(1024);
  sen_records *records = sen_index_sel(idx, query.c_str(), query.size());
  while (true) {
    int score = 0;
    int keylen = sen_records_next(records, NULL, 0, &score);
    if (keylen == 0) break;
    if (keybuf.size() <= keylen) keybuf.resize(keylen + 1);
    sen_records_curr_key(records, &keybuf[0], keylen);
    keybuf[keylen] = '\0';
    cout << "\t" << "score: " << score << "\t" << string(&keybuf[0]) << endl;
  }

  rc = sen_index_close(idx);
  assert(rc == sen_success);

  return 0;
}

static void
usage()
{
  cout << "a.out <indexname> <ins> <ngram|ii> <string>" << endl;
  cout << "a.out <indexname> <sel> <string>" << endl;
  exit(0);
}

int
main(int argc, char **argv)
{
  if (argc < 3) usage();

  sen_rc rc;
  rc = sen_init();
  assert(rc == sen_success);

  string cmd = argv[2];
  if (cmd == "ins") {
    do_insert(argv[1], argv[3], argv[4]);
  } else if (cmd == "sel") {
    do_select(argv[1], argv[3]);
  } else {
    usage();
  }

  rc = sen_fin();
  assert(rc == sen_success);
  return 0;
}

コンパイル

$ g++ senna.cpp -O2 -lsenna

実行

$ rm hoge.*; ./a.out hoge ins ngram /repos/jawiki/00000/00000001.est
insert: hoge << /repos/jawiki/00000/00000001.est
$ ./a.out hoge sel 浜崎あゆみ
select: hoge << 浜崎あゆみ
        score: 2        /repos/jawiki/00000/00000001.est

疑問っぽいもの

  • KWIC APIの概念が分からない
    • sen_recordsについてKWICを取り出す訳では無くて、別系統の検索APIと考えれば良い?
    • その割にsen_snip_open()のmax_resultsに10より大きい数字を入れるとNULLが帰る