Daijiro MORI
null+****@clear*****
Thu Feb 7 09:54:27 JST 2013
Daijiro MORI 2013-02-07 09:54:27 +0900 (Thu, 07 Feb 2013) New Revision: a896618a210e61e112edc8ea661c5e9e89247461 https://github.com/groonga/groonga/commit/a896618a210e61e112edc8ea661c5e9e89247461 Log: Add grn_array_push and grn_array_pull Modified files: include/groonga.h lib/hash.c lib/hash.h plugins/table/table.c Modified: include/groonga.h (+8 -0) =================================================================== --- include/groonga.h 2013-02-06 14:06:59 +0900 (d5b577b) +++ include/groonga.h 2013-02-07 09:54:27 +0900 (b44edac) @@ -2828,6 +2828,14 @@ GRN_API grn_array *grn_array_create(grn_ctx *ctx, const char *path, GRN_API grn_array *grn_array_open(grn_ctx *ctx, const char *path); GRN_API grn_rc grn_array_close(grn_ctx *ctx, grn_array *array); GRN_API grn_id grn_array_add(grn_ctx *ctx, grn_array *array, void **value); +GRN_API grn_id grn_array_push(grn_ctx *ctx, grn_array *array, + void (*func)(grn_ctx *, + grn_array *, grn_id, void *), + void *func_arg); +GRN_API grn_id grn_array_pull(grn_ctx *ctx, grn_array *array, grn_bool blockp, + void (*func)(grn_ctx *, + grn_array *, grn_id, void *), + void *func_arg); GRN_API int grn_array_get_value(grn_ctx *ctx, grn_array *array, grn_id id, void *valuebuf); GRN_API grn_rc grn_array_set_value(grn_ctx *ctx, grn_array *array, grn_id id, const void *value, int flags); Modified: lib/hash.c (+101 -0) =================================================================== --- lib/hash.c 2013-02-06 14:06:59 +0900 (7148a4f) +++ lib/hash.c 2013-02-07 09:54:27 +0900 (aa2a970) @@ -337,6 +337,50 @@ grn_table_queue_init(grn_ctx *ctx, grn_table_queue *queue) grn_table_queue_lock_init(ctx, queue); } +uint32_t +grn_table_queue_size(grn_table_queue *queue) +{ + return (queue->head < queue->tail) + ? 2 * queue->cap + queue->head - queue->tail + : queue->head - queue->tail; +} + +void +grn_table_queue_head_increment(grn_table_queue *queue) +{ + if (queue->head == 2 * queue->cap) { + queue->head = 1; + } else { + queue->head++; + } +} + +void +grn_table_queue_tail_increment(grn_table_queue *queue) +{ + if (queue->tail == 2 * queue->cap) { + queue->tail = 1; + } else { + queue->tail++; + } +} + +grn_id +grn_table_queue_head(grn_table_queue *queue) +{ + return queue->head > queue->cap + ? queue->head - queue->cap + : queue->head; +} + +grn_id +grn_table_queue_tail(grn_table_queue *queue) +{ + return queue->tail > queue->cap + ? queue->tail - queue->cap + : queue->tail; +} + /* grn_array */ #define GRN_ARRAY_SEGMENT_SIZE 0x400000 @@ -1046,6 +1090,63 @@ grn_array_add(grn_ctx *ctx, grn_array *array, void **value) return GRN_ID_NIL; } +grn_id +grn_array_push(grn_ctx *ctx, grn_array *array, + void (*func)(grn_ctx *, grn_array *, grn_id, void *), + void *func_arg) +{ + grn_id id = GRN_ID_NIL; + grn_table_queue *queue = grn_array_queue(ctx, array); + if (queue) { + MUTEX_LOCK(queue->mutex); + if (grn_table_queue_head(queue) == queue->cap) { + grn_array_clear_curr_rec(ctx, array); + } + id = grn_array_add(ctx, array, NULL); + if (func) { + func(ctx, array, id, func_arg); + } + if (grn_table_queue_size(queue) == queue->cap) { + grn_table_queue_tail_increment(queue); + } + grn_table_queue_head_increment(queue); + COND_SIGNAL(queue->cond); + MUTEX_UNLOCK(queue->mutex); + } else { + ERR(GRN_OPERATION_NOT_SUPPORTED, "only persistent arrays support push"); + } + return id; +} + +grn_id +grn_array_pull(grn_ctx *ctx, grn_array *array, grn_bool blockp, + void (*func)(grn_ctx *, grn_array *, grn_id, void *), + void *func_arg) +{ + grn_id id = GRN_ID_NIL; + grn_table_queue *queue = grn_array_queue(ctx, array); + if (queue) { + MUTEX_LOCK(queue->mutex); + while (grn_table_queue_size(queue) == 0) { + if (!blockp) { + MUTEX_UNLOCK(queue->mutex); + GRN_OUTPUT_BOOL(0); + return id; + } + COND_WAIT(queue->cond, queue->mutex); + } + grn_table_queue_tail_increment(queue); + id = grn_table_queue_tail(queue); + if (func) { + func(ctx, array, id, func_arg); + } + MUTEX_UNLOCK(queue->mutex); + } else { + ERR(GRN_OPERATION_NOT_SUPPORTED, "only persistent arrays support pull"); + } + return id; +} + /* grn_hash : hash table */ #define GRN_HASH_MAX_SEGMENT 0x400 Modified: lib/hash.h (+5 -0) =================================================================== --- lib/hash.h 2013-02-06 14:06:59 +0900 (6792e5b) +++ lib/hash.h 2013-02-07 09:54:27 +0900 (62b1c5f) @@ -182,6 +182,11 @@ struct _grn_table_queue { GRN_API void grn_array_queue_lock_clear(grn_ctx *ctx, grn_array *array); GRN_API void grn_array_clear_curr_rec(grn_ctx *ctx, grn_array *array); GRN_API grn_table_queue *grn_array_queue(grn_ctx *ctx, grn_array *array); +GRN_API uint32_t grn_table_queue_size(grn_table_queue *queue); +GRN_API void grn_table_queue_head_increment(grn_table_queue *queue); +GRN_API void grn_table_queue_tail_increment(grn_table_queue *queue); +GRN_API grn_id grn_table_queue_head(grn_table_queue *queue); +GRN_API grn_id grn_table_queue_tail(grn_table_queue *queue); /**** grn_hash ****/ Modified: plugins/table/table.c (+28 -65) =================================================================== --- plugins/table/table.c 2013-02-06 14:06:59 +0900 (f3d451d) +++ plugins/table/table.c 2013-02-07 09:54:27 +0900 (644e5c8) @@ -405,31 +405,38 @@ command_add(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data) static grn_obj * command_set(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data) { - /* TODO: implement */ - grn_obj *table = grn_ctx_get(ctx, GRN_TEXT_VALUE(VAR(0)), GRN_TEXT_LEN(VAR(0))); + int table_name_len = GRN_TEXT_LEN(VAR(0)); + const char *table_name = GRN_TEXT_VALUE(VAR(0)); + grn_obj *table = grn_ctx_get(ctx, table_name, table_name_len); if (table) { - grn_id id; - if (GRN_TEXT_LEN(VAR(1))) { - if ((id = grn_table_get(ctx, table, GRN_TEXT_VALUE(VAR(1)), GRN_TEXT_LEN(VAR(1))))) { - grn_obj obj; - grn_obj_format format; - GRN_RECORD_INIT(&obj, 0, ((grn_db_obj *)table)->id); - GRN_OBJ_FORMAT_INIT(&format, 1, 0, 1, 0); - GRN_RECORD_SET(ctx, &obj, id); - grn_obj_columns(ctx, table, - GRN_TEXT_VALUE(VAR(4)), - GRN_TEXT_LEN(VAR(4)), &format.columns); - format.flags = 0 /* GRN_OBJ_FORMAT_WITH_COLUMN_NAMES */; - GRN_OUTPUT_OBJ(&obj, &format); - GRN_OBJ_FORMAT_FIN(ctx, &format); - } else { - /* todo : error handling */ - } + grn_id id = GRN_ID_NIL; + int key_len = GRN_TEXT_LEN(VAR(2)); + int id_len = GRN_TEXT_LEN(VAR(5)); + if (key_len) { + const char *key = GRN_TEXT_VALUE(VAR(2)); + id = grn_table_get(ctx, table, key, key_len); } else { - /* todo : get_by_id */ + if (id_len) { + id = grn_atoui(GRN_TEXT_VALUE(VAR(5)), GRN_BULK_CURR(VAR(5)), NULL); + } + id = grn_table_at(ctx, table, id); + } + if (id) { + grn_obj obj; + grn_obj_format format; + GRN_RECORD_INIT(&obj, 0, ((grn_db_obj *)table)->id); + GRN_OBJ_FORMAT_INIT(&format, 1, 0, 1, 0); + GRN_RECORD_SET(ctx, &obj, id); + grn_obj_columns(ctx, table, + GRN_TEXT_VALUE(VAR(4)), + GRN_TEXT_LEN(VAR(4)), &format.columns); + format.flags = 0 /* GRN_OBJ_FORMAT_WITH_COLUMN_NAMES */; + GRN_OUTPUT_OBJ(&obj, &format); + GRN_OBJ_FORMAT_FIN(ctx, &format); } } else { - /* todo : error handling */ + ERR(GRN_INVALID_ARGUMENT, + "nonexistent table name: <%.*s>", table_name_len, table_name); } return NULL; } @@ -554,50 +561,6 @@ command_get(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data) return NULL; } -uint32_t -grn_table_queue_size(grn_table_queue *queue) -{ - return (queue->head < queue->tail) - ? 2 * queue->cap + queue->head - queue->tail - : queue->head - queue->tail; -} - -void -grn_table_queue_head_increment(grn_table_queue *queue) -{ - if (queue->head == 2 * queue->cap) { - queue->head = 1; - } else { - queue->head++; - } -} - -void -grn_table_queue_tail_increment(grn_table_queue *queue) -{ - if (queue->tail == 2 * queue->cap) { - queue->tail = 1; - } else { - queue->tail++; - } -} - -grn_id -grn_table_queue_head(grn_table_queue *queue) -{ - return queue->head > queue->cap - ? queue->head - queue->cap - : queue->head; -} - -grn_id -grn_table_queue_tail(grn_table_queue *queue) -{ - return queue->tail > queue->cap - ? queue->tail - queue->cap - : queue->tail; -} - static grn_obj * command_push(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data) { -------------- next part -------------- HTML����������������������������...Download