susumu.yata
null+****@clear*****
Wed Oct 14 12:28:20 JST 2015
susumu.yata 2015-10-14 12:28:20 +0900 (Wed, 14 Oct 2015) New Revision: 9accab91a63db66d4ea8983135272201e19cc2b1 https://github.com/groonga/groonga/commit/9accab91a63db66d4ea8983135272201e19cc2b1 Message: grn_ts: support an operator "&!" GitHub: #416 Modified files: lib/grn_ts.h lib/ts.c Modified: lib/grn_ts.h (+1 -0) =================================================================== --- lib/grn_ts.h 2015-10-13 12:43:03 +0900 (1b6288c) +++ lib/grn_ts.h 2015-10-14 12:28:20 +0900 (6841a6d) @@ -70,6 +70,7 @@ typedef enum { /* Binary operators. */ GRN_TS_OP_LOGICAL_AND, /* X && Y */ GRN_TS_OP_LOGICAL_OR, /* X || Y */ + GRN_TS_OP_LOGICAL_SUB, /* X &! Y */ GRN_TS_OP_BITWISE_AND, /* X & Y */ GRN_TS_OP_BITWISE_OR, /* X | Y */ GRN_TS_OP_BITWISE_XOR, /* X ^ Y */ Modified: lib/ts.c (+106 -16) =================================================================== --- lib/ts.c 2015-10-13 12:43:03 +0900 (cc96003) +++ lib/ts.c 2015-10-14 12:28:20 +0900 (3e47bff) @@ -724,6 +724,7 @@ grn_ts_op_get_n_args(grn_ts_op_type op_type) { } case GRN_TS_OP_LOGICAL_AND: /* X && Y */ case GRN_TS_OP_LOGICAL_OR: /* X || Y */ + case GRN_TS_OP_LOGICAL_SUB: /* X &! Y */ case GRN_TS_OP_BITWISE_AND: /* X & Y */ case GRN_TS_OP_BITWISE_OR: /* X | Y */ case GRN_TS_OP_BITWISE_XOR: /* X ^ Y */ @@ -767,6 +768,9 @@ grn_ts_op_get_precedence(grn_ts_op_type op_type) { return 5; } case GRN_TS_OP_LOGICAL_OR: { + return 3; + } + case GRN_TS_OP_LOGICAL_SUB: { return 4; } case GRN_TS_OP_BITWISE_AND: { @@ -3350,7 +3354,8 @@ grn_ts_expr_op_node_check_args(grn_ctx *ctx, grn_ts_expr_op_node *node) { return GRN_SUCCESS; } case GRN_TS_OP_LOGICAL_AND: - case GRN_TS_OP_LOGICAL_OR: { + case GRN_TS_OP_LOGICAL_OR: + case GRN_TS_OP_LOGICAL_SUB: { if ((node->args[0]->data_kind != GRN_TS_BOOL) || (node->args[1]->data_kind != GRN_TS_BOOL)) { GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d, %d", @@ -3700,6 +3705,52 @@ grn_ts_op_logical_or_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node, return GRN_SUCCESS; } +/* grn_ts_op_logical_sub_evaluate() evaluates an operator. */ +static grn_rc +grn_ts_op_logical_sub_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node, + const grn_ts_record *in, size_t n_in, + void *out) { + size_t i, j, count; + grn_rc rc; + grn_ts_bool *buf_ptrs[2], *out_ptr = (grn_ts_bool *)out; + grn_ts_buf *tmp_in_buf = &node->bufs[2]; + grn_ts_record *tmp_in; + + /* Evaluate the 1st argument. */ + rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[0], in, n_in, + &node->bufs[0]); + if (rc != GRN_SUCCESS) { + return rc; + } + buf_ptrs[0] = (grn_ts_bool *)node->bufs[0].ptr; + + /* Create a list of true records. */ + rc = grn_ts_buf_reserve(ctx, tmp_in_buf, sizeof(grn_ts_record) * n_in); + if (rc != GRN_SUCCESS) { + return rc; + } + tmp_in = (grn_ts_record *)tmp_in_buf->ptr; + count = 0; + for (i = 0; i < n_in; i++) { + if (buf_ptrs[0][i]) { + tmp_in[count++] = in[i]; + } + } + + /* Evaluate the 2nd argument. */ + rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[1], tmp_in, count, + &node->bufs[1]); + buf_ptrs[1] = (grn_ts_bool *)node->bufs[1].ptr; + + /* Merge the results. */ + count = 0; + for (i = 0, j = 0; i < n_in; i++) { + out_ptr[count++] = buf_ptrs[0][i] && + grn_ts_op_logical_not_bool(buf_ptrs[1][j++]); + } + return GRN_SUCCESS; +} + #define GRN_TS_OP_BITWISE_EVALUATE_CASE(type, KIND, kind)\ case GRN_TS_ ## KIND: {\ /* @@ -4214,6 +4265,9 @@ grn_ts_expr_op_node_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node, case GRN_TS_OP_LOGICAL_OR: { return grn_ts_op_logical_or_evaluate(ctx, node, in, n_in, out); } + case GRN_TS_OP_LOGICAL_SUB: { + return grn_ts_op_logical_sub_evaluate(ctx, node, in, n_in, out); + } case GRN_TS_OP_BITWISE_AND: { return grn_ts_op_bitwise_and_evaluate(ctx, node, in, n_in, out); } @@ -4389,6 +4443,29 @@ grn_ts_op_logical_or_filter(grn_ctx *ctx, grn_ts_expr_op_node *node, return GRN_SUCCESS; } +/* grn_ts_op_logical_sub_filter() filters records. */ +static grn_rc +grn_ts_op_logical_sub_filter(grn_ctx *ctx, grn_ts_expr_op_node *node, + grn_ts_record *in, size_t n_in, + grn_ts_record *out, size_t *n_out) { + size_t i, n, count; + grn_ts_bool *buf_ptr; + grn_rc rc = grn_ts_expr_node_filter(ctx, node->args[0], in, n_in, out, &n); + if (rc != GRN_SUCCESS) { + return rc; + } + rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[1], out, n, + &node->bufs[0]); + buf_ptr = (grn_ts_bool *)node->bufs[0].ptr; + for (i = 0, count = 0; i < n; i++) { + if (grn_ts_op_logical_not_bool(buf_ptr[i])) { + out[count++] = out[i]; + } + } + *n_out = count; + return GRN_SUCCESS; +} + #define GRN_TS_OP_BITWISE_FILTER(type)\ size_t i, count = 0;\ grn_ts_bool *buf_ptrs[2];\ @@ -4588,6 +4665,9 @@ grn_ts_expr_op_node_filter(grn_ctx *ctx, grn_ts_expr_op_node *node, case GRN_TS_OP_LOGICAL_OR: { return grn_ts_op_logical_or_filter(ctx, node, in, n_in, out, n_out); } + case GRN_TS_OP_LOGICAL_SUB: { + return grn_ts_op_logical_sub_filter(ctx, node, in, n_in, out, n_out); + } case GRN_TS_OP_BITWISE_AND: { return grn_ts_op_bitwise_and_filter(ctx, node, in, n_in, out, n_out); } @@ -5656,21 +5736,31 @@ grn_ts_expr_parser_tokenize_op(grn_ctx *ctx, grn_ts_expr_parser *parser, GRN_TS_EXPR_PARSER_TOKENIZE_OP_CASE('>', GREATER, SHIFT_ARITHMETIC_RIGHT, SHIFT_LOGICAL_RIGHT, GREATER_EQUAL) #undef GRN_TS_EXPR_PARSER_TOKENIZE_OP_CASE -#define GRN_TS_EXPR_PARSER_TOKENIZE_OP_CASE(label, TYPE_1, TYPE_2)\ - case label: {\ - if ((str.size >= 2) && (str.ptr[1] == label)) {\ - token_str.size = 2;\ - op_type = GRN_TS_OP_ ## TYPE_2;\ - } else {\ - token_str.size = 1;\ - op_type = GRN_TS_OP_ ## TYPE_1;\ - }\ - rc = grn_ts_expr_op_token_open(ctx, token_str, op_type, &new_token);\ - break;\ - } - GRN_TS_EXPR_PARSER_TOKENIZE_OP_CASE('&', BITWISE_AND, LOGICAL_AND) - GRN_TS_EXPR_PARSER_TOKENIZE_OP_CASE('|', BITWISE_OR, LOGICAL_OR) -#undef GRN_TS_EXPR_PARSER_TOKENIZE_OP_CASE + case '&': { + if ((str.size >= 2) && (str.ptr[1] == '&')) { + token_str.size = 2; + op_type = GRN_TS_OP_LOGICAL_AND; + } else if ((str.size >= 2) && (str.ptr[1] == '&')) { + token_str.size = 2; + op_type = GRN_TS_OP_LOGICAL_SUB; + } else { + token_str.size = 1; + op_type = GRN_TS_OP_BITWISE_AND; + } + rc = grn_ts_expr_op_token_open(ctx, token_str, op_type, &new_token); + break; + } + case '|': { + if ((str.size >= 2) && (str.ptr[1] == '|')) { + token_str.size = 2; + op_type = GRN_TS_OP_LOGICAL_OR; + } else { + token_str.size = 1; + op_type = GRN_TS_OP_BITWISE_OR; + } + rc = grn_ts_expr_op_token_open(ctx, token_str, op_type, &new_token); + break; + } case '=': { if ((str.size < 2) || (str.ptr[1] != '=')) { GRN_TS_ERR_RETURN(GRN_INVALID_FORMAT, -------------- next part -------------- HTML����������������������������...Download