Kouhei Sutou
null+****@clear*****
Sun Feb 8 19:19:25 JST 2015
Kouhei Sutou 2015-02-08 19:19:25 +0900 (Sun, 08 Feb 2015) New Revision: 5bfa57f0e1becafea1de488acfe815bf615743f1 https://github.com/groonga/groonga/commit/5bfa57f0e1becafea1de488acfe815bf615743f1 Message: Extract compare operation codes as functions It's for reusing these operations in plugin without creating grn_expr. Modified files: include/groonga/groonga.h lib/expr.c lib/operator.c Modified: include/groonga/groonga.h (+6 -0) =================================================================== --- include/groonga/groonga.h 2015-02-08 19:07:19 +0900 (35438be) +++ include/groonga/groonga.h 2015-02-08 19:19:25 +0900 (98e7c1f) @@ -714,6 +714,12 @@ GRN_API const char *grn_operator_to_string(grn_operator op); GRN_API grn_bool grn_operator_exec_equal(grn_ctx *ctx, grn_obj *x, grn_obj *y); GRN_API grn_bool grn_operator_exec_not_equal(grn_ctx *ctx, grn_obj *x, grn_obj *y); +GRN_API grn_bool grn_operator_exec_less(grn_ctx *ctx, grn_obj *x, grn_obj *y); +GRN_API grn_bool grn_operator_exec_greater(grn_ctx *ctx, grn_obj *x, grn_obj *y); +GRN_API grn_bool grn_operator_exec_less_equal(grn_ctx *ctx, + grn_obj *x, grn_obj *y); +GRN_API grn_bool grn_operator_exec_greater_equal(grn_ctx *ctx, + grn_obj *x, grn_obj *y); struct _grn_table_group_result { grn_obj *table; Modified: lib/expr.c (+12 -229) =================================================================== --- lib/expr.c 2015-02-08 19:07:19 +0900 (413c937) +++ lib/expr.c 2015-02-08 19:19:25 +0900 (aeaa9bc) @@ -1234,223 +1234,6 @@ grn_expr_compile(grn_ctx *ctx, grn_obj *expr) s1 = sp[-2];\ } while (0) -#define DO_COMPARE_SUB_NUMERIC(y,op) do {\ - switch ((y)->header.domain) {\ - case GRN_DB_INT8 :\ - r = (x_ op GRN_INT8_VALUE(y));\ - break;\ - case GRN_DB_UINT8 :\ - r = (x_ op GRN_UINT8_VALUE(y));\ - break;\ - case GRN_DB_INT16 :\ - r = (x_ op GRN_INT16_VALUE(y));\ - break;\ - case GRN_DB_UINT16 :\ - r = (x_ op GRN_UINT16_VALUE(y));\ - break;\ - case GRN_DB_INT32 :\ - r = (x_ op GRN_INT32_VALUE(y));\ - break;\ - case GRN_DB_UINT32 :\ - r = (x_ op GRN_UINT32_VALUE(y));\ - break;\ - case GRN_DB_INT64 :\ - r = (x_ op GRN_INT64_VALUE(y));\ - break;\ - case GRN_DB_TIME :\ - r = (GRN_TIME_PACK(x_,0) op GRN_INT64_VALUE(y));\ - break;\ - case GRN_DB_UINT64 :\ - r = (x_ op GRN_UINT64_VALUE(y));\ - break;\ - case GRN_DB_FLOAT :\ - r = (x_ op GRN_FLOAT_VALUE(y));\ - break;\ - default :\ - r = 0;\ - break;\ - }\ -} while (0) - -#define DO_COMPARE_SUB(op) do {\ - switch (y->header.domain) {\ - case GRN_DB_SHORT_TEXT :\ - case GRN_DB_TEXT :\ - case GRN_DB_LONG_TEXT :\ - {\ - grn_obj y_;\ - GRN_OBJ_INIT(&y_, GRN_BULK, 0, x->header.domain);\ - if (grn_obj_cast(ctx, y, &y_, GRN_FALSE)) {\ - r = 0;\ - } else {\ - DO_COMPARE_SUB_NUMERIC(&y_, op);\ - }\ - GRN_OBJ_FIN(ctx, &y_);\ - }\ - break;\ - default :\ - DO_COMPARE_SUB_NUMERIC(y,op);\ - break;\ - }\ -} while (0) - -#define DO_COMPARE_BUILTIN(x,y,r,op) do {\ - switch (x->header.domain) {\ - case GRN_DB_INT8 :\ - {\ - int8_t x_ = GRN_INT8_VALUE(x);\ - DO_COMPARE_SUB(op);\ - }\ - break;\ - case GRN_DB_UINT8 :\ - {\ - uint8_t x_ = GRN_UINT8_VALUE(x);\ - DO_COMPARE_SUB(op);\ - }\ - break;\ - case GRN_DB_INT16 :\ - {\ - int16_t x_ = GRN_INT16_VALUE(x);\ - DO_COMPARE_SUB(op);\ - }\ - break;\ - case GRN_DB_UINT16 :\ - {\ - uint16_t x_ = GRN_UINT16_VALUE(x);\ - DO_COMPARE_SUB(op);\ - }\ - break;\ - case GRN_DB_INT32 :\ - {\ - int32_t x_ = GRN_INT32_VALUE(x);\ - DO_COMPARE_SUB(op);\ - }\ - break;\ - case GRN_DB_UINT32 :\ - {\ - uint32_t x_ = GRN_UINT32_VALUE(x);\ - DO_COMPARE_SUB(op);\ - }\ - break;\ - case GRN_DB_TIME :\ - {\ - int64_t x_ = GRN_INT64_VALUE(x);\ - switch (y->header.domain) {\ - case GRN_DB_INT32 :\ - r = (x_ op GRN_TIME_PACK(GRN_INT32_VALUE(y), 0));\ - break;\ - case GRN_DB_UINT32 :\ - r = (x_ op GRN_TIME_PACK(GRN_UINT32_VALUE(y), 0));\ - break;\ - case GRN_DB_INT64 :\ - case GRN_DB_TIME :\ - r = (x_ op GRN_INT64_VALUE(y));\ - break;\ - case GRN_DB_UINT64 :\ - r = (x_ op GRN_UINT64_VALUE(y));\ - break;\ - case GRN_DB_FLOAT :\ - r = (x_ op GRN_TIME_PACK(GRN_FLOAT_VALUE(y), 0));\ - break;\ - case GRN_DB_SHORT_TEXT :\ - case GRN_DB_TEXT :\ - case GRN_DB_LONG_TEXT :\ - {\ - grn_obj time_value_;\ - GRN_TIME_INIT(&time_value_, 0);\ - if (grn_obj_cast(ctx, y, &time_value_, GRN_FALSE) == GRN_SUCCESS) {\ - r = (x_ op GRN_TIME_VALUE(&time_value_));\ - } else {\ - r = 0;\ - }\ - GRN_OBJ_FIN(ctx, &time_value_);\ - }\ - break;\ - default :\ - r = 0;\ - break;\ - }\ - }\ - break;\ - case GRN_DB_INT64 :\ - {\ - int64_t x_ = GRN_INT64_VALUE(x);\ - DO_COMPARE_SUB(op);\ - }\ - break;\ - case GRN_DB_UINT64 :\ - {\ - uint64_t x_ = GRN_UINT64_VALUE(x);\ - DO_COMPARE_SUB(op);\ - }\ - break;\ - case GRN_DB_FLOAT :\ - {\ - double x_ = GRN_FLOAT_VALUE(x);\ - DO_COMPARE_SUB(op);\ - }\ - break;\ - case GRN_DB_SHORT_TEXT :\ - case GRN_DB_TEXT :\ - case GRN_DB_LONG_TEXT :\ - if (GRN_DB_SHORT_TEXT <= y->header.domain && y->header.domain <= GRN_DB_LONG_TEXT) {\ - int r_;\ - uint32_t la = GRN_TEXT_LEN(x), lb = GRN_TEXT_LEN(y);\ - if (la > lb) {\ - if (!(r_ = memcmp(GRN_TEXT_VALUE(x), GRN_TEXT_VALUE(y), lb))) {\ - r_ = 1;\ - }\ - } else {\ - if (!(r_ = memcmp(GRN_TEXT_VALUE(x), GRN_TEXT_VALUE(y), la))) {\ - r_ = la == lb ? 0 : -1;\ - }\ - }\ - r = (r_ op 0);\ - } else {\ - const char *q_ = GRN_TEXT_VALUE(x);\ - int x_ = grn_atoi(q_, q_ + GRN_TEXT_LEN(x), NULL);\ - DO_COMPARE_SUB(op);\ - }\ - break;\ - default :\ - r = 0;\ - break;\ - }\ -} while (0) - -#define DO_COMPARE(x, y, r, op) do {\ - if (x->header.domain >= GRN_N_RESERVED_TYPES) {\ - grn_obj *table;\ - table = grn_ctx_at(ctx, x->header.domain);\ - switch (table->header.type) {\ - case GRN_TABLE_HASH_KEY :\ - case GRN_TABLE_PAT_KEY :\ - {\ - grn_obj key;\ - int length;\ - GRN_OBJ_INIT(&key, GRN_BULK, 0, table->header.domain);\ - length = grn_table_get_key2(ctx, table, GRN_RECORD_VALUE(x), &key);\ - if (length > 0) {\ - grn_obj *x_original = x;\ - x = &key;\ - DO_COMPARE_BUILTIN((&key), y, r, op);\ - x = x_original;\ - } else {\ - r = 0;\ - }\ - GRN_OBJ_FIN(ctx, &key);\ - }\ - break;\ - default :\ - r = 0;\ - break;\ - }\ - grn_obj_unlink(ctx, table);\ - } else {\ - DO_COMPARE_BUILTIN(x, y, r, op);\ - }\ -} while (0) - #define GEO_RESOLUTION 3600000 #define GEO_RADIOUS 6357303 #define GEO_BES_C1 6334834 @@ -3460,11 +3243,11 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs) break; case GRN_OP_LESS : { - int r; + grn_bool r; grn_obj *x, *y; POP2ALLOC1(x, y, res); - DO_COMPARE(x, y, r, <); - GRN_INT32_SET(ctx, res, r); + r = grn_operator_exec_less(ctx, x, y); + GRN_INT32_SET(ctx, res, r ? 1 : 0); res->header.type = GRN_BULK; res->header.domain = GRN_DB_INT32; } @@ -3472,11 +3255,11 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs) break; case GRN_OP_GREATER : { - int r; + grn_bool r; grn_obj *x, *y; POP2ALLOC1(x, y, res); - DO_COMPARE(x, y, r, >); - GRN_INT32_SET(ctx, res, r); + r = grn_operator_exec_greater(ctx, x, y); + GRN_INT32_SET(ctx, res, r ? 1 : 0); res->header.type = GRN_BULK; res->header.domain = GRN_DB_INT32; } @@ -3484,11 +3267,11 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs) break; case GRN_OP_LESS_EQUAL : { - int r; + grn_bool r; grn_obj *x, *y; POP2ALLOC1(x, y, res); - DO_COMPARE(x, y, r, <=); - GRN_INT32_SET(ctx, res, r); + r = grn_operator_exec_less_equal(ctx, x, y); + GRN_INT32_SET(ctx, res, r ? 1 : 0); res->header.type = GRN_BULK; res->header.domain = GRN_DB_INT32; } @@ -3496,11 +3279,11 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs) break; case GRN_OP_GREATER_EQUAL : { - int r; + grn_bool r; grn_obj *x, *y; POP2ALLOC1(x, y, res); - DO_COMPARE(x, y, r, >=); - GRN_INT32_SET(ctx, res, r); + r = grn_operator_exec_greater_equal(ctx, x, y); + GRN_INT32_SET(ctx, res, r ? 1 : 0); res->header.type = GRN_BULK; res->header.domain = GRN_DB_INT32; } Modified: lib/operator.c (+253 -0) =================================================================== --- lib/operator.c 2015-02-08 19:07:19 +0900 (4e07c59) +++ lib/operator.c 2015-02-08 19:19:25 +0900 (27aa5df) @@ -341,3 +341,256 @@ grn_operator_exec_not_equal(grn_ctx *ctx, grn_obj *x, grn_obj *y) DO_EQ(x, y, r); GRN_API_RETURN(!r); } + +#define DO_COMPARE_SUB_NUMERIC(y,op) do {\ + switch ((y)->header.domain) {\ + case GRN_DB_INT8 :\ + r = (x_ op GRN_INT8_VALUE(y));\ + break;\ + case GRN_DB_UINT8 :\ + r = (x_ op GRN_UINT8_VALUE(y));\ + break;\ + case GRN_DB_INT16 :\ + r = (x_ op GRN_INT16_VALUE(y));\ + break;\ + case GRN_DB_UINT16 :\ + r = (x_ op GRN_UINT16_VALUE(y));\ + break;\ + case GRN_DB_INT32 :\ + r = (x_ op GRN_INT32_VALUE(y));\ + break;\ + case GRN_DB_UINT32 :\ + r = (x_ op GRN_UINT32_VALUE(y));\ + break;\ + case GRN_DB_INT64 :\ + r = (x_ op GRN_INT64_VALUE(y));\ + break;\ + case GRN_DB_TIME :\ + r = (GRN_TIME_PACK(x_,0) op GRN_INT64_VALUE(y));\ + break;\ + case GRN_DB_UINT64 :\ + r = (x_ op GRN_UINT64_VALUE(y));\ + break;\ + case GRN_DB_FLOAT :\ + r = (x_ op GRN_FLOAT_VALUE(y));\ + break;\ + default :\ + r = GRN_FALSE;\ + break;\ + }\ +} while (0) + +#define DO_COMPARE_SUB(op) do {\ + switch (y->header.domain) {\ + case GRN_DB_SHORT_TEXT :\ + case GRN_DB_TEXT :\ + case GRN_DB_LONG_TEXT :\ + {\ + grn_obj y_;\ + GRN_OBJ_INIT(&y_, GRN_BULK, 0, x->header.domain);\ + if (grn_obj_cast(ctx, y, &y_, GRN_FALSE)) {\ + r = GRN_FALSE;\ + } else {\ + DO_COMPARE_SUB_NUMERIC(&y_, op);\ + }\ + GRN_OBJ_FIN(ctx, &y_);\ + }\ + break;\ + default :\ + DO_COMPARE_SUB_NUMERIC(y,op);\ + break;\ + }\ +} while (0) + +#define DO_COMPARE_BUILTIN(x,y,r,op) do {\ + switch (x->header.domain) {\ + case GRN_DB_INT8 :\ + {\ + int8_t x_ = GRN_INT8_VALUE(x);\ + DO_COMPARE_SUB(op);\ + }\ + break;\ + case GRN_DB_UINT8 :\ + {\ + uint8_t x_ = GRN_UINT8_VALUE(x);\ + DO_COMPARE_SUB(op);\ + }\ + break;\ + case GRN_DB_INT16 :\ + {\ + int16_t x_ = GRN_INT16_VALUE(x);\ + DO_COMPARE_SUB(op);\ + }\ + break;\ + case GRN_DB_UINT16 :\ + {\ + uint16_t x_ = GRN_UINT16_VALUE(x);\ + DO_COMPARE_SUB(op);\ + }\ + break;\ + case GRN_DB_INT32 :\ + {\ + int32_t x_ = GRN_INT32_VALUE(x);\ + DO_COMPARE_SUB(op);\ + }\ + break;\ + case GRN_DB_UINT32 :\ + {\ + uint32_t x_ = GRN_UINT32_VALUE(x);\ + DO_COMPARE_SUB(op);\ + }\ + break;\ + case GRN_DB_TIME :\ + {\ + int64_t x_ = GRN_INT64_VALUE(x);\ + switch (y->header.domain) {\ + case GRN_DB_INT32 :\ + r = (x_ op GRN_TIME_PACK(GRN_INT32_VALUE(y), 0));\ + break;\ + case GRN_DB_UINT32 :\ + r = (x_ op GRN_TIME_PACK(GRN_UINT32_VALUE(y), 0));\ + break;\ + case GRN_DB_INT64 :\ + case GRN_DB_TIME :\ + r = (x_ op GRN_INT64_VALUE(y));\ + break;\ + case GRN_DB_UINT64 :\ + r = (x_ op GRN_UINT64_VALUE(y));\ + break;\ + case GRN_DB_FLOAT :\ + r = (x_ op GRN_TIME_PACK(GRN_FLOAT_VALUE(y), 0));\ + break;\ + case GRN_DB_SHORT_TEXT :\ + case GRN_DB_TEXT :\ + case GRN_DB_LONG_TEXT :\ + {\ + grn_obj time_value_;\ + GRN_TIME_INIT(&time_value_, 0);\ + if (grn_obj_cast(ctx, y, &time_value_, GRN_FALSE) == GRN_SUCCESS) {\ + r = (x_ op GRN_TIME_VALUE(&time_value_));\ + } else {\ + r = GRN_FALSE;\ + }\ + GRN_OBJ_FIN(ctx, &time_value_);\ + }\ + break;\ + default :\ + r = GRN_FALSE;\ + break;\ + }\ + }\ + break;\ + case GRN_DB_INT64 :\ + {\ + int64_t x_ = GRN_INT64_VALUE(x);\ + DO_COMPARE_SUB(op);\ + }\ + break;\ + case GRN_DB_UINT64 :\ + {\ + uint64_t x_ = GRN_UINT64_VALUE(x);\ + DO_COMPARE_SUB(op);\ + }\ + break;\ + case GRN_DB_FLOAT :\ + {\ + double x_ = GRN_FLOAT_VALUE(x);\ + DO_COMPARE_SUB(op);\ + }\ + break;\ + case GRN_DB_SHORT_TEXT :\ + case GRN_DB_TEXT :\ + case GRN_DB_LONG_TEXT :\ + if (GRN_DB_SHORT_TEXT <= y->header.domain && y->header.domain <= GRN_DB_LONG_TEXT) {\ + int r_;\ + uint32_t la = GRN_TEXT_LEN(x), lb = GRN_TEXT_LEN(y);\ + if (la > lb) {\ + if (!(r_ = memcmp(GRN_TEXT_VALUE(x), GRN_TEXT_VALUE(y), lb))) {\ + r_ = 1;\ + }\ + } else {\ + if (!(r_ = memcmp(GRN_TEXT_VALUE(x), GRN_TEXT_VALUE(y), la))) {\ + r_ = la == lb ? 0 : -1;\ + }\ + }\ + r = (r_ op 0);\ + } else {\ + const char *q_ = GRN_TEXT_VALUE(x);\ + int x_ = grn_atoi(q_, q_ + GRN_TEXT_LEN(x), NULL);\ + DO_COMPARE_SUB(op);\ + }\ + break;\ + default :\ + r = GRN_FALSE;\ + break;\ + }\ +} while (0) + +#define DO_COMPARE(x, y, r, op) do {\ + if (x->header.domain >= GRN_N_RESERVED_TYPES) {\ + grn_obj *table;\ + table = grn_ctx_at(ctx, x->header.domain);\ + switch (table->header.type) {\ + case GRN_TABLE_HASH_KEY :\ + case GRN_TABLE_PAT_KEY :\ + {\ + grn_obj key;\ + int length;\ + GRN_OBJ_INIT(&key, GRN_BULK, 0, table->header.domain);\ + length = grn_table_get_key2(ctx, table, GRN_RECORD_VALUE(x), &key);\ + if (length > 0) {\ + grn_obj *x_original = x;\ + x = &key;\ + DO_COMPARE_BUILTIN((&key), y, r, op);\ + x = x_original;\ + } else {\ + r = GRN_FALSE;\ + }\ + GRN_OBJ_FIN(ctx, &key);\ + }\ + break;\ + default :\ + r = GRN_FALSE;\ + break;\ + }\ + grn_obj_unlink(ctx, table);\ + } else {\ + DO_COMPARE_BUILTIN(x, y, r, op);\ + }\ +} while (0) + +grn_bool +grn_operator_exec_less(grn_ctx *ctx, grn_obj *x, grn_obj *y) +{ + grn_bool r; + GRN_API_ENTER; + DO_COMPARE(x, y, r, <); + GRN_API_RETURN(r); +} + +grn_bool +grn_operator_exec_greater(grn_ctx *ctx, grn_obj *x, grn_obj *y) +{ + grn_bool r; + GRN_API_ENTER; + DO_COMPARE(x, y, r, >); + GRN_API_RETURN(r); +} + +grn_bool +grn_operator_exec_less_equal(grn_ctx *ctx, grn_obj *x, grn_obj *y) +{ + grn_bool r; + GRN_API_ENTER; + DO_COMPARE(x, y, r, <=); + GRN_API_RETURN(r); +} + +grn_bool +grn_operator_exec_greater_equal(grn_ctx *ctx, grn_obj *x, grn_obj *y) +{ + grn_bool r; + GRN_API_ENTER; + DO_COMPARE(x, y, r, >=); + GRN_API_RETURN(r); +} -------------- next part -------------- HTML����������������������������... Download