三日で書くGroonga関数

2,339 views

Published on

Published in: Technology, Business
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,339
On SlideShare
0
From Embeds
0
Number of Embeds
41
Actions
Shares
0
Downloads
7
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

三日で書くGroonga関数

  1. 1. 三日で作る Groonga 関数 hotpepsi@twitter
  2. 2. Agenda  filter で呼べる関数を自作する  ただし三日くらいで
  3. 3. 背景  しょぼいサーバでスループットを上げ たい  更新中も検索を止めたくない  検索されるものは全部 Groonga につっ こむ
  4. 4. 処理したい内容  親子関係を持つテーブルがある  親と子の個数の比は 1:n  ある条件で子テーブルを検索し、合致 する親テーブルを取得したい  具体的には : 商品 (1) : 在庫・価格 (n)
  5. 5. SQL の場合  子テーブルに親テーブルを JOIN  検索結果を親のキーで DISTINCT  Groonga の場合、素直にはできない  ※ ドリルダウンすれば 2 度引きで可能
  6. 6. Groonga の場合  子テーブルで検索する  重複するキーを filter で捨てる  filter で使える関数を自作する必要があ る
  7. 7. 自作する関数の仕様  引数として親のキー( _key )をとる  格納済かどうかを返す  Int32 distinct(ShortText parent_key)
  8. 8. 雛形  test/unit/fix/fixtures/modules/string.c に ある str_len を参考にする  自作の関数を登録する :grn_proc_create  grn_proc_create(ctx, "str_len", strlen("str_len"), GRN_PROC_FUNCTION, func_str_len, NULL, NULL, 0, NULL);
  9. 9. とりあえず版 登録 proc.c ... grn_proc_create(ctx, "distinct", 8, GRN_PROC_FUNCTION, func_distinct, NULL, NULL, 0, NULL); ...
  10. 10. とりあえず版 関数 proc.c static grn_obj *func_distinct(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data) { int result = 0; grn_obj *obj; if (nargs == 1) { grn_obj *item_key = args[0]; result = _distinct(GRN_TEXT_VALUE(item_key), GRN_TEXT_LEN(item_key)); if ((obj = GRN_PROC_ALLOC(GRN_DB_UINT32, 0))) { GRN_UINT32_SET(ctx, obj, result); } } return obj; }
  11. 11. とりあえず版 中身 distinct.cc #include <string> #include <set> typedef std::set<std::string> Map; static Map _map; // 格納済キーの保存庫 extern "C" int _distinct(const char *name, size_t length) { std::string _key(name, length); // std::string に変換 Map::iterator it = _map.find(_key); // キーを探す if (it != _map.end()) return 0; // 格納済なら 0 を返す _map.insert(key); // 格納する return 1; }
  12. 12. 適当にビルドしてみる  lib/ に distinct.cc を追加して make  よくわからないエラー  ../lib/.libs/libgroonga.so: undefined reference to `__cxa_begin_catch‘  g++ 経由でリンクしないと駄目
  13. 13. 正式なやり方  configure.ac に AC_PROG_CXX を追加  lib/Makefile.am の libgroonga_la_SOURCES に distinct.cc を追加  autoreconf で configure を再生成
  14. 14. autoreconf への道  色々更新が必要  autoconf-2.67  automake-1.11.1  libtool-2.2.6b  激しく遠い道のりなので以下略
  15. 15. 手抜き  Makefile.in に追記  .SUFFIXES に .cc を追加  CCLD を gcc から g++ に変更  ビルドルールに .cc.o を追加
  16. 16. デモ  商品テーブル item  ShortText 型 description  3 件  在庫テーブル stock  item 型 i  Time 型 date  Int32 型 price  9 件
  17. 17. distinct なし  select --table stock --output_columns i._key,price  → i._key が重複する
  18. 18. distinct あり  select --table stock --filter "distinct(i._key)" --output_columns i._key,price  → i._key が重複しない
  19. 19. end of file

×