[Groonga-commit] groonga/groonga [master] Add grn_array_push and grn_array_pull

Back to archive index

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 



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