[Groonga-commit] groonga/groonga at 170da9f [master] Add grn_operator_exec_prefix()

Back to archive index

Kouhei Sutou null+****@clear*****
Tue Mar 10 16:27:58 JST 2015


Kouhei Sutou	2015-03-10 16:27:58 +0900 (Tue, 10 Mar 2015)

  New Revision: 170da9fe79acbcc2dca101146a3c912c16a9f2b6
  https://github.com/groonga/groonga/commit/170da9fe79acbcc2dca101146a3c912c16a9f2b6

  Message:
    Add grn_operator_exec_prefix()

  Modified files:
    include/groonga/groonga.h
    lib/expr.c
    lib/operator.c
    test/unit/core/test-operator.c

  Modified: include/groonga/groonga.h (+2 -0)
===================================================================
--- include/groonga/groonga.h    2015-03-10 16:18:09 +0900 (79e8812)
+++ include/groonga/groonga.h    2015-03-10 16:27:58 +0900 (704778f)
@@ -726,6 +726,8 @@ GRN_API grn_bool grn_operator_exec_greater_equal(grn_ctx *ctx,
                                                  grn_obj *x, grn_obj *y);
 GRN_API grn_bool grn_operator_exec_match(grn_ctx *ctx,
                                          grn_obj *target, grn_obj *sub_text);
+GRN_API grn_bool grn_operator_exec_prefix(grn_ctx *ctx,
+                                          grn_obj *target, grn_obj *prefix);
 
 struct _grn_table_group_result {
   grn_obj *table;

  Modified: lib/expr.c (+1 -122)
===================================================================
--- lib/expr.c    2015-03-10 16:18:09 +0900 (1f627ce)
+++ lib/expr.c    2015-03-10 16:27:58 +0900 (b21ff3f)
@@ -2222,127 +2222,6 @@ grn_proc_call(grn_ctx *ctx, grn_obj *proc, int nargs, grn_obj *caller)
   }                                                                     \
 } while (0)
 
