[Groonga-commit] groonga/groonga [master] Now command suggest supports types parameter.

Back to archive index

null+****@clear***** null+****@clear*****
2010年 8月 26日 (木) 18:14:15 JST


Tasuku SUENAGA a.k.a. gunyarakun	2010-08-26 09:14:15 +0000 (Thu, 26 Aug 2010)

  New Revision: f6f3bf62a90eb8d69556bbfe8b7d785441b92c3e

  Log:
    Now command suggest supports types parameter.

  Modified files:
    doc/ja/source/commands/suggest.txt
    modules/suggest/suggest.c

  Modified: doc/ja/source/commands/suggest.txt (+2 -2)
===================================================================
--- doc/ja/source/commands/suggest.txt    2010-08-26 09:00:29 +0000 (6202fda)
+++ doc/ja/source/commands/suggest.txt    2010-08-26 09:14:15 +0000 (846bd7b)
@@ -14,7 +14,7 @@ suggest - 指定したクエリに対する補完・修正・提案を行う。
 ----
 ::
 
- suggest type table column query
+ suggest types table column query
 
 説明
 ----
@@ -26,7 +26,7 @@ suggestコマンドは、指定したクエリに対して補完・修正・提
 引数
 ----
 
-``type``
+``types``
 
   補完・修正・提案のいずれを行うかを、パイプ('|')で組み合わせたシンボル名で指定します(例: correct|suggest)
 

  Modified: modules/suggest/suggest.c (+117 -83)
===================================================================
--- modules/suggest/suggest.c    2010-08-26 09:00:29 +0000 (56dc239)
+++ modules/suggest/suggest.c    2010-08-26 09:14:15 +0000 (17bbc31)
@@ -23,15 +23,43 @@
 #define CONST_STR_LEN(x) x, x ? sizeof(x) - 1 : 0
 #define VAR GRN_PROC_GET_VAR_BY_OFFSET
 
