susumu.yata
null+****@clear*****
Sat Oct 10 02:31:13 JST 2015
susumu.yata 2015-10-10 02:31:13 +0900 (Sat, 10 Oct 2015) New Revision: 2b1f52b1e33927a44a741ef655ac346142f08357 https://github.com/groonga/groonga/commit/2b1f52b1e33927a44a741ef655ac346142f08357 Message: grn_ts: support bitwise operators "&", "|" and "^" GitHub: #416 Modified files: lib/ts.c Modified: lib/ts.c (+203 -13) =================================================================== --- lib/ts.c 2015-10-09 21:34:33 +0900 (2989609) +++ lib/ts.c 2015-10-10 02:31:13 +0900 (8a1adc1) @@ -843,6 +843,42 @@ grn_ts_op_negative_float(grn_ts_float arg) { return -arg; } +/* grn_ts_op_bitwise_and_bool() returns lhs & rhs. */ +inline static grn_ts_bool +grn_ts_op_bitwise_and_bool(grn_ts_bool lhs, grn_ts_bool rhs) { + return lhs & rhs; +} + +/* grn_ts_op_bitwise_and_int() returns lhs & rhs. */ +inline static grn_ts_int +grn_ts_op_bitwise_and_int(grn_ts_int lhs, grn_ts_int rhs) { + return lhs & rhs; +} + +/* grn_ts_op_bitwise_or_bool() returns lhs | rhs. */ +inline static grn_ts_bool +grn_ts_op_bitwise_or_bool(grn_ts_bool lhs, grn_ts_bool rhs) { + return lhs | rhs; +} + +/* grn_ts_op_bitwise_or_int() returns lhs | rhs. */ +inline static grn_ts_int +grn_ts_op_bitwise_or_int(grn_ts_int lhs, grn_ts_int rhs) { + return lhs | rhs; +} + +/* grn_ts_op_bitwise_xor_bool() returns lhs ^ rhs. */ +inline static grn_ts_bool +grn_ts_op_bitwise_xor_bool(grn_ts_bool lhs, grn_ts_bool rhs) { + return lhs ^ rhs; +} + +/* grn_ts_op_bitwise_xor_int() returns lhs ^ rhs. */ +inline static grn_ts_int +grn_ts_op_bitwise_xor_int(grn_ts_int lhs, grn_ts_int rhs) { + return lhs ^ rhs; +} + /* grn_ts_op_equal_bool() returns lhs == rhs. */ inline static grn_ts_bool grn_ts_op_equal_bool(grn_ts_bool lhs, grn_ts_bool rhs) { @@ -3255,14 +3291,18 @@ grn_ts_expr_op_node_check_args(grn_ctx *ctx, grn_ts_expr_op_node *node) { return GRN_SUCCESS; } case GRN_TS_OP_BITWISE_NOT: { - if ((node->args[0]->data_kind != GRN_TS_BOOL) && - (node->args[0]->data_kind != GRN_TS_INT)) { - GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d", - node->args[0]->data_kind); + switch (node->args[0]->data_kind) { + case GRN_TS_BOOL: + case GRN_TS_INT: { + node->data_kind = node->args[0]->data_kind; + node->data_type = grn_ts_data_kind_to_type(node->data_kind); + return GRN_SUCCESS; + } + default: { + GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d", + node->args[0]->data_kind); + } } - node->data_kind = node->args[0]->data_kind; - node->data_type = grn_ts_data_kind_to_type(node->data_kind); - return GRN_SUCCESS; } case GRN_TS_OP_POSITIVE: case GRN_TS_OP_NEGATIVE: { @@ -3277,13 +3317,33 @@ grn_ts_expr_op_node_check_args(grn_ctx *ctx, grn_ts_expr_op_node *node) { } case GRN_TS_OP_LOGICAL_AND: case GRN_TS_OP_LOGICAL_OR: { - if (node->args[0]->data_kind != GRN_TS_BOOL) { - GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d", - node->args[0]->data_kind); + 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", + node->args[0]->data_kind, node->args[1]->data_kind); } - if (node->args[1]->data_kind != GRN_TS_BOOL) { - GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d", - node->args[1]->data_kind); + node->data_kind = GRN_TS_BOOL; + node->data_type = GRN_DB_BOOL; + return GRN_SUCCESS; + } + case GRN_TS_OP_BITWISE_AND: + case GRN_TS_OP_BITWISE_OR: + case GRN_TS_OP_BITWISE_XOR: { + if (node->args[0]->data_kind != node->args[1]->data_kind) { + GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "data kind conflict: %d != %d", + node->args[0]->data_kind, node->args[1]->data_kind); + } + switch (node->args[0]->data_kind) { + case GRN_TS_BOOL: + case GRN_TS_INT: { + node->data_kind = node->args[0]->data_kind; + node->data_type = grn_ts_data_kind_to_type(node->data_kind); + return GRN_SUCCESS; + } + default: { + GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d", + node->args[0]->data_kind); + } } node->data_kind = GRN_TS_BOOL; node->data_type = GRN_DB_BOOL; @@ -3592,6 +3652,75 @@ grn_ts_op_logical_or_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node, return GRN_SUCCESS; } +#define GRN_TS_OP_BITWISE_EVALUATE_CASE(type, KIND, kind)\ + case GRN_TS_ ## KIND: {\ + /* + * Use the output buffer to put evaluation results of the 1st argument, + * because the data kind is same. + */\ + size_t i;\ + grn_rc rc;\ + grn_ts_ ## kind *out_ptr = (grn_ts_ ## kind *)out;\ + rc = grn_ts_expr_node_evaluate(ctx, node->args[0], in, n_in, out);\ + if (rc == GRN_SUCCESS) {\ + rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[1],\ + in, n_in, &node->bufs[0]);\ + if (rc == GRN_SUCCESS) {\ + grn_ts_ ## kind *buf_ptr = (grn_ts_ ## kind *)node->bufs[0].ptr;\ + for (i = 0; i < n_in; i++) {\ + out_ptr[i] = grn_ts_op_bitwise_ ## type ## _ ## kind(out_ptr[i],\ + buf_ptr[i]);\ + }\ + }\ + }\ + return rc;\ + } +/* grn_ts_op_bitwise_and_evaluate() evaluates an operator. */ +static grn_rc +grn_ts_op_bitwise_and_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node, + const grn_ts_record *in, size_t n_in, + void *out) { + switch (node->args[0]->data_kind) { + GRN_TS_OP_BITWISE_EVALUATE_CASE(and, BOOL, bool) + GRN_TS_OP_BITWISE_EVALUATE_CASE(and, INT, int) + default: { + GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d", + node->args[0]->data_kind); + } + } +} + +/* grn_ts_op_bitwise_or_evaluate() evaluates an operator. */ +static grn_rc +grn_ts_op_bitwise_or_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node, + const grn_ts_record *in, size_t n_in, + void *out) { + switch (node->args[0]->data_kind) { + GRN_TS_OP_BITWISE_EVALUATE_CASE(or, BOOL, bool) + GRN_TS_OP_BITWISE_EVALUATE_CASE(or, INT, int) + default: { + GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d", + node->args[0]->data_kind); + } + } +} + +/* grn_ts_op_bitwise_xor_evaluate() evaluates an operator. */ +static grn_rc +grn_ts_op_bitwise_xor_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node, + const grn_ts_record *in, size_t n_in, + void *out) { + switch (node->args[0]->data_kind) { + GRN_TS_OP_BITWISE_EVALUATE_CASE(xor, BOOL, bool) + GRN_TS_OP_BITWISE_EVALUATE_CASE(xor, INT, int) + default: { + GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d", + node->args[0]->data_kind); + } + } +} +#undef GRN_TS_OP_BITWISE_EVALUATE_CASE + #define GRN_TS_OP_CHK_EVALUATE_CASE(type, KIND, kind)\ case GRN_TS_ ## KIND: {\ grn_ts_ ## kind *buf_ptrs[] = {\ @@ -3984,6 +4113,15 @@ 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_BITWISE_AND: { + return grn_ts_op_bitwise_and_evaluate(ctx, node, in, n_in, out); + } + case GRN_TS_OP_BITWISE_OR: { + return grn_ts_op_bitwise_or_evaluate(ctx, node, in, n_in, out); + } + case GRN_TS_OP_BITWISE_XOR: { + return grn_ts_op_bitwise_xor_evaluate(ctx, node, in, n_in, out); + } case GRN_TS_OP_EQUAL: { return grn_ts_op_equal_evaluate(ctx, node, in, n_in, out); } @@ -4138,6 +4276,49 @@ grn_ts_op_logical_or_filter(grn_ctx *ctx, grn_ts_expr_op_node *node, return GRN_SUCCESS; } +#define GRN_TS_OP_BITWISE_FILTER(type)\ + size_t i, count = 0;\ + grn_ts_bool *buf_ptrs[2];\ + 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;\ + }\ + buf_ptrs[i] = (grn_ts_bool *)node->bufs[i].ptr;\ + }\ + for (i = 0; i < n_in; i++) {\ + if (grn_ts_op_bitwise_ ## type ## _bool(buf_ptrs[0][i], buf_ptrs[1][i])) {\ + out[count++] = in[i];\ + }\ + }\ + *n_out = count;\ + return GRN_SUCCESS;\ +/* grn_ts_op_bitwise_and_filter() filters records. */ +static grn_rc +grn_ts_op_bitwise_and_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) { + GRN_TS_OP_BITWISE_FILTER(and); +} + +/* grn_ts_op_bitwise_or_filter() filters records. */ +static grn_rc +grn_ts_op_bitwise_or_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) { + GRN_TS_OP_BITWISE_FILTER(or); +} + +/* grn_ts_op_bitwise_xor_filter() filters records. */ +static grn_rc +grn_ts_op_bitwise_xor_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) { + GRN_TS_OP_BITWISE_FILTER(xor); +} +#undef GRN_TS_OP_BITWISE_FILTER_CASE + #define GRN_TS_OP_CHK_FILTER_CASE(type, KIND, kind)\ case GRN_TS_ ## KIND: {\ grn_ts_ ## kind *buf_ptrs[] = {\ @@ -4294,6 +4475,15 @@ 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_BITWISE_AND: { + return grn_ts_op_bitwise_and_filter(ctx, node, in, n_in, out, n_out); + } + case GRN_TS_OP_BITWISE_OR: { + return grn_ts_op_bitwise_or_filter(ctx, node, in, n_in, out, n_out); + } + case GRN_TS_OP_BITWISE_XOR: { + return grn_ts_op_bitwise_xor_filter(ctx, node, in, n_in, out, n_out); + } case GRN_TS_OP_EQUAL: { return grn_ts_op_equal_filter(ctx, node, in, n_in, out, n_out); } -------------- next part -------------- HTML����������������������������... Download