[Groonga-commit] groonga/groonga at 3d10711 [master] ii: add support for auto destination chunk expansion

Back to archive index
Kouhei Sutou null+****@clear*****
Mon Mar 25 12:44:08 JST 2019


Kouhei Sutou	2019-03-25 12:44:08 +0900 (Mon, 25 Mar 2019)

  Revision: 3d1071188b32fe0bebb3f484da5c5482e04b4b2b
  https://github.com/groonga/groonga/commit/3d1071188b32fe0bebb3f484da5c5482e04b4b2b

  Message:
    ii: add support for auto destination chunk expansion

  Modified files:
    lib/grn_io.h
    lib/ii.c

  Modified: lib/grn_io.h (+2 -0)
===================================================================
--- lib/grn_io.h    2019-03-24 17:32:43 +0900 (8389a8d10)
+++ lib/grn_io.h    2019-03-25 12:44:08 +0900 (2f2c4563f)
@@ -370,6 +370,8 @@ grn_rc grn_io_flush(grn_ctx *ctx, grn_io *io);
 
 /* encode/decode */
 
+#define GRN_B_ENC_MAX_SIZE 5
+
 /* B is for BER */
 #define GRN_B_ENC(v,p) do {\
   uint8_t *_p = (uint8_t *)p; \

  Modified: lib/ii.c (+304 -253)
===================================================================
--- lib/ii.c    2019-03-24 17:32:43 +0900 (52d5095f9)
+++ lib/ii.c    2019-03-25 12:44:08 +0900 (98498148d)
@@ -1723,6 +1723,9 @@ pack_(uint32_t *p, uint32_t i, int w, uint8_t *rp)
   }
 }
 
+/* TODO: This is too rough. I hope that this is large enough. */
+#define PACK_MAX_SIZE ((UNIT_SIZE / 8) * 32 + (UNIT_SIZE * GRN_B_ENC_MAX_SIZE))
+
 static uint8_t *
 pack(uint32_t *p, uint32_t i, uint8_t *freq, uint8_t *rp)
 {
@@ -1856,10 +1859,11 @@ datavec_fin(grn_ctx *ctx, datavec *dv)
 }
 
 /* p is for PForDelta */
-size_t
+static size_t
 grn_p_encv(grn_ctx *ctx, datavec *dv, uint32_t dvlen, uint8_t *res)
 {
   uint8_t *rp = res, freq[33];
+  size_t estimated = 0;
   /* f in df is for frequency */
   uint32_t pgap, usep, l, df, data_size, *dp, *dpe;
   if (!dvlen || !(df = dv[0].data_size)) { return 0; }
@@ -1874,18 +1878,34 @@ grn_p_encv(grn_ctx *ctx, datavec *dv, uint32_t dvlen, uint8_t *res)
   }
   pgap = data_size - df * dvlen;
   if (!usep) {
-    GRN_B_ENC((df << 1) + 1, rp);
+    if (rp) {
+      GRN_B_ENC((df << 1) + 1, rp);
+    } else {
+      estimated += GRN_B_ENC_MAX_SIZE;
+    }
     for (l = 0; l < dvlen; l++) {
       for (dp = dv[l].data, dpe = dp + dv[l].data_size; dp < dpe; dp++) {
-        GRN_B_ENC(*dp, rp);
+        if (rp) {
+          GRN_B_ENC(*dp, rp);
+        } else {
+          estimated += GRN_B_ENC_MAX_SIZE;
+        }
       }
     }
   } else {
     uint32_t buf[UNIT_SIZE];
-    GRN_B_ENC((usep << 1), rp);
-    GRN_B_ENC(df, rp);
+    if (rp) {
+      GRN_B_ENC((usep << 1), rp);
+      GRN_B_ENC(df, rp);
+    } else {
+      estimated += GRN_B_ENC_MAX_SIZE * 2;
+    }
     if (dv[dvlen - 1].flags & ODD) {
-      GRN_B_ENC(pgap, rp);
+      if (rp) {
+        GRN_B_ENC(pgap, rp);
+      } else {
+        estimated += GRN_B_ENC_MAX_SIZE;
+      }
     } else {
       GRN_ASSERT(!pgap);
     }
@@ -1897,7 +1917,11 @@ grn_p_encv(grn_ctx *ctx, datavec *dv, uint32_t dvlen, uint8_t *res)
         memset(freq, 0, 33);
         while (dp < dpe) {
           if (j == UNIT_SIZE) {
-            rp = pack(buf, j, freq, rp);
+            if (rp) {
+              rp = pack(buf, j, freq, rp);
+            } else {
+              estimated += PACK_MAX_SIZE;
+            }
             memset(freq, 0, 33);
             j = 0;
           }
@@ -1909,13 +1933,29 @@ grn_p_encv(grn_ctx *ctx, datavec *dv, uint32_t dvlen, uint8_t *res)
             freq[0]++;
           }
         }
-        if (j) { rp = pack(buf, j, freq, rp); }
+        if (j > 0) {
+          if (rp) {
+            rp = pack(buf, j, freq, rp);
+          } else {
+            estimated += PACK_MAX_SIZE;
+          }
+        }
       } else {
-        while (dp < dpe) { GRN_B_ENC(*dp++, rp); }
+        for (; dp < dpe; dp++) {
+          if (rp) {
+            GRN_B_ENC(*dp, rp);
+          } else {
+            estimated += GRN_B_ENC_MAX_SIZE;
+          }
+        }
       }
     }
   }
-  return rp - res;
+  if (rp) {
+    return rp - res;
+  } else {
+    return estimated;
+  }
 }
 
 #define GRN_B_DEC_CHECK(v,p,pe) do { \
@@ -3867,15 +3907,63 @@ buffer_merge_dump_datavec(grn_ctx *ctx,
   GRN_OBJ_FIN(ctx, &buffer);
 }
 
-/* If dc doesn't have enough space, program may be crashed.
- * TODO: Support auto space extension or max size check.
- */
+static void
+buffer_merge_ensure_dc(grn_ctx *ctx,
+                       grn_ii *ii,
+                       uint8_t **dc,
+                       uint8_t **dcp,
+                       size_t *dc_size,
+                       size_t required_size,
+                       const char *tag)
+{
+  size_t dc_used_size = *dcp - *dc;
+  if (required_size <= (*dc_size - dc_used_size)) {
+    return;
+  }
+
+  size_t new_dc_size = *dc_size * 2;
+  while (required_size > (new_dc_size - dc_used_size)) {
+    new_dc_size *= 2;
+  }
+  uint8_t *new_dc = GRN_REALLOC(*dc, new_dc_size);
+  if (new_dc) {
+    DEFINE_NAME(ii);
+    GRN_LOG(ctx,
+            GRN_LOG_INFO,
+            "[ii][buffer][merge]%s destination chunk is expanded: "
+            "<%.*s>: "
+            "<%" GRN_FMT_SIZE "> -> <%" GRN_FMT_SIZE ">",
+            tag,
+            name_size, name,
+            *dc_size,
+            new_dc_size);
+    *dcp = new_dc + dc_used_size;
+    *dc = new_dc;
+    *dc_size = new_dc_size;
+  } else {
+    grn_rc rc = ctx->rc;
+    if (rc == GRN_SUCCESS) {
+      rc = GRN_NO_MEMORY_AVAILABLE;
+    }
+    DEFINE_NAME(ii);
+    ERR(rc,
+        "[ii][buffer][merge]%s failed to expand destination chunk: "
+        "<%.*s>: "
+        "<%" GRN_FMT_SIZE "> -> <%" GRN_FMT_SIZE ">",
+        tag,
+        name_size, name,
+        *dc_size,
+        new_dc_size);
+  }
+}
+
 static grn_rc
 buffer_merge(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h,
-             buffer *sb, uint8_t *sc, buffer *db, uint8_t *dc)
+             buffer *sb, uint8_t *sc, buffer *db, uint8_t **dc_output)
 {
   buffer_term *bt;
-  uint8_t *dcp = dc;
+  uint8_t *dc = NULL;
+  uint8_t *dcp = NULL;
   datavec dv[MAX_N_ELEMENTS + 1];
   datavec rdv[MAX_N_ELEMENTS + 1];
   uint16_t n = db->header.nterms, nterms_void = 0;
@@ -3910,6 +3998,24 @@ buffer_merge(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h,
   if ((ii->header->flags & GRN_OBJ_WITH_POSITION)) {
     rdv[ii->n_elements - 1].flags = ODD;
   }
+
+  size_t dc_size = (sb->header.chunk_size + S_SEGMENT) * 2;
+  dc = GRN_MALLOC(dc_size);
+  if (!dc) {
+    grn_rc rc = ctx->rc;
+    if (rc == GRN_SUCCESS) {
+      rc = GRN_NO_MEMORY_AVAILABLE;
+    }
+    DEFINE_NAME(ii);
+    ERR(rc,
+        "[ii][buffer][merge] failed to allocate destination chunk: "
+        "<%.*s>: <%" GRN_FMT_SIZE ">",
+        name_size, name,
+        dc_size);
+    goto exit;
+  }
+  dcp = dc;
+
   for (bt = db->terms; n; n--, bt++) {
     merger_data data = {0};
     merger_buffer_data *buffer_data = &(data.source.buffer);
@@ -3950,6 +4056,16 @@ buffer_merge(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h,
         goto exit;
       }
       if (bt->size_in_chunk > 0) {
+        buffer_merge_ensure_dc(ctx,
+                               ii,
+                               &dc,
+                               &dcp,
+                               &dc_size,
+                               bt->size_in_chunk,
+                               "[copy-chunk]");
+        if (ctx->rc != GRN_SUCCESS) {
+          goto exit;
+        }
         grn_memcpy(dcp,
                    chunk_data->data_start + bt->pos_in_chunk,
                    bt->size_in_chunk);
@@ -4184,7 +4300,6 @@ buffer_merge(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h,
           nterms_void++;
         } else {
           int j = 0;
-          uint8_t *dcp0;
           uint32_t encsize;
           uint32_t f_s = (ndf < 3) ? 0 : USE_P_ENC;
           uint32_t f_d = ((ndf < 16) || (ndf <= (data.last_id.rid >> 8))) ? 0 : USE_P_ENC;
@@ -4206,15 +4321,27 @@ buffer_merge(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h,
             }
             dv[j].data_size = np; dv[j].flags = f_p|ODD;
           }
-          dcp0 = dcp;
+
+          const size_t dc_offset = dcp - dc;
           a[1] =
             (bt->size_in_chunk ? a[1] : 0) +
             (ndf - chunk_data->n_documents) +
             balance;
           if (nvchunks) {
-            int i;
+            buffer_merge_ensure_dc(ctx,
+                                   ii,
+                                   &dc,
+                                   &dcp,
+                                   &dc_size,
+                                   GRN_B_ENC_MAX_SIZE * (1 + 3 * nchunks),
+                                   "[encode-chunk-metadata]");
+            if (ctx->rc != GRN_SUCCESS) {
+              if (cinfo) { GRN_FREE(cinfo); }
+              array_unref(ii, tid);
+              goto exit;
+            }
             GRN_B_ENC(nvchunks, dcp);
-            for (i = 0; i < nchunks; i++) {
+            for (uint32_t i = 0; i < nchunks; i++) {
               if (cinfo[i].size) {
                 GRN_B_ENC(cinfo[i].segno, dcp);
                 GRN_B_ENC(cinfo[i].size, dcp);
@@ -4222,24 +4349,24 @@ buffer_merge(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h,
               }
             }
           }
-          encsize = grn_p_encv(ctx, dv, ii->n_elements, dcp);
-
-          if (grn_logger_pass(ctx, GRN_LOG_DEBUG)) {
-            if (buffer_data->buffer->header.chunk_size + S_SEGMENT <=
-                (dcp - dc) + encsize) {
-              GRN_LOG(ctx, GRN_LOG_DEBUG,
-                      "cs(%d)+(%d)=(%d)"
-                      "<=(%" GRN_FMT_LLD ")+(%d)="
-                      "(%" GRN_FMT_LLD ")",
-                      buffer_data->buffer->header.chunk_size,
-                      S_SEGMENT,
-                      buffer_data->buffer->header.chunk_size + S_SEGMENT,
-                      (long long int)(dcp - dc),
-                      encsize,
-                      (long long int)((dcp - dc) + encsize));
-              buffer_merge_dump_datavec(ctx, ii, dv, rdv);
-            }
+          const size_t estimated_encsize = grn_p_encv(ctx,
+                                                      dv,
+                                                      ii->n_elements,
+                                                      NULL);
+          buffer_merge_ensure_dc(ctx,
+                                 ii,
+                                 &dc,
+                                 &dcp,
+                                 &dc_size,
+                                 estimated_encsize,
+                                 "[encode-data-vector]");
+          if (ctx->rc != GRN_SUCCESS) {
+            buffer_merge_dump_datavec(ctx, ii, dv, rdv);
+            if (cinfo) { GRN_FREE(cinfo); }
+            array_unref(ii, tid);
+            goto exit;
           }
+          encsize = grn_p_encv(ctx, dv, ii->n_elements, dcp);
 
           if (encsize > CHUNK_SPLIT_THRESHOLD &&
               (cinfo || (cinfo = GRN_MALLOCN(chunk_info, nchunks + 1))) &&
@@ -4247,7 +4374,7 @@ buffer_merge(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h,
             int i;
             cinfo[nchunks].dgap = data.last_id.rid - crid;
             nvchunks++;
-            dcp = dcp0;
+            dcp = dc + dc_offset;
             GRN_B_ENC(nvchunks, dcp);
             for (i = 0; i <= nchunks; i++) {
               if (cinfo[i].size) {
@@ -4265,8 +4392,8 @@ buffer_merge(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h,
               bt->tid &= ~CHUNK_SPLIT;
             }
           }
-          bt->pos_in_chunk = (uint32_t)(dcp0 - dc);
-          bt->size_in_chunk = (uint32_t)(dcp - dcp0);
+          bt->pos_in_chunk = (uint32_t)dc_offset;
+          bt->size_in_chunk = (uint32_t)(dcp - (dc + dc_offset));
           bt->size_in_buffer = 0;
           bt->pos_in_buffer = 0;
         }
@@ -4285,6 +4412,13 @@ buffer_merge(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h,
   }
 
 exit :
+  if (ctx->rc == GRN_SUCCESS) {
+    *dc_output = dc;
+  } else {
+    if (dc) {
+      GRN_FREE(dc);
+    }
+  }
   datavec_fin(ctx, dv);
   datavec_fin(ctx, rdv);
   return ctx->rc;
@@ -4309,7 +4443,6 @@ buffer_flush(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h)
 {
   grn_io_win sw, dw;
   buffer *sb, *db = NULL;
-  uint8_t *dc, *sc = NULL;
   uint32_t ds, pseg, scn, dcn = 0;
   if (ii->header->binfo[seg] == GRN_II_PSEG_NOT_ASSIGNED) {
     DEFINE_NAME(ii);
@@ -4343,83 +4476,64 @@ buffer_flush(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h)
   {
     GRN_IO_SEG_REF(ii->seg, ds, db);
     if (db) {
-      uint32_t actual_chunk_size = 0;
-      uint32_t max_dest_chunk_size = sb->header.chunk_size + S_SEGMENT;
-      if ((dc = GRN_MALLOC(max_dest_chunk_size * 2))) {
-        if ((scn = sb->header.chunk) == GRN_II_PSEG_NOT_ASSIGNED ||
-            (sc = WIN_MAP(ii->chunk, ctx, &sw, scn, 0,
-                          sb->header.chunk_size, grn_io_rdonly))) {
-          uint16_t n = sb->header.nterms;
-          memset(db, 0, S_SEGMENT);
-          grn_memcpy(db->terms, sb->terms, n * sizeof(buffer_term));
-          db->header.nterms = n;
-          buffer_merge(ctx, ii, seg, h, sb, sc, db, dc);
+      uint8_t *sc = NULL;
+      if ((scn = sb->header.chunk) == GRN_II_PSEG_NOT_ASSIGNED ||
+          (sc = WIN_MAP(ii->chunk, ctx, &sw, scn, 0,
+                        sb->header.chunk_size, grn_io_rdonly))) {
+        uint16_t n = sb->header.nterms;
+        memset(db, 0, S_SEGMENT);
+        grn_memcpy(db->terms, sb->terms, n * sizeof(buffer_term));
+        db->header.nterms = n;
+        uint8_t *dc = NULL;
+        buffer_merge(ctx, ii, seg, h, sb, sc, db, &dc);
+        if (ctx->rc == GRN_SUCCESS) {
+          const uint32_t actual_chunk_size = db->header.chunk_size;
+          if (actual_chunk_size > 0) {
+            chunk_new(ctx, ii, &dcn, actual_chunk_size);
+          }
           if (ctx->rc == GRN_SUCCESS) {
-            actual_chunk_size = db->header.chunk_size;
-            if (actual_chunk_size > 0) {
-              chunk_new(ctx, ii, &dcn, actual_chunk_size);
-            }
-            if (ctx->rc == GRN_SUCCESS) {
-              grn_rc rc;
-              db->header.chunk =
-                actual_chunk_size ? dcn : GRN_II_PSEG_NOT_ASSIGNED;
-              fake_map(ctx, ii->chunk, &dw, dc, dcn, actual_chunk_size);
-              rc = grn_io_win_unmap(&dw);
-              if (rc == GRN_SUCCESS) {
-                buffer_segment_update(ii, seg, ds);
-                ii->header->total_chunk_size += actual_chunk_size;
-                if (scn != GRN_II_PSEG_NOT_ASSIGNED) {
-                  grn_io_win_unmap(&sw);
-                  chunk_free(ctx, ii, scn, 0, sb->header.chunk_size);
-                  ii->header->total_chunk_size -= sb->header.chunk_size;
-                }
-              } else {
-                GRN_FREE(dc);
-                if (actual_chunk_size) {
-                  chunk_free(ctx, ii, dcn, 0, actual_chunk_size);
-                }
-                if (scn != GRN_II_PSEG_NOT_ASSIGNED) { grn_io_win_unmap(&sw); }
-                {
-                  DEFINE_NAME(ii);
-                  ERR(rc,
-                      "[ii][buffer][flush] failed to unmap a destination chunk: "
-                      "<%.*s> : "
-                      "segment:<%u>, destination-segment:<%u>, actual-size:<%u>",
-                      name_size, name,
-                      seg,
-                      dcn,
-                      actual_chunk_size);
-                }
+            grn_rc rc;
+            db->header.chunk =
+              (actual_chunk_size > 0) ? dcn : GRN_II_PSEG_NOT_ASSIGNED;
+            fake_map(ctx, ii->chunk, &dw, dc, dcn, actual_chunk_size);
+            rc = grn_io_win_unmap(&dw);
+            if (rc == GRN_SUCCESS) {
+              dc = NULL;
+              buffer_segment_update(ii, seg, ds);
+              ii->header->total_chunk_size += actual_chunk_size;
+              if (scn != GRN_II_PSEG_NOT_ASSIGNED) {
+                chunk_free(ctx, ii, scn, 0, sb->header.chunk_size);
+                ii->header->total_chunk_size -= sb->header.chunk_size;
               }
             } else {
-              GRN_FREE(dc);
-              if (scn != GRN_II_PSEG_NOT_ASSIGNED) { grn_io_win_unmap(&sw); }
+              DEFINE_NAME(ii);
+              ERR(rc,
+                  "[ii][buffer][flush] failed to unmap a destination chunk: "
+                  "<%.*s> : "
+                  "segment:<%u>, destination-segment:<%u>, actual-size:<%u>",
+                  name_size, name,
+                  seg,
+                  dcn,
+                  actual_chunk_size);
+            }
+            if (actual_chunk_size > 0) {
+              chunk_free(ctx, ii, dcn, 0, actual_chunk_size);
             }
-          } else {
-            GRN_FREE(dc);
-            if (scn != GRN_II_PSEG_NOT_ASSIGNED) { grn_io_win_unmap(&sw); }
           }
-        } else {
-          GRN_FREE(dc);
-          {
-            DEFINE_NAME(ii);
-            MERR("[ii][buffer][flush] failed to map a source chunk: "
-                 "<%.*s>: "
-                 "segment:<%u>, source-segment:<%u>, chunk-size:<%u>",
-                 name_size, name,
-                 seg,
-                 scn,
-                 sb->header.chunk_size);
+          if (dc) {
+            GRN_FREE(dc);
           }
         }
+        if (scn != GRN_II_PSEG_NOT_ASSIGNED) { grn_io_win_unmap(&sw); }
       } else {
         DEFINE_NAME(ii);
-        MERR("[ii][buffer][flush] failed to allocate a destination chunk: "
+        MERR("[ii][buffer][flush] failed to map a source chunk: "
              "<%.*s>: "
-             "segment:<%u>, destination-segment:<%u>",
+             "segment:<%u>, source-segment:<%u>, chunk-size:<%u>",
              name_size, name,
              seg,
-             ds);
+             scn,
+             sb->header.chunk_size);
       }
       GRN_IO_SEG_UNREF(ii->seg, ds);
     } else {
@@ -4720,7 +4834,6 @@ buffer_split(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h)
 {
   grn_io_win sw, dw0, dw1;
   buffer *sb, *db0 = NULL, *db1 = NULL;
-  uint8_t *sc = NULL, *dc0, *dc1;
   uint32_t dps0 = 0, dps1 = 0, dls0 = 0, dls1 = 0, sps, scn, dcn0 = 0, dcn1 = 0;
   if (ii->header->binfo[seg] == GRN_II_PSEG_NOT_ASSIGNED) {
     DEFINE_NAME(ii);
@@ -4756,178 +4869,116 @@ buffer_split(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h)
     if (db0) {
       GRN_IO_SEG_REF(ii->seg, dps1, db1);
       if (db1) {
-        uint32_t actual_db0_chunk_size = 0;
-        uint32_t actual_db1_chunk_size = 0;
-        uint32_t max_dest_chunk_size = sb->header.chunk_size + S_SEGMENT;
-        if ((dc0 = GRN_MALLOC(max_dest_chunk_size * 2))) {
-          if ((dc1 = GRN_MALLOC(max_dest_chunk_size * 2))) {
-            if ((scn = sb->header.chunk) == GRN_II_PSEG_NOT_ASSIGNED ||
-                (sc = WIN_MAP(ii->chunk, ctx, &sw, scn, 0,
-                              sb->header.chunk_size, grn_io_rdonly))) {
-              term_split(ctx, ii->lexicon, sb, db0, db1);
-              buffer_merge(ctx, ii, seg, h, sb, sc, db0, dc0);
-              if (ctx->rc == GRN_SUCCESS) {
-                actual_db0_chunk_size = db0->header.chunk_size;
-                if (actual_db0_chunk_size > 0) {
-                  chunk_new(ctx, ii, &dcn0, actual_db0_chunk_size);
-                }
+        uint8_t *sc = NULL;
+        if ((scn = sb->header.chunk) == GRN_II_PSEG_NOT_ASSIGNED ||
+            (sc = WIN_MAP(ii->chunk, ctx, &sw, scn, 0,
+                          sb->header.chunk_size, grn_io_rdonly))) {
+          term_split(ctx, ii->lexicon, sb, db0, db1);
+          uint8_t *dc0 = NULL;
+          buffer_merge(ctx, ii, seg, h, sb, sc, db0, &dc0);
+          if (ctx->rc == GRN_SUCCESS) {
+            const uint32_t actual_db0_chunk_size = db0->header.chunk_size;
+            if (actual_db0_chunk_size > 0) {
+              chunk_new(ctx, ii, &dcn0, actual_db0_chunk_size);
+            }
+            if (ctx->rc == GRN_SUCCESS) {
+              grn_rc rc;
+              db0->header.chunk =
+                actual_db0_chunk_size ? dcn0 : GRN_II_PSEG_NOT_ASSIGNED;
+              fake_map(ctx, ii->chunk, &dw0, dc0, dcn0, actual_db0_chunk_size);
+              rc = grn_io_win_unmap(&dw0);
+              if (rc == GRN_SUCCESS) {
+                dc0 = NULL;
+                uint8_t *dc1 = NULL;
+                buffer_merge(ctx, ii, seg, h, sb, sc, db1, &dc1);
                 if (ctx->rc == GRN_SUCCESS) {
-                  grn_rc rc;
-                  db0->header.chunk =
-                    actual_db0_chunk_size ? dcn0 : GRN_II_PSEG_NOT_ASSIGNED;
-                  fake_map(ctx, ii->chunk, &dw0, dc0, dcn0, actual_db0_chunk_size);
-                  rc = grn_io_win_unmap(&dw0);
-                  if (rc == GRN_SUCCESS) {
-                    buffer_merge(ctx, ii, seg, h, sb, sc, db1, dc1);
-                    if (ctx->rc == GRN_SUCCESS) {
-                      actual_db1_chunk_size = db1->header.chunk_size;
-                      if (actual_db1_chunk_size > 0) {
-                        chunk_new(ctx, ii, &dcn1, actual_db1_chunk_size);
-                      }
-                      if (ctx->rc == GRN_SUCCESS) {
-                        fake_map(ctx, ii->chunk, &dw1, dc1, dcn1,
-                                 actual_db1_chunk_size);
-                        rc = grn_io_win_unmap(&dw1);
-                        if (rc == GRN_SUCCESS) {
-                          db1->header.chunk =
-                            actual_db1_chunk_size ? dcn1 : GRN_II_PSEG_NOT_ASSIGNED;
-                          buffer_segment_update(ii, dls0, dps0);
-                          buffer_segment_update(ii, dls1, dps1);
-                          array_update(ctx, ii, dls0, db0);
-                          array_update(ctx, ii, dls1, db1);
-                          buffer_segment_clear(ii, seg);
-                          ii->header->total_chunk_size += actual_db0_chunk_size;
-                          ii->header->total_chunk_size += actual_db1_chunk_size;
-                          if (scn != GRN_II_PSEG_NOT_ASSIGNED) {
-                            grn_io_win_unmap(&sw);
-                            chunk_free(ctx, ii, scn, 0, sb->header.chunk_size);
-                            ii->header->total_chunk_size -= sb->header.chunk_size;
-                          }
-                        } else {
-                          if (actual_db1_chunk_size) {
-                            chunk_free(ctx, ii, dcn1, 0, actual_db1_chunk_size);
-                          }
-                          if (actual_db0_chunk_size) {
-                            chunk_free(ctx, ii, dcn0, 0, actual_db0_chunk_size);
-                          }
-                          GRN_FREE(dc1);
-                          if (scn != GRN_II_PSEG_NOT_ASSIGNED) {
-                            grn_io_win_unmap(&sw);
-                          }
-                          {
-                            DEFINE_NAME(ii);
-                            ERR(rc,
-                                "[ii][buffer][merge] "
-                                "failed to unmap a destination chunk2: "
-                                "<%.*s> :"
-                                "segment:<%u>, "
-                                "destination-chunk1:<%u>, "
-                                "destination-chunk2:<%u>, "
-                                "actual-size1:<%u>, "
-                                "actual-size2:<%u>",
-                                name_size, name,
-                                seg,
-                                dcn0,
-                                dcn1,
-                                actual_db0_chunk_size,
-                                actual_db1_chunk_size);
-                          }
-                        }
-                      } else {
-                        if (actual_db0_chunk_size) {
-                          chunk_free(ctx, ii, dcn0, 0, actual_db0_chunk_size);
-                        }
-                        GRN_FREE(dc1);
-                        if (scn != GRN_II_PSEG_NOT_ASSIGNED) {
-                          grn_io_win_unmap(&sw);
-                        }
-                      }
-                    } else {
-                      if (actual_db0_chunk_size) {
-                        chunk_free(ctx, ii, dcn0, 0, actual_db0_chunk_size);
-                      }
-                      GRN_FREE(dc1);
+                  const uint32_t actual_db1_chunk_size = db1->header.chunk_size;
+                  if (actual_db1_chunk_size > 0) {
+                    chunk_new(ctx, ii, &dcn1, actual_db1_chunk_size);
+                  }
+                  if (ctx->rc == GRN_SUCCESS) {
+                    fake_map(ctx, ii->chunk, &dw1, dc1, dcn1,
+                             actual_db1_chunk_size);
+                    rc = grn_io_win_unmap(&dw1);
+                    if (rc == GRN_SUCCESS) {
+                      dc1 = NULL;
+                      db1->header.chunk =
+                        (actual_db1_chunk_size > 0) ?
+                        dcn1 :
+                        GRN_II_PSEG_NOT_ASSIGNED;
+                      buffer_segment_update(ii, dls0, dps0);
+                      buffer_segment_update(ii, dls1, dps1);
+                      array_update(ctx, ii, dls0, db0);
+                      array_update(ctx, ii, dls1, db1);
+                      buffer_segment_clear(ii, seg);
+                      ii->header->total_chunk_size += actual_db0_chunk_size;
+                      ii->header->total_chunk_size += actual_db1_chunk_size;
                       if (scn != GRN_II_PSEG_NOT_ASSIGNED) {
-                        grn_io_win_unmap(&sw);
+                        chunk_free(ctx, ii, scn, 0, sb->header.chunk_size);
+                        ii->header->total_chunk_size -= sb->header.chunk_size;
                       }
-                    }
-                  } else {
-                    if (actual_db0_chunk_size) {
-                      chunk_free(ctx, ii, dcn0, 0, actual_db0_chunk_size);
-                    }
-                    GRN_FREE(dc1);
-                    GRN_FREE(dc0);
-                    if (scn != GRN_II_PSEG_NOT_ASSIGNED) {
-                      grn_io_win_unmap(&sw);
-                    }
-                    {
+                    } else {
                       DEFINE_NAME(ii);
                       ERR(rc,
                           "[ii][buffer][merge] "
-                          "failed to unmap a destination chunk1: "
-                          "<%.*s> :"
+                          "failed to unmap a destination chunk2: "
+                          "<%.*s>: "
                           "segment:<%u>, "
                           "destination-chunk1:<%u>, "
-                          "actual-size1:<%u>",
+                          "destination-chunk2:<%u>, "
+                          "actual-size1:<%u>, "
+                          "actual-size2:<%u>",
                           name_size, name,
                           seg,
                           dcn0,
-                          actual_db0_chunk_size);
+                          dcn1,
+                          actual_db0_chunk_size,
+                          actual_db1_chunk_size);
+                    }
+                    if (actual_db1_chunk_size > 0) {
+                      chunk_free(ctx, ii, dcn1, 0, actual_db1_chunk_size);
                     }
                   }
-                } else {
-                  GRN_FREE(dc1);
-                  GRN_FREE(dc0);
-                  if (scn != GRN_II_PSEG_NOT_ASSIGNED) { grn_io_win_unmap(&sw); }
+                  if (dc1) {
+                    GRN_FREE(dc1);
+                  }
                 }
               } else {
-                GRN_FREE(dc1);
-                GRN_FREE(dc0);
-                if (scn != GRN_II_PSEG_NOT_ASSIGNED) { grn_io_win_unmap(&sw); }
-              }
-            } else {
-              GRN_FREE(dc1);
-              GRN_FREE(dc0);
-              {
                 DEFINE_NAME(ii);
-                MERR("[ii][buffer][split] failed to map a source chunk: "
-                     "<%.*s> :"
-                     "segment:<%u>, "
-                     "source-segment:<%u>, "
-                     "chunk-size:<%u>",
-                     name_size, name,
-                     seg,
-                     scn,
-                     sb->header.chunk_size);
+                ERR(rc,
+                    "[ii][buffer][merge] "
+                    "failed to unmap a destination chunk1: "
+                    "<%.*s> :"
+                    "segment:<%u>, "
+                    "destination-chunk1:<%u>, "
+                    "actual-size1:<%u>",
+                    name_size, name,
+                    seg,
+                    dcn0,
+                    actual_db0_chunk_size);
+              }
+              if (actual_db0_chunk_size > 0) {
+                chunk_free(ctx, ii, dcn0, 0, actual_db0_chunk_size);
               }
             }
-          } else {
-            GRN_FREE(dc0);
-            {
-              DEFINE_NAME(ii);
-              MERR("[ii][buffer][split] "
-                   "failed to allocate a destination chunk2: "
-                   "<%.*s> :"
-                   "segment:<%u>, "
-                   "destination-segment1:<%u>, "
-                   "destination-segment2:<%u>",
-                   name_size, name,
-                   seg,
-                   dps0,
-                   dps1);
+            if (dc0) {
+              GRN_FREE(dc0);
             }
           }
+          if (scn != GRN_II_PSEG_NOT_ASSIGNED) {
+            grn_io_win_unmap(&sw);
+          }
         } else {
           DEFINE_NAME(ii);
-          MERR("[ii][buffer][split] failed to allocate a destination chunk1: "
-               "<%.*s>: "
+          MERR("[ii][buffer][split] failed to map a source chunk: "
+               "<%.*s> :"
                "segment:<%u>, "
-               "destination-segment1:<%u>, "
-               "destination-segment2:<%u>",
+               "source-segment:<%u>, "
+               "chunk-size:<%u>",
                name_size, name,
                seg,
-               dps0,
-               dps1);
+               scn,
+               sb->header.chunk_size);
         }
         GRN_IO_SEG_UNREF(ii->seg, dps1);
       } else {
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.osdn.me/mailman/archives/groonga-commit/attachments/20190325/09c37a29/attachment-0001.html>


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