-static grn_bool
-pseudo_prefix_search_match(grn_ctx *ctx,
-                           const char *x, unsigned int x_len,
-                           const char *y, unsigned int y_len)
-{
-  return (x_len >= y_len && strncmp(x, y, y_len) == 0);
-}
-
-static grn_bool
-pseudo_prefix_search_raw_text_raw_text(grn_ctx *ctx,
-                                       const char *x, unsigned int x_len,
-                                       const char *y, unsigned int y_len)
-{
-  grn_obj *normalizer;
-  grn_obj *norm_x;
-  grn_obj *norm_y;
-  const char *norm_x_raw;
-  const char *norm_y_raw;
-  unsigned int norm_x_raw_len;
-  unsigned int norm_y_raw_len;
-  grn_bool matched = GRN_FALSE;
-
-  normalizer = grn_ctx_get(ctx, GRN_NORMALIZER_AUTO_NAME, -1);
-  norm_x = grn_string_open(ctx, x, x_len, normalizer, 0);
-  norm_y = grn_string_open(ctx, y, y_len, normalizer, 0);
-  grn_string_get_normalized(ctx, norm_x, &norm_x_raw, &norm_x_raw_len, NULL);
-  grn_string_get_normalized(ctx, norm_y, &norm_y_raw, &norm_y_raw_len, NULL);
-  matched = pseudo_prefix_search_match(ctx,
-                                       norm_x_raw, norm_x_raw_len,
-                                       norm_y_raw, norm_y_raw_len);
-
-  grn_obj_close(ctx, norm_x);
-  grn_obj_close(ctx, norm_y);
-  grn_obj_unlink(ctx, normalizer);
-
-  return matched;
-}
-
-static grn_bool
-pseudo_prefix_search_record_text(grn_ctx *ctx, grn_obj *record, grn_obj *table,
-                                 grn_obj *y)
-{
-  grn_obj *normalizer;
-  char x_key[GRN_TABLE_MAX_KEY_SIZE];
-  int x_key_len;
-  grn_bool matched = GRN_FALSE;
-
-  if (table->header.domain != GRN_DB_SHORT_TEXT) {
-    return GRN_FALSE;
-  }
-
-  x_key_len = grn_table_get_key(ctx, table, GRN_RECORD_VALUE(record),
-                                x_key, GRN_TABLE_MAX_KEY_SIZE);
-  grn_table_get_info(ctx, table, NULL, NULL, NULL, &normalizer, NULL);
-  if (normalizer) {
-    grn_obj *norm_y;
-    const char *norm_y_raw;
-    unsigned int norm_y_raw_len;
-    norm_y = grn_string_open(ctx, GRN_TEXT_VALUE(y), GRN_TEXT_LEN(y),
-                             normalizer, 0);
-    grn_string_get_normalized(ctx, norm_y, &norm_y_raw, &norm_y_raw_len, NULL);
-    matched = pseudo_prefix_search_match(ctx,
-                                         x_key, x_key_len,
-                                         norm_y_raw, norm_y_raw_len);
-    grn_obj_close(ctx, norm_y);
-  } else {
-    matched = pseudo_prefix_search_raw_text_raw_text(ctx,
-                                                     x_key,
-                                                     x_key_len,
-                                                     GRN_TEXT_VALUE(y),
-                                                     GRN_TEXT_LEN(y));
-  }
-
-  return matched;
-}
-
-static grn_bool
-pseudo_prefix_search_text_text(grn_ctx *ctx, grn_obj *x, grn_obj *y)
-{
-  return pseudo_prefix_search_raw_text_raw_text(ctx,
-                                                GRN_TEXT_VALUE(x),
-                                                GRN_TEXT_LEN(x),
-                                                GRN_TEXT_VALUE(y),
-                                                GRN_TEXT_LEN(y));
-}
-
-static grn_bool
-pseudo_prefix_search(grn_ctx *ctx, grn_obj *x, grn_obj *y)
-{
-  switch (x->header.domain) {
-  case GRN_DB_SHORT_TEXT :
-  case GRN_DB_TEXT :
-  case GRN_DB_LONG_TEXT :
-    switch (y->header.domain) {
-    case GRN_DB_SHORT_TEXT :
-    case GRN_DB_TEXT :
-    case GRN_DB_LONG_TEXT :
-      return pseudo_prefix_search_text_text(ctx, x, y);
-    default :
-      break;
-    }
-    return GRN_FALSE;
-  default:
-    {
-      grn_obj *domain;
-      domain = grn_ctx_at(ctx, x->header.domain);
-      if (GRN_OBJ_TABLEP(domain)) {
-        switch (y->header.domain) {
-        case GRN_DB_SHORT_TEXT :
-        case GRN_DB_TEXT :
-        case GRN_DB_LONG_TEXT :
-          return pseudo_prefix_search_record_text(ctx, x, domain, y);
-        default :
-          break;
-        }
-      }
-    }
-    return GRN_FALSE;
-  }
-}
-
 inline static void
 grn_expr_exec_get_member(grn_ctx *ctx,
                          grn_obj *expr,
@@ -3092,7 +2971,7 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs)
           POP1(y);
           POP1(x);
           WITH_SPSAVE({
-            matched = pseudo_prefix_search(ctx, x, y);
+            matched = grn_operator_exec_prefix(ctx, x, y);
           });
           ALLOC1(res);
           grn_obj_reinit(ctx, res, GRN_DB_INT32, 0);

  Modified: lib/operator.c (+152 -0)
===================================================================
--- lib/operator.c    2015-03-10 16:18:09 +0900 (11693a6)
+++ lib/operator.c    2015-03-10 16:27:58 +0900 (c1a8a5e)
@@ -769,3 +769,155 @@ grn_operator_exec_match(grn_ctx *ctx, grn_obj *target, grn_obj *sub_text)
   matched = grn_operator_exec_match_bulk_bulk(ctx, target, sub_text);
   GRN_API_RETURN(matched);
 }