+static int
+grn_parse_suggest_types(const char *nptr, const char *end)
+{
+  int types = 0;
+  while (nptr < end) {
+    if (*nptr == '|') {
+      nptr += 1;
+      continue;
+    }
+    if (!memcmp(nptr, CONST_STR_LEN("complete"))) {
+      types |= 1;
+      nptr += sizeof("complete") - 1;
+    }
+    if (!memcmp(nptr, CONST_STR_LEN("correct"))) {
+      types |= 2;
+      nptr += sizeof("correct") - 1;
+    }
+    if (!memcmp(nptr, CONST_STR_LEN("suggest"))) {
+      types |= 4;
+      nptr += sizeof("suggest") - 1;
+    }
+  }
+  return types;
+}
+
 static grn_obj *
 command_suggest(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
 {
+  int types;
   grn_obj *table;
-  if ((table = grn_ctx_get(ctx, GRN_TEXT_VALUE(VAR(0)),
-                           GRN_TEXT_LEN(VAR(0))))) {
+  types = grn_parse_suggest_types(GRN_TEXT_VALUE(VAR(0)), GRN_BULK_CURR(VAR(0)));
+
+  if ((table = grn_ctx_get(ctx, GRN_TEXT_VALUE(VAR(1)),
+                           GRN_TEXT_LEN(VAR(1))))) {
     grn_obj *col;
-    if ((col = grn_obj_column(ctx, table, GRN_TEXT_VALUE(VAR(1)),
-                              GRN_TEXT_LEN(VAR(1))))) {
+    if ((col = grn_obj_column(ctx, table, GRN_TEXT_VALUE(VAR(2)),
+                              GRN_TEXT_LEN(VAR(2))))) {
       grn_obj *res;
       if ((res = grn_table_create(ctx, NULL, 0, NULL,
                                    GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC, table, NULL))) {
@@ -39,60 +67,62 @@ command_suggest(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_dat
         if ((sorted = grn_table_create(ctx, NULL, 0, NULL,
                                        GRN_OBJ_TABLE_NO_KEY, NULL, res))) {
           grn_str *norm;
-          if ((norm = grn_str_open(ctx, GRN_TEXT_VALUE(VAR(2)), GRN_TEXT_LEN(VAR(2)),
+          if ((norm = grn_str_open(ctx, GRN_TEXT_VALUE(VAR(3)), GRN_TEXT_LEN(VAR(3)),
                                    GRN_STR_NORMALIZE))) {
-#if 1
-            /* RK search + prefix search */
-            grn_obj *index;
-            /* FIXME: support index selection */
-            if (grn_column_index(ctx, col, GRN_OP_PREFIX,
-                                 &index, 1, NULL)) {
-              grn_table_cursor *cur;
-              if ((cur = grn_table_cursor_open(ctx, grn_ctx_at(ctx, index->header.domain),
-                                               norm->norm, norm->norm_blen,
-                                               NULL, 0,
-                                               0, -1,
-                                               GRN_CURSOR_PREFIX | GRN_CURSOR_RK))) {
-                grn_id id;
-                while ((id = grn_table_cursor_next(ctx, cur))) {
-                  grn_ii_cursor *icur;
-                  if ((icur = grn_ii_cursor_open(ctx, (grn_ii *)index, id,
-                                                 GRN_ID_NIL, GRN_ID_MAX, 1, 0))) {
-                    grn_ii_posting *p;
-                    while ((p = grn_ii_cursor_next(ctx, icur))) {
-                      grn_hash_add(ctx, (grn_hash *)res, &p->rid, sizeof(grn_id), NULL, NULL);
-                      /* FIXME: execute _score = score */
+            if (types & 1) {
+              /* RK search + prefix search */
+              grn_obj *index;
+              /* FIXME: support index selection */
+              if (grn_column_index(ctx, col, GRN_OP_PREFIX,
+                                   &index, 1, NULL)) {
+                grn_table_cursor *cur;
+                if ((cur = grn_table_cursor_open(ctx, grn_ctx_at(ctx, index->header.domain),
+                                                 norm->norm, norm->norm_blen,
+                                                 NULL, 0,
+                                                 0, -1,
+                                                 GRN_CURSOR_PREFIX | GRN_CURSOR_RK))) {
+                  grn_id id;
+                  while ((id = grn_table_cursor_next(ctx, cur))) {
+                    grn_ii_cursor *icur;
+                    if ((icur = grn_ii_cursor_open(ctx, (grn_ii *)index, id,
+                                                   GRN_ID_NIL, GRN_ID_MAX, 1, 0))) {
+                      grn_ii_posting *p;
+                      while ((p = grn_ii_cursor_next(ctx, icur))) {
+                        grn_hash_add(ctx, (grn_hash *)res, &p->rid, sizeof(grn_id), NULL, NULL);
+                        /* FIXME: execute _score = score */
+                      }
+                      grn_ii_cursor_close(ctx, icur);
                     }
-                    grn_ii_cursor_close(ctx, icur);
                   }
+                  grn_table_cursor_close(ctx, cur);
+                } else {
+                  ERR(GRN_UNKNOWN_ERROR, "cannot open cursor for pk.");
+                  goto exit;
                 }
-                grn_table_cursor_close(ctx, cur);
-              } else {
-                ERR(GRN_UNKNOWN_ERROR, "cannot open cursor for pk.");
-                goto exit;
-              }
 
-              if ((cur = grn_table_cursor_open(ctx, table,
-                                               GRN_TEXT_VALUE(VAR(2)), GRN_TEXT_LEN(VAR(2)),
-                                               NULL, 0, 0, -1, GRN_CURSOR_PREFIX))) {
-                grn_id id;
-                while ((id = grn_table_cursor_next(ctx, cur))) {
-                  grn_hash_add(ctx, (grn_hash *)res, &id, sizeof(grn_id), NULL, NULL);
+                if ((cur = grn_table_cursor_open(ctx, table,
+                                                 GRN_TEXT_VALUE(VAR(3)), GRN_TEXT_LEN(VAR(3)),
+                                                 NULL, 0, 0, -1, GRN_CURSOR_PREFIX))) {
+                  grn_id id;
+                  while ((id = grn_table_cursor_next(ctx, cur))) {
+                    grn_hash_add(ctx, (grn_hash *)res, &id, sizeof(grn_id), NULL, NULL);
+                  }
+                  grn_table_cursor_close(ctx, cur);
                 }
-                grn_table_cursor_close(ctx, cur);
+              } else {
+                ERR(GRN_UNKNOWN_ERROR, "cannot find index for prefix search.");
               }
-            } else {
-              ERR(GRN_UNKNOWN_ERROR, "cannot find index for prefix search.");
-              goto exit;
+              grn_str_close(ctx, norm);
             }
-#else
+          }
+          if (types & 2) {
             grn_select_optarg optarg;
             memset(&optarg, 0, sizeof(grn_select_optarg));
             optarg.mode = GRN_OP_SIMILAR;
             optarg.similarity_threshold = 1048576;
 
             grn_ii_select(ctx, (grn_ii *)grn_ctx_get(ctx, CONST_STR_LEN("SuggestBigram.suggest_key")),
-                          GRN_TEXT_VALUE(VAR(2)), GRN_TEXT_LEN(VAR(2)),
+                          GRN_TEXT_VALUE(VAR(3)), GRN_TEXT_LEN(VAR(3)),
                           (grn_hash *)res, GRN_OP_OR, &optarg);
             {
               /* exec _score = edit_distance(_key, "query string") for all records */
@@ -128,51 +158,53 @@ command_suggest(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_dat
                 goto exit;
               }
             }
-#endif
-            /* sort */
-            {
-              uint32_t nkeys;
-              grn_obj *score_col;
-              grn_table_sort_key *keys;
-              score_col = grn_obj_column(ctx, res, CONST_STR_LEN("_score"));
-              /* FIXME: use grn_table_sort instead */
-              if ((keys = grn_table_sort_key_from_str(ctx, CONST_STR_LEN("-_score"), res, &nkeys))) {
-                grn_table_cursor *scur;
-                /* TODO: support offset limit */
-                grn_table_sort(ctx, res, 0, grn_table_size(ctx, res), sorted, keys, nkeys);
-                GRN_OUTPUT_ARRAY_OPEN("RESULTS", -1);
-                if ((scur = grn_table_cursor_open(ctx, sorted, NULL, 0, NULL, 0, 0, -1, 0))) {
-                  grn_id id;
-                  while ((id = grn_table_cursor_next(ctx, scur))) {
-                    grn_id res_id;
-                    unsigned int key_len;
-                    char key[GRN_TABLE_MAX_KEY_SIZE];
-                    grn_obj score_val;
+          }
+          if (types & 4) {
+          }
+          if (ctx->rc) { goto exit; }
 
-                    GRN_OUTPUT_ARRAY_OPEN("RESULT", 2);
-                    grn_table_get_key(ctx, sorted, id, &res_id, sizeof(grn_id));
-                    grn_table_get_key(ctx, res, res_id, &id, sizeof(grn_id));
-                    key_len = grn_table_get_key(ctx, table, id, key, GRN_TABLE_MAX_KEY_SIZE);
-                    GRN_OUTPUT_STR(key, key_len);
+          /* sort */
+          {
+            uint32_t nkeys;
+            grn_obj *score_col;
+            grn_table_sort_key *keys;
+            score_col = grn_obj_column(ctx, res, CONST_STR_LEN("_score"));
+            /* FIXME: use grn_table_sort instead */
+            if ((keys = grn_table_sort_key_from_str(ctx, CONST_STR_LEN("-_score"), res, &nkeys))) {
+              grn_table_cursor *scur;
+              /* TODO: support offset limit */
+              grn_table_sort(ctx, res, 0, grn_table_size(ctx, res), sorted, keys, nkeys);
+              GRN_OUTPUT_ARRAY_OPEN("RESULTS", -1);
+              if ((scur = grn_table_cursor_open(ctx, sorted, NULL, 0, NULL, 0, 0, -1, 0))) {
+                grn_id id;
+                while ((id = grn_table_cursor_next(ctx, scur))) {
+                  grn_id res_id;
+                  unsigned int key_len;
+                  char key[GRN_TABLE_MAX_KEY_SIZE];
+                  grn_obj score_val;
 
-                    GRN_INT32_INIT(&score_val, 0);
-                    grn_obj_get_value(ctx, score_col, res_id, &score_val);
-                    GRN_OUTPUT_INT32(GRN_INT32_VALUE(&score_val));
-                    GRN_OUTPUT_ARRAY_CLOSE();
-                  }
-                  grn_table_cursor_close(ctx, scur);
-                } else {
-                  ERR(GRN_UNKNOWN_ERROR, "cannot open sorted cursor.");
+                  GRN_OUTPUT_ARRAY_OPEN("RESULT", 2);
+                  grn_table_get_key(ctx, sorted, id, &res_id, sizeof(grn_id));
+                  grn_table_get_key(ctx, res, res_id, &id, sizeof(grn_id));
+                  key_len = grn_table_get_key(ctx, table, id, key, GRN_TABLE_MAX_KEY_SIZE);
+                  GRN_OUTPUT_STR(key, key_len);
+
+                  GRN_INT32_INIT(&score_val, 0);
+                  grn_obj_get_value(ctx, score_col, res_id, &score_val);
+                  GRN_OUTPUT_INT32(GRN_INT32_VALUE(&score_val));
+                  GRN_OUTPUT_ARRAY_CLOSE();
                 }
-                GRN_OUTPUT_ARRAY_CLOSE();
-                grn_table_sort_key_close(ctx, keys, nkeys);
+                grn_table_cursor_close(ctx, scur);
               } else {
-                ERR(GRN_UNKNOWN_ERROR, "cannot sort.");
+                ERR(GRN_UNKNOWN_ERROR, "cannot open sorted cursor.");
               }
+              GRN_OUTPUT_ARRAY_CLOSE();
+              grn_table_sort_key_close(ctx, keys, nkeys);
+            } else {
+              ERR(GRN_UNKNOWN_ERROR, "cannot sort.");
             }
-exit:
-            grn_str_close(ctx, norm);
           }
+exit:
           grn_obj_close(ctx, sorted);
         } else {
           ERR(GRN_UNKNOWN_ERROR, "cannot create temporary sort table.");
@@ -301,6 +333,7 @@ grn_module_register_suggest(grn_ctx *ctx)
 {
   /* TODO: offset/limit */
   grn_expr_var vars[] = {
+    {CONST_STR_LEN("types")},
     {CONST_STR_LEN("table")},
     {CONST_STR_LEN("column")},
     {CONST_STR_LEN("query")}
@@ -308,8 +341,9 @@ grn_module_register_suggest(grn_ctx *ctx)
   GRN_TEXT_INIT(&vars[0].value, 0);
   GRN_TEXT_INIT(&vars[1].value, 0);
   GRN_TEXT_INIT(&vars[2].value, 0);
+  GRN_TEXT_INIT(&vars[3].value, 0);
   grn_proc_create(ctx, CONST_STR_LEN("suggest"), GRN_PROC_COMMAND,
-                  command_suggest, NULL, NULL, 3, vars);
+                  command_suggest, NULL, NULL, 4, vars);
 
   grn_proc_create(ctx, CONST_STR_LEN("suggest_preparer"), GRN_PROC_FUNCTION,
                   func_suggest_preparer, NULL, NULL, 0, NULL);




Groonga-commit メーリングリストの案内
Back to archive index