susumu.yata
null+****@clear*****
Wed Sep 9 20:52:00 JST 2015
susumu.yata 2015-09-09 20:52:00 +0900 (Wed, 09 Sep 2015) New Revision: 1808edab4d5fb5846bb5d2e28b95404c70ca3f84 https://github.com/groonga/groonga/commit/1808edab4d5fb5846bb5d2e28b95404c70ca3f84 Message: grn_ts: implement a comparison operator "!=" GitHub: #386 Modified files: lib/ts.c Modified: lib/ts.c (+215 -1) =================================================================== --- lib/ts.c 2015-09-09 20:35:10 +0900 (069a214) +++ lib/ts.c 2015-09-09 20:52:00 +0900 (6d4b61e) @@ -640,6 +640,93 @@ grn_ts_op_equal_geo_point_vector(grn_ts_geo_point_vector lhs, } #undef GRN_TS_OP_EQUAL_VECTOR +/* grn_ts_op_not_equal_bool() returns lhs != rhs. */ +inline static grn_bool +grn_ts_op_not_equal_bool(grn_ts_bool lhs, grn_ts_bool rhs) { + return lhs != rhs; +} + +/* grn_ts_op_not_equal_int() returns lhs != rhs. */ +inline static grn_bool +grn_ts_op_not_equal_int(grn_ts_int lhs, grn_ts_int rhs) { + return lhs != rhs; +} + +/* grn_ts_op_not_equal_float() returns lhs != rhs. */ +inline static grn_bool +grn_ts_op_not_equal_float(grn_ts_float lhs, grn_ts_float rhs) { + /* To suppress warnings, "lhs != rhs" is not used. */ + return (lhs < rhs) || (lhs > rhs); +} + +/* grn_ts_op_not_equal_time() returns lhs != rhs. */ +inline static grn_bool +grn_ts_op_not_equal_time(grn_ts_time lhs, grn_ts_time rhs) { + return lhs != rhs; +} + +/* grn_ts_op_not_equal_text() returns lhs != rhs. */ +inline static grn_bool +grn_ts_op_not_equal_text(grn_ts_text lhs, grn_ts_text rhs) { + return (lhs.size != rhs.size) && !memcmp(lhs.ptr, rhs.ptr, lhs.size); +} + +/* grn_ts_op_not_equal_geo_point() returns lhs != rhs. */ +inline static grn_bool +grn_ts_op_not_equal_geo_point(grn_ts_geo_point lhs, grn_ts_geo_point rhs) { + return (lhs.latitude != rhs.latitude) && (lhs.longitude != rhs.longitude); +} + +#define GRN_TS_OP_NOT_EQUAL_VECTOR(kind)\ + size_t i;\ + if (lhs.size != rhs.size) {\ + return GRN_FALSE;\ + }\ + for (i = 0; i < lhs.size; i++) {\ + if (!grn_ts_op_not_equal_ ## kind(lhs.ptr[i], rhs.ptr[i])) {\ + return GRN_FALSE;\ + }\ + }\ + return GRN_TRUE; +/* grn_ts_op_not_equal_bool_vector() returns lhs != rhs. */ +inline static grn_bool +grn_ts_op_not_equal_bool_vector(grn_ts_bool_vector lhs, grn_ts_bool_vector rhs) { + GRN_TS_OP_NOT_EQUAL_VECTOR(bool) +} + +/* grn_ts_op_not_equal_int_vector() returns lhs != rhs. */ +inline static grn_bool +grn_ts_op_not_equal_int_vector(grn_ts_int_vector lhs, grn_ts_int_vector rhs) { + GRN_TS_OP_NOT_EQUAL_VECTOR(int) +} + +/* grn_ts_op_not_equal_float_vector() returns lhs != rhs. */ +inline static grn_bool +grn_ts_op_not_equal_float_vector(grn_ts_float_vector lhs, + grn_ts_float_vector rhs) { + GRN_TS_OP_NOT_EQUAL_VECTOR(float) +} + +/* grn_ts_op_not_equal_time_vector() returns lhs != rhs. */ +inline static grn_bool +grn_ts_op_not_equal_time_vector(grn_ts_time_vector lhs, grn_ts_time_vector rhs) { + GRN_TS_OP_NOT_EQUAL_VECTOR(time) +} + +/* grn_ts_op_not_equal_text_vector() returns lhs != rhs. */ +inline static grn_bool +grn_ts_op_not_equal_text_vector(grn_ts_text_vector lhs, grn_ts_text_vector rhs) { + GRN_TS_OP_NOT_EQUAL_VECTOR(text) +} + +/* grn_ts_op_not_equal_geo_point_vector() returns lhs != rhs. */ +inline static grn_bool +grn_ts_op_not_equal_geo_point_vector(grn_ts_geo_point_vector lhs, + grn_ts_geo_point_vector rhs) { + GRN_TS_OP_NOT_EQUAL_VECTOR(geo_point) +} +#undef GRN_TS_OP_NOT_EQUAL_VECTOR + /*------------------------------------------------------------- * Groonga objects. */ @@ -2238,7 +2325,6 @@ grn_ts_op_logical_or_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node, return GRN_SUCCESS; } - #define GRN_TS_OP_EQUAL_EVALUATE_CASE_BLOCK(KIND, kind)\ case GRN_TS_ ## KIND: {\ grn_ts_ ## kind *buf_ptrs[] = {\ @@ -2308,6 +2394,76 @@ grn_ts_op_equal_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node, #undef GRN_TS_OP_EQUAL_EVALUATE_VECTOR_CASE_BLOCK #undef GRN_TS_OP_EQUAL_EVALUATE_CASE_BLOCK +#define GRN_TS_OP_NOT_EQUAL_EVALUATE_CASE_BLOCK(KIND, kind)\ + case GRN_TS_ ## KIND: {\ + grn_ts_ ## kind *buf_ptrs[] = {\ + (grn_ts_ ## kind *)node->bufs[0].ptr,\ + (grn_ts_ ## kind *)node->bufs[1].ptr\ + };\ + for (i = 0; i < n_in; i++) {\ + out_ptr[i] = grn_ts_op_not_equal_ ## kind(buf_ptrs[0][i],\ + buf_ptrs[1][i]);\ + }\ + return GRN_SUCCESS;\ + } +#define GRN_TS_OP_NOT_EQUAL_EVALUATE_VECTOR_CASE_BLOCK(KIND, kind)\ + GRN_TS_OP_NOT_EQUAL_EVALUATE_CASE_BLOCK(KIND ## _VECTOR, kind ## _vector) +/* grn_ts_op_not_equal_evaluate() evaluates an operator. */ +static grn_rc +grn_ts_op_not_equal_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node, + const grn_ts_record *in, size_t n_in, void *out) { + size_t i; + grn_rc rc; + grn_ts_bool *out_ptr = (grn_ts_bool *)out; + + if (node->args[0]->data_kind == GRN_TS_BOOL) { + /* + * Use the output buffer to put evaluation results of the 1st argument, + * because the data kind is same. + */ + rc = grn_ts_expr_node_evaluate(ctx, node->args[0], in, n_in, out); + if (rc == GRN_SUCCESS) { + grn_ts_buf *buf = &node->bufs[0]; + rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[1], in, n_in, buf); + if (rc == GRN_SUCCESS) { + grn_ts_bool *buf_ptr = (grn_ts_bool *)buf->ptr; + for (i = 0; i < n_in; i++) { + out_ptr[i] = grn_ts_op_not_equal_bool(out_ptr[i], buf_ptr[i]); + } + } + } + return rc; + } + + for (i = 0; i < 2; i++) { + rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[i], in, n_in, + &node->bufs[i]); + if (rc != GRN_SUCCESS) { + return rc; + } + } + switch (node->args[0]->data_kind) { + GRN_TS_OP_NOT_EQUAL_EVALUATE_CASE_BLOCK(INT, int) + GRN_TS_OP_NOT_EQUAL_EVALUATE_CASE_BLOCK(FLOAT, float) + GRN_TS_OP_NOT_EQUAL_EVALUATE_CASE_BLOCK(TIME, time) + GRN_TS_OP_NOT_EQUAL_EVALUATE_CASE_BLOCK(TEXT, text) + GRN_TS_OP_NOT_EQUAL_EVALUATE_CASE_BLOCK(GEO_POINT, geo_point) + // TODO: GRN_TS_REF. + GRN_TS_OP_NOT_EQUAL_EVALUATE_VECTOR_CASE_BLOCK(BOOL, bool) + GRN_TS_OP_NOT_EQUAL_EVALUATE_VECTOR_CASE_BLOCK(INT, int) + GRN_TS_OP_NOT_EQUAL_EVALUATE_VECTOR_CASE_BLOCK(FLOAT, float) + GRN_TS_OP_NOT_EQUAL_EVALUATE_VECTOR_CASE_BLOCK(TIME, time) + GRN_TS_OP_NOT_EQUAL_EVALUATE_VECTOR_CASE_BLOCK(TEXT, text) + GRN_TS_OP_NOT_EQUAL_EVALUATE_VECTOR_CASE_BLOCK(GEO_POINT, geo_point) + // TODO: GRN_TS_REF_VECTOR. + default: { + return GRN_INVALID_ARGUMENT; + } + } +} +#undef GRN_TS_OP_NOT_EQUAL_EVALUATE_VECTOR_CASE_BLOCK +#undef GRN_TS_OP_NOT_EQUAL_EVALUATE_CASE_BLOCK + /* grn_ts_expr_op_node_evaluate() evaluates an operator. */ static grn_rc grn_ts_expr_op_node_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node, @@ -2326,6 +2482,9 @@ grn_ts_expr_op_node_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node, case GRN_TS_OP_EQUAL: { return grn_ts_op_equal_evaluate(ctx, node, in, n_in, out); } + case GRN_TS_OP_NOT_EQUAL: { + return grn_ts_op_not_equal_evaluate(ctx, node, in, n_in, out); + } // TODO default: { return GRN_OPERATION_NOT_SUPPORTED; @@ -2472,6 +2631,58 @@ grn_ts_op_equal_filter(grn_ctx *ctx, grn_ts_expr_op_node *node, #undef GRN_TS_OP_EQUAL_FILTER_VECTOR_CASE_BLOCK #undef GRN_TS_OP_EQUAL_FILTER_CASE_BLOCK +#define GRN_TS_OP_NOT_EQUAL_FILTER_CASE_BLOCK(KIND, kind)\ + case GRN_TS_ ## KIND: {\ + grn_ts_ ## kind *buf_ptrs[] = {\ + (grn_ts_ ## kind *)node->bufs[0].ptr,\ + (grn_ts_ ## kind *)node->bufs[1].ptr\ + };\ + for (i = 0; i < n_in; i++) {\ + if (grn_ts_op_not_equal_ ## kind(buf_ptrs[0][i], buf_ptrs[1][i])) {\ + out[count++] = in[i];\ + }\ + }\ + *n_out = count;\ + return GRN_SUCCESS;\ + } +#define GRN_TS_OP_NOT_EQUAL_FILTER_VECTOR_CASE_BLOCK(KIND, kind)\ + GRN_TS_OP_NOT_EQUAL_FILTER_CASE_BLOCK(KIND ## _VECTOR, kind ## _vector) +/* grn_ts_op_not_equal_filter() filters records. */ +static grn_rc +grn_ts_op_not_equal_filter(grn_ctx *ctx, grn_ts_expr_op_node *node, + const grn_ts_record *in, size_t n_in, + grn_ts_record *out, size_t *n_out) { + size_t i, count; + for (i = 0; i < 2; i++) { + grn_rc rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[i], in, n_in, + &node->bufs[i]); + if (rc != GRN_SUCCESS) { + return rc; + } + } + switch (node->args[0]->data_kind) { + GRN_TS_OP_NOT_EQUAL_FILTER_CASE_BLOCK(BOOL, int) + GRN_TS_OP_NOT_EQUAL_FILTER_CASE_BLOCK(INT, int) + GRN_TS_OP_NOT_EQUAL_FILTER_CASE_BLOCK(FLOAT, float) + GRN_TS_OP_NOT_EQUAL_FILTER_CASE_BLOCK(TIME, time) + GRN_TS_OP_NOT_EQUAL_FILTER_CASE_BLOCK(TEXT, text) + GRN_TS_OP_NOT_EQUAL_FILTER_CASE_BLOCK(GEO_POINT, geo_point) + // TODO: GRN_TS_REF. + GRN_TS_OP_NOT_EQUAL_FILTER_VECTOR_CASE_BLOCK(BOOL, bool) + GRN_TS_OP_NOT_EQUAL_FILTER_VECTOR_CASE_BLOCK(INT, int) + GRN_TS_OP_NOT_EQUAL_FILTER_VECTOR_CASE_BLOCK(FLOAT, float) + GRN_TS_OP_NOT_EQUAL_FILTER_VECTOR_CASE_BLOCK(TIME, time) + GRN_TS_OP_NOT_EQUAL_FILTER_VECTOR_CASE_BLOCK(TEXT, text) + GRN_TS_OP_NOT_EQUAL_FILTER_VECTOR_CASE_BLOCK(GEO_POINT, geo_point) + // TODO: GRN_TS_REF_VECTOR. + default: { + return GRN_INVALID_ARGUMENT; + } + } +} +#undef GRN_TS_OP_NOT_EQUAL_FILTER_VECTOR_CASE_BLOCK +#undef GRN_TS_OP_NOT_EQUAL_FILTER_CASE_BLOCK + /* grn_ts_expr_op_node_filter() filters records. */ static grn_rc grn_ts_expr_op_node_filter(grn_ctx *ctx, grn_ts_expr_op_node *node, @@ -2490,6 +2701,9 @@ grn_ts_expr_op_node_filter(grn_ctx *ctx, grn_ts_expr_op_node *node, case GRN_TS_OP_EQUAL: { return grn_ts_op_equal_filter(ctx, node, in, n_in, out, n_out); } + case GRN_TS_OP_NOT_EQUAL: { + return grn_ts_op_not_equal_filter(ctx, node, in, n_in, out, n_out); + } // TODO default: { return GRN_OPERATION_NOT_SUPPORTED; -------------- next part -------------- HTML����������������������������... 下載