+
+static grn_bool
+string_have_prefix(grn_ctx *ctx,
+                   const char *target, unsigned int target_len,
+                   const char *prefix, unsigned int prefix_len)
+{
+  return (target_len >= prefix_len &&
+          strncmp(target, prefix, prefix_len) == 0);
+}
+
+static grn_bool
+grn_operator_exec_prefix_raw_text_raw_text(grn_ctx *ctx,
+                                           const char *target,
+                                           unsigned int target_len,
+                                           const char *prefix,
+                                           unsigned int prefix_len)
+{
+  grn_obj *normalizer;
+  grn_obj *norm_target;
+  grn_obj *norm_prefix;
+  const char *norm_target_raw;
+  const char *norm_prefix_raw;
+  unsigned int norm_target_raw_len;
+  unsigned int norm_prefix_raw_len;
+  grn_bool matched = GRN_FALSE;
+
+  normalizer = grn_ctx_get(ctx, GRN_NORMALIZER_AUTO_NAME, -1);
+  norm_target = grn_string_open(ctx, target, target_len, normalizer, 0);
+  norm_prefix = grn_string_open(ctx, prefix, prefix_len, normalizer, 0);
+  grn_string_get_normalized(ctx,
+                            norm_target,
+                            &norm_target_raw,
+                            &norm_target_raw_len,
+                            NULL);
+  grn_string_get_normalized(ctx,
+                            norm_prefix,
+                            &norm_prefix_raw,
+                            &norm_prefix_raw_len,
+                            NULL);
+  matched = string_have_prefix(ctx,
+                               norm_target_raw, norm_target_raw_len,
+                               norm_prefix_raw, norm_prefix_raw_len);
+
+  grn_obj_close(ctx, norm_target);
+  grn_obj_close(ctx, norm_prefix);
+  grn_obj_unlink(ctx, normalizer);
+
+  return matched;
+}
+
+static grn_bool
+grn_operator_exec_prefix_record_text(grn_ctx *ctx,
+                                     grn_obj *record, grn_obj *table,
+                                     grn_obj *prefix)
+{
+  grn_obj *normalizer;
+  char record_key[GRN_TABLE_MAX_KEY_SIZE];
+  int record_key_len;
+  grn_bool matched = GRN_FALSE;
+
+  if (table->header.domain != GRN_DB_SHORT_TEXT) {
+    return GRN_FALSE;
+  }
+
+  record_key_len = grn_table_get_key(ctx, table, GRN_RECORD_VALUE(record),
+                                     record_key, GRN_TABLE_MAX_KEY_SIZE);
+  grn_table_get_info(ctx, table, NULL, NULL, NULL, &normalizer, NULL);
+  if (normalizer) {
+    grn_obj *norm_prefix;
+    const char *norm_prefix_raw;
+    unsigned int norm_prefix_raw_len;
+    norm_prefix = grn_string_open(ctx,
+                                  GRN_TEXT_VALUE(prefix), GRN_TEXT_LEN(prefix),
+                                  normalizer, 0);
+    grn_string_get_normalized(ctx,
+                              norm_prefix,
+                              &norm_prefix_raw,
+                              &norm_prefix_raw_len,
+                              NULL);
+    matched = string_have_prefix(ctx,
+                                 record_key, record_key_len,
+                                 norm_prefix_raw, norm_prefix_raw_len);
+    grn_obj_close(ctx, norm_prefix);
+  } else {
+    matched = grn_operator_exec_prefix_raw_text_raw_text(ctx,
+                                                         record_key,
+                                                         record_key_len,
+                                                         GRN_TEXT_VALUE(prefix),
+                                                         GRN_TEXT_LEN(prefix));
+  }
+
+  return matched;
+}
+
+static grn_bool
+grn_operator_exec_prefix_text_text(grn_ctx *ctx,
+                                   grn_obj *target,
+                                   grn_obj *prefix)
+{
+  return grn_operator_exec_prefix_raw_text_raw_text(ctx,
+                                                    GRN_TEXT_VALUE(target),
+                                                    GRN_TEXT_LEN(target),
+                                                    GRN_TEXT_VALUE(prefix),
+                                                    GRN_TEXT_LEN(prefix));
+}
+
+static grn_bool
+grn_operator_exec_prefix_bulk_bulk(grn_ctx *ctx,
+                                   grn_obj *target,
+                                   grn_obj *prefix)
+{
+  switch (target->header.domain) {
+  case GRN_DB_SHORT_TEXT :
+  case GRN_DB_TEXT :
+  case GRN_DB_LONG_TEXT :
+    switch (prefix->header.domain) {
+    case GRN_DB_SHORT_TEXT :
+    case GRN_DB_TEXT :
+    case GRN_DB_LONG_TEXT :
+      return grn_operator_exec_prefix_text_text(ctx, target, prefix);
+    default :
+      break;
+    }
+    return GRN_FALSE;
+  default:
+    {
+      grn_obj *domain;
+      domain = grn_ctx_at(ctx, target->header.domain);
+      if (GRN_OBJ_TABLEP(domain)) {
+        switch (prefix->header.domain) {
+        case GRN_DB_SHORT_TEXT :
+        case GRN_DB_TEXT :
+        case GRN_DB_LONG_TEXT :
+          return grn_operator_exec_prefix_record_text(ctx, target, domain,
+                                                      prefix);
+        default :
+          break;
+        }
+      }
+    }
+    return GRN_FALSE;
+  }
+}
+
+grn_bool
+grn_operator_exec_prefix(grn_ctx *ctx, grn_obj *target, grn_obj *prefix)
+{
+  grn_bool matched;
+  GRN_API_ENTER;
+  matched = grn_operator_exec_prefix_bulk_bulk(ctx, target, prefix);
+  GRN_API_RETURN(matched);
+}

  Modified: test/unit/core/test-operator.c (+60 -0)
===================================================================
--- test/unit/core/test-operator.c    2015-03-10 16:18:09 +0900 (ce3a137)
+++ test/unit/core/test-operator.c    2015-03-10 16:27:58 +0900 (7bfddb2)
@@ -53,6 +53,10 @@ void data_exec_match_true(void);
 void test_exec_match_true(gconstpointer data);
 void data_exec_match_false(void);
 void test_exec_match_false(gconstpointer data);
+void data_exec_prefix_true(void);
+void test_exec_prefix_true(gconstpointer data);
+void data_exec_prefix_false(void);
+void test_exec_prefix_false(gconstpointer data);
 
 static gchar *tmp_directory;
 
@@ -516,3 +520,59 @@ test_exec_match_false(gconstpointer data)
   set_text(&rhs, "lo!");
   cut_assert_false(grn_operator_exec_match(context, &lhs, &rhs));
 }
+
+void
+data_exec_prefix_true(void)
+{
+#define ADD_DATA(lhs_type, rhs_type)                            \
+  gcut_add_datum(lhs_type " @^ " rhs_type,                      \
+                 "lhs_type", G_TYPE_STRING, lhs_type,           \
+                 "rhs_type", G_TYPE_STRING, rhs_type,           \
+                 NULL)
+
+  ADD_DATA("text", "text");
+
+#undef ADD_DATA
+}
+
+void
+test_exec_prefix_true(gconstpointer data)
+{
+  const gchar *lhs_type;
+  const gchar *rhs_type;
+
+  lhs_type = gcut_data_get_string(data, "lhs_type");
+  rhs_type = gcut_data_get_string(data, "rhs_type");
+
+  set_text(&lhs, "Hello");
+  set_text(&rhs, "He");
+  cut_assert_true(grn_operator_exec_prefix(context, &lhs, &rhs));
+}
+
+void
+data_exec_prefix_false(void)
+{
+#define ADD_DATA(lhs_type, rhs_type)                            \
+  gcut_add_datum(lhs_type " @^ " rhs_type,                      \
+                 "lhs_type", G_TYPE_STRING, lhs_type,           \
+                 "rhs_type", G_TYPE_STRING, rhs_type,           \
+                 NULL)
+
+  ADD_DATA("text", "text");
+
+#undef ADD_DATA
+}
+
+void
+test_exec_prefix_false(gconstpointer data)
+{
+  const gchar *lhs_type;
+  const gchar *rhs_type;
+
+  lhs_type = gcut_data_get_string(data, "lhs_type");
+  rhs_type = gcut_data_get_string(data, "rhs_type");
+
+  set_text(&lhs, "Hello");
+  set_text(&rhs, "ell");
+  cut_assert_false(grn_operator_exec_prefix(context, &lhs, &rhs));
+}
-------------- next part --------------
HTML����������������������������...
Download 



More information about the Groonga-commit mailing list
Back to archive index