Kouhei Sutou
null+****@clear*****
Thu Apr 5 11:47:54 JST 2018
Kouhei Sutou 2018-04-05 11:47:54 +0900 (Thu, 05 Apr 2018) New Revision: 7c490b4d435f8a5d96bdbddf0034a99151d4c925 https://github.com/groonga/groonga/commit/7c490b4d435f8a5d96bdbddf0034a99151d4c925 Message: option: support multiple option value per ID It required MessagePack. Modified files: include/groonga/option.h lib/grn_options.h lib/options.c Modified: include/groonga/option.h (+4 -0) =================================================================== --- include/groonga/option.h 2018-04-05 10:11:26 +0900 (9d889eba2) +++ include/groonga/option.h 2018-04-05 11:47:54 +0900 (024f064b7) @@ -22,6 +22,10 @@ extern "C" { #endif +typedef void * grn_option_revision; +#define GRN_OPTION_REVISION_NONE ((grn_option_revision)0) +#define GRN_OPTION_REVISION_UNCHANGED ((grn_option_revision)1) + #define GRN_OPTION_VALUES_EACH_BEGIN(ctx, \ option_values, \ i, \ Modified: lib/grn_options.h (+9 -4) =================================================================== --- lib/grn_options.h 2018-04-05 10:11:26 +0900 (bab2f1911) +++ lib/grn_options.h 2018-04-05 11:47:54 +0900 (2f2775993) @@ -43,11 +43,16 @@ grn_rc grn_options_flush(grn_ctx *ctx, grn_options *options); grn_rc grn_options_set(grn_ctx *ctx, grn_options *options, grn_id id, + const char *name, + int name_length, grn_obj *values); -grn_bool grn_options_get(grn_ctx *ctx, - grn_options *options, - grn_id id, - grn_obj *values); +grn_option_revision grn_options_get(grn_ctx *ctx, + grn_options *options, + grn_id id, + const char *name, + int name_length, + grn_option_revision revision, + grn_obj *values); #ifdef __cplusplus } Modified: lib/options.c (+143 -8) =================================================================== --- lib/options.c 2018-04-05 10:11:26 +0900 (3f069bc23) +++ lib/options.c 2018-04-05 11:47:54 +0900 (d2130f63c) @@ -16,12 +16,17 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "grn_options.h" #include "grn_db.h" +#include "grn_msgpack.h" +#include "grn_options.h" #include "grn_util.h" #include <stdio.h> +#ifdef GRN_WITH_MESSAGE_PACK +# include <groonga/msgpack.h> +#endif /* GRN_WITH_MESSAGE_PACK */ + struct _grn_options { grn_ja *values; }; @@ -166,36 +171,166 @@ grn_options_flush(grn_ctx *ctx, grn_options *options) return grn_obj_flush(ctx, (grn_obj *)(options->values)); } +#ifdef GRN_WITH_MESSAGE_PACK +typedef struct { + grn_ctx *ctx; + grn_obj *buffer; +} grn_options_msgpack_write_data; + +static int +grn_options_msgpack_write(void *data, const char *buf, msgpack_size_t len) +{ + grn_options_msgpack_write_data *write_data = data; + return grn_bulk_write(write_data->ctx, + write_data->buffer, + buf, + len); +} +#endif /* GRN_WITH_MESSAGE_PACK */ + grn_rc grn_options_set(grn_ctx *ctx, grn_options *options, grn_id id, + const char *name, + int name_length, grn_obj *values) { - return grn_ja_putv(ctx, options->values, id, values, 0); +#ifdef GRN_WITH_MESSAGE_PACK + msgpack_packer packer; + grn_options_msgpack_write_data data; + grn_obj buffer; + grn_io_win iw; + void *raw_value; + uint32_t length; + unsigned int i, n; + + if (name_length < 0) { + name_length = strlen(name); + } + + GRN_TEXT_INIT(&buffer, 0); + data.ctx = ctx; + data.buffer = &buffer; + + msgpack_packer_init(&packer, &data, grn_options_msgpack_write); + + raw_value = grn_ja_ref(ctx, options->values, id, &iw, &length); + if (raw_value) { + msgpack_unpacker unpacker; + msgpack_unpacked unpacked; + + msgpack_unpacker_init(&unpacker, MSGPACK_UNPACKER_INIT_BUFFER_SIZE); + msgpack_unpacked_init(&unpacked); + msgpack_unpacked_destroy(&unpacked); + msgpack_unpacker_destroy(&unpacker); + + grn_ja_unref(ctx, &iw); + } else { + msgpack_pack_map(&packer, 1); + msgpack_pack_str(&packer, name_length); + msgpack_pack_str_body(&packer, name, name_length); + } + + n = grn_vector_size(ctx, values); + msgpack_pack_array(&packer, n); + for (i = 0; i < n; i++) { + const char *value; + unsigned int value_size; + grn_id value_domain; + + value_size = grn_vector_get_element(ctx, + values, + i, + &value, + NULL, + &value_domain); + grn_msgpack_pack_raw_internal(ctx, &packer, value, value_size, value_domain); + if (ctx->rc != GRN_SUCCESS) { + break; + } + } + + if (ctx->rc == GRN_SUCCESS) { + grn_ja_put(ctx, + options->values, + id, + GRN_TEXT_VALUE(&buffer), + GRN_TEXT_LEN(&buffer), + GRN_OBJ_SET, + NULL); + } + GRN_OBJ_FIN(ctx, &buffer); +#else /* GRN_WITH_MESSAGE_PACK */ + ERR(GRN_FUNCTION_NOT_IMPLEMENTED, "[options] MessagePack is required"); +#endif /* GRN_WITH_MESSAGE_PACK */ + return ctx->rc; } -grn_bool +grn_option_revision grn_options_get(grn_ctx *ctx, grn_options *options, grn_id id, + const char *name, + int name_length, + grn_option_revision revision, grn_obj *value) { +#ifdef GRN_WITH_MESSAGE_PACK + grn_bool found = GRN_FALSE; grn_io_win iw; void *raw_value; uint32_t length; + msgpack_unpacker unpacker; + msgpack_unpacked unpacked; raw_value = grn_ja_ref(ctx, options->values, id, &iw, &length); if (!raw_value) { - return GRN_FALSE; + return GRN_OPTION_REVISION_NONE; + } + + if (raw_value == revision) { + return GRN_OPTION_REVISION_UNCHANGED; + } + + if (name_length < 0) { + name_length = strlen(name); } - if (value->header.type != GRN_VECTOR) { - grn_obj_reinit(ctx, value, value->header.domain, GRN_OBJ_VECTOR); + msgpack_unpacker_init(&unpacker, length); + msgpack_unpacked_init(&unpacked); + memcpy(msgpack_unpacker_buffer(&unpacker), + iw.addr, + length); + msgpack_unpacker_buffer_consumed(&unpacker, length); + while (MSGPACK_UNPACKER_NEXT(&unpacker, &unpacked)) { + msgpack_object *object = &(unpacked.data); + if (object->type == MSGPACK_OBJECT_MAP) { + msgpack_object_map *map = &(object->via.map); + uint32_t i; + for (i = 0; i < map->size; i++) { + msgpack_object_kv *kv = map->ptr; + if (kv->key.type == MSGPACK_OBJECT_STR && + kv->key.via.str.size == name_length && + memcmp(kv->key.via.str.ptr, name, name_length) == 0) { + if (kv->val.type == MSGPACK_OBJECT_ARRAY) { + grn_msgpack_unpack_array_internal(ctx, + &(kv->val.via.array), + value); + found = GRN_TRUE; + } + break; + } + } + } } - grn_vector_decode(ctx, value, raw_value, length); + msgpack_unpacked_destroy(&unpacked); + msgpack_unpacker_destroy(&unpacker); grn_ja_unref(ctx, &iw); - return GRN_TRUE; + return raw_value; +#else /* GRN_WITH_MESSAGE_PACK */ + return GRN_OPTION_REVISION_NONE; +#endif /* GRN_WITH_MESSAGE_PACK */ } -------------- next part -------------- HTML����������������������������... URL: https://lists.osdn.me/mailman/archives/groonga-commit/attachments/20180405/5366789c/attachment-0001.htm