Your SlideShare is downloading. ×
三日で書くGroonga関数
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

三日で書くGroonga関数

1,771

Published on

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

No Downloads
Views
Total Views
1,771
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
5
Comments
0
Likes
2
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. 三日で作る Groonga 関数 hotpepsi@twitter
  • 2. Agenda  filter で呼べる関数を自作する  ただし三日くらいで
  • 3. 背景  しょぼいサーバでスループットを上げ たい  更新中も検索を止めたくない  検索されるものは全部 Groonga につっ こむ
  • 4. 処理したい内容  親子関係を持つテーブルがある  親と子の個数の比は 1:n  ある条件で子テーブルを検索し、合致 する親テーブルを取得したい  具体的には : 商品 (1) : 在庫・価格 (n)
  • 5. SQL の場合  子テーブルに親テーブルを JOIN  検索結果を親のキーで DISTINCT  Groonga の場合、素直にはできない  ※ ドリルダウンすれば 2 度引きで可能
  • 6. Groonga の場合  子テーブルで検索する  重複するキーを filter で捨てる  filter で使える関数を自作する必要があ る
  • 7. 自作する関数の仕様  引数として親のキー( _key )をとる  格納済かどうかを返す  Int32 distinct(ShortText parent_key)
  • 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. とりあえず版 登録 proc.c ... grn_proc_create(ctx, "distinct", 8, GRN_PROC_FUNCTION, func_distinct, NULL, NULL, 0, NULL); ...
  • 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. とりあえず版 中身 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. 適当にビルドしてみる  lib/ に distinct.cc を追加して make  よくわからないエラー  ../lib/.libs/libgroonga.so: undefined reference to `__cxa_begin_catch‘  g++ 経由でリンクしないと駄目
  • 13. 正式なやり方  configure.ac に AC_PROG_CXX を追加  lib/Makefile.am の libgroonga_la_SOURCES に distinct.cc を追加  autoreconf で configure を再生成
  • 14. autoreconf への道  色々更新が必要  autoconf-2.67  automake-1.11.1  libtool-2.2.6b  激しく遠い道のりなので以下略
  • 15. 手抜き  Makefile.in に追記  .SUFFIXES に .cc を追加  CCLD を gcc から g++ に変更  ビルドルールに .cc.o を追加
  • 16. デモ  商品テーブル item  ShortText 型 description  3 件  在庫テーブル stock  item 型 i  Time 型 date  Int32 型 price  9 件
  • 17. distinct なし  select --table stock --output_columns i._key,price  → i._key が重複する
  • 18. distinct あり  select --table stock --filter "distinct(i._key)" --output_columns i._key,price  → i._key が重複しない
  • 19. end of file

×