[Groonga-commit] groonga/groonga at 7c490b4 [master] option: support multiple option value per ID

Back to archive index

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 



More information about the Groonga-commit mailing list
Back to archive index