[Groonga-commit] groonga/groonga [master] grn_ja supports GRN_OBJ_WITH_BUFFER.

Back to archive index

null+****@clear***** null+****@clear*****
2010年 8月 19日 (木) 18:41:46 JST


Daijiro MORI	2010-08-19 09:41:46 +0000 (Thu, 19 Aug 2010)

  New Revision: d679b8db09f5069638088125c021efeb1ec2b81c

  Log:
    grn_ja supports GRN_OBJ_WITH_BUFFER.

  Modified files:
    lib/store.c

  Modified: lib/store.c (+110 -19)
===================================================================
--- lib/store.c    2010-08-19 01:57:08 +0000 (14c0f38)
+++ lib/store.c    2010-08-19 09:41:46 +0000 (42964a2)
@@ -672,6 +672,28 @@ grn_ja_alloc(grn_ctx *ctx, grn_ja *ja, grn_id id,
   }
 }
 
+static grn_rc
+set_value(grn_ctx *ctx, grn_ja *ja, grn_id id, void *value, uint32_t value_len,
+          grn_ja_einfo *einfo)
+{
+  grn_rc rc = GRN_SUCCESS;
+  grn_io_win iw;
+  if ((ja->header->flags & GRN_OBJ_WITH_BUFFER) &&
+      value_len >= ja->header->max_element_size) {
+    if ((rc = grn_ja_alloc(ctx, ja, id, value_len + sizeof(uint32_t), einfo, &iw))) {
+      return rc;
+    }
+    memcpy(iw.addr, value, value_len);
+    memset((byte *)iw.addr + value_len, 0, sizeof(uint32_t));
+    grn_io_win_unmap2(&iw);
+  } else {
+    if ((rc = grn_ja_alloc(ctx, ja, id, value_len, einfo, &iw))) { return rc; }
+    memcpy(iw.addr, value, value_len);
+    grn_io_win_unmap2(&iw);
+  }
+  return rc;
+}
+
 grn_rc
 grn_ja_put_raw(grn_ctx *ctx, grn_ja *ja, grn_id id,
                void *value, uint32_t value_len, int flags, uint64_t *cas)
@@ -687,15 +709,46 @@ grn_ja_put_raw(grn_ctx *ctx, grn_ja *ja, grn_id id,
       uint32_t old_len;
       void *oldvalue = grn_ja_ref(ctx, ja, id, &jw, &old_len);
       if (oldvalue) {
-        if ((rc = grn_ja_alloc(ctx, ja, id, value_len + old_len, &einfo, &iw))) { return rc; }
-        memcpy(iw.addr, oldvalue, old_len);
-        memcpy((byte *)iw.addr + old_len, value, value_len);
+        if ((ja->header->flags & GRN_OBJ_WITH_BUFFER) &&
+            old_len + value_len >= ja->header->max_element_size) {
+          if (old_len >= ja->header->max_element_size) {
+            byte *b = oldvalue;
+            uint32_t el = old_len - sizeof(uint32_t);
+            uint32_t pos = *((uint32_t *)(b + el));
+            GRN_ASSERT(pos < el);
+            if (el <= pos + value_len) {
+              uint32_t rest = el - pos;
+              memcpy(b + pos, value, rest);
+              memcpy(b, (byte *)value + rest, value_len - rest);
+              *((uint32_t *)(b + el)) = value_len - rest;
+            } else {
+              memcpy(b + pos, value, value_len);
+              *((uint32_t *)(b + el)) = pos + value_len;
+            }
+          } else {
+            if ((rc = grn_ja_alloc(ctx, ja, id,
+                                   value_len + old_len + sizeof(uint32_t),
+                                   &einfo, &iw))) {
+              grn_ja_unref(ctx, &jw);
+              return rc;
+            }
+            memcpy(iw.addr, oldvalue, old_len);
+            memcpy((byte *)iw.addr + old_len, value, value_len);
+            memset((byte *)iw.addr + old_len + value_len, 0, sizeof(uint32_t));
+            grn_io_win_unmap2(&iw);
+          }
+        } else {
+          if ((rc = grn_ja_alloc(ctx, ja, id, value_len + old_len, &einfo, &iw))) {
+            grn_ja_unref(ctx, &jw);
+            return rc;
+          }
+          memcpy(iw.addr, oldvalue, old_len);
+          memcpy((byte *)iw.addr + old_len, value, value_len);
+          grn_io_win_unmap2(&iw);
+        }
         grn_ja_unref(ctx, &jw);
-        grn_io_win_unmap2(&iw);
       } else {
-        if ((rc = grn_ja_alloc(ctx, ja, id, value_len, &einfo, &iw))) { return rc; }
-        memcpy(iw.addr, value, value_len);
-        grn_io_win_unmap2(&iw);
+        set_value(ctx, ja, id, value, value_len, &einfo);
       }
     }
     break;
@@ -705,15 +758,46 @@ grn_ja_put_raw(grn_ctx *ctx, grn_ja *ja, grn_id id,
       uint32_t old_len;
       void *oldvalue = grn_ja_ref(ctx, ja, id, &jw, &old_len);
       if (oldvalue) {
-        if ((rc = grn_ja_alloc(ctx, ja, id, value_len + old_len, &einfo, &iw))) { return rc; }
-        memcpy(iw.addr, value, value_len);
-        memcpy((byte *)iw.addr + value_len, oldvalue, old_len);
+        if ((ja->header->flags & GRN_OBJ_WITH_BUFFER) &&
+            old_len + value_len >= ja->header->max_element_size) {
+          if (old_len >= ja->header->max_element_size) {
+            byte *b = oldvalue;
+            uint32_t el = old_len - sizeof(uint32_t);
+            uint32_t pos = *((uint32_t *)(b + el));
+            GRN_ASSERT(pos < el);
+            if (pos < value_len) {
+              uint32_t rest = value_len - pos;
+              memcpy(b, (byte *)value + rest, pos);
+              memcpy(b + el - rest, value, rest);
+              *((uint32_t *)(b + el)) = el - rest;
+            } else {
+              memcpy(b + pos - value_len, value, value_len);
+              *((uint32_t *)(b + el)) = pos - value_len;
+            }
+          } else {
+            if ((rc = grn_ja_alloc(ctx, ja, id,
+                                   value_len + old_len + sizeof(uint32_t),
+                                   &einfo, &iw))) {
+              grn_ja_unref(ctx, &jw);
+              return rc;
+            }
+            memcpy(iw.addr, value, value_len);
+            memcpy((byte *)iw.addr + value_len, oldvalue, old_len);
+            memset((byte *)iw.addr + value_len + old_len, 0, sizeof(uint32_t));
+            grn_io_win_unmap2(&iw);
+          }
+        } else {
+          if ((rc = grn_ja_alloc(ctx, ja, id, value_len + old_len, &einfo, &iw))) {
+            grn_ja_unref(ctx, &jw);
+            return rc;
+          }
+          memcpy(iw.addr, value, value_len);
+          memcpy((byte *)iw.addr + value_len, oldvalue, old_len);
+          grn_io_win_unmap2(&iw);
+        }
         grn_ja_unref(ctx, &jw);
-        grn_io_win_unmap2(&iw);
       } else {
-        if ((rc = grn_ja_alloc(ctx, ja, id, value_len, &einfo, &iw))) { return rc; }
-        memcpy(iw.addr, value, value_len);
-        grn_io_win_unmap2(&iw);
+        set_value(ctx, ja, id, value, value_len, &einfo);
       }
     }
     break;
@@ -751,10 +835,7 @@ grn_ja_put_raw(grn_ctx *ctx, grn_ja *ja, grn_id id,
     /* fallthru */
   case GRN_OBJ_SET :
     if (value_len) {
-      if ((rc = grn_ja_alloc(ctx, ja, id, value_len, &einfo, &iw))) { return rc; }
-      // printf("put id=%d, value_len=%d value=%p ei=%p(%d:%d)\n", id, value_len, buf, &einfo, einfo.pos, einfo.tail[0]);
-      memcpy(iw.addr, value, value_len);
-      grn_io_win_unmap2(&iw);
+      set_value(ctx, ja, id, value, value_len, &einfo);
     } else {
       memset(&einfo, 0, sizeof(grn_ja_einfo));
     }
@@ -991,7 +1072,17 @@ grn_ja_get_value(grn_ctx *ctx, grn_ja *ja, grn_id id, grn_obj *value)
     }
   }
   if ((v = grn_ja_ref(ctx, ja, id, &iw, &len))) {
-    grn_bulk_write(ctx, value, v, len);
+    if ((ja->header->flags & GRN_OBJ_WITH_BUFFER) &&
+        len > ja->header->max_element_size) {
+      byte *b = v;
+      uint32_t el = len - sizeof(uint32_t);
+      uint32_t pos = *((uint32_t *)(b + el));
+      GRN_ASSERT(pos < el);
+      grn_bulk_write(ctx, value, b + pos, el - pos);
+      grn_bulk_write(ctx, value, b, pos);
+    } else {
+      grn_bulk_write(ctx, value, v, len);
+    }
     grn_ja_unref(ctx, &iw);
   }
 exit :




Groonga-commit メーリングリストの案内
Back to archive index