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