[Groonga-commit] groonga/groonga at 2c143c4 [master] grn_ja_reader: add grn_ja_reader_ref/unref()

Back to archive index

Susumu Yata null+****@clear*****
Thu Dec 10 17:21:27 JST 2015


Susumu Yata	2015-12-10 17:21:27 +0900 (Thu, 10 Dec 2015)

  New Revision: 2c143c4c761294c371d1f759e325752895a12d5b
  https://github.com/groonga/groonga/commit/2c143c4c761294c371d1f759e325752895a12d5b

  Message:
    grn_ja_reader: add grn_ja_reader_ref/unref()
    
    GitHub; #446

  Modified files:
    lib/grn_store.h
    lib/store.c

  Modified: lib/grn_store.h (+29 -12)
===================================================================
--- lib/grn_store.h    2015-12-10 12:35:01 +0900 (1c92a85)
+++ lib/grn_store.h    2015-12-10 17:21:27 +0900 (b1580c7)
@@ -102,22 +102,30 @@ GRN_API uint32_t grn_ja_size(grn_ctx *ctx, grn_ja *ja, grn_id id);
 
 void grn_ja_check(grn_ctx *ctx, grn_ja *ja);
 
+#define GRN_JA_READER_INITIAL_REF_SEG_IDS_SIZE 16
+
 /*
  * grn_ja_reader is designed to improve the performance of sequential access.
  */
 typedef struct {
-  grn_ja *ja;               /* Target jagged array (without ref. count). */
-  uint32_t einfo_seg_id;    /* ID of the current header segment. */
-  void *einfo_seg_addr;     /* Address of the current header segment. */
-  void *einfo;              /* Header of the current value. */
-  uint32_t body_seg_id;     /* ID of the current body segment. */
-  uint32_t body_seg_offset; /* Offset in the current body segment. */
-  void *body_seg_addr;      /* Address of the current body segment. */
-  uint32_t value_size;      /* Size of the current value. */
-  uint32_t packed_size;     /* Compressed size of the current value. */
-  void *packed_buf;         /* Buffer for decompression. */
-  uint32_t packed_buf_size; /* Size of the buffer for decompression. */
-  void *stream;             /* Stream of a compression library. */
+  grn_ja *ja;                /* Target jagged array (without ref. count). */
+  uint32_t einfo_seg_id;     /* ID of the current header segment. */
+  void *einfo_seg_addr;      /* Address of the current header segment. */
+  void *einfo;               /* Header of the current value. */
+  grn_bool ref_avail;        /* grn_ja_reader_ref() is available or not. */
+  uint32_t ref_seg_id;       /* ID of the current referenced segment. */
+  void *ref_seg_addr;        /* Address of the current referenced segment. */
+  uint32_t *ref_seg_ids;     /* IDs of referenced segments. */
+  uint32_t nref_seg_ids;     /* Number of referenced segments. */
+  uint32_t ref_seg_ids_size; /* Maximum number of referenced segments. */
+  uint32_t body_seg_id;      /* ID of the current body segment. */
+  uint32_t body_seg_offset;  /* Offset in the current body segment. */
+  void *body_seg_addr;       /* Address of the current body segment. */
+  uint32_t value_size;       /* Size of the current value. */
+  uint32_t packed_size;      /* Compressed size of the current value. */
+  void *packed_buf;          /* Buffer for decompression. */
+  uint32_t packed_buf_size;  /* Size of the buffer for decompression. */
+  void *stream;              /* Stream of a compression library. */
 } grn_ja_reader;
 
 /*
@@ -144,6 +152,15 @@ grn_rc grn_ja_reader_close(grn_ctx *ctx, grn_ja_reader *reader);
  */
 grn_rc grn_ja_reader_seek(grn_ctx *ctx, grn_ja_reader *reader, grn_id id);
 
+/*
+ * grn_ja_reader_ref() gets the address to the current value.
+ * This function is available if `reader->ref_avail` is true.
+ */
+grn_rc grn_ja_reader_ref(grn_ctx *ctx, grn_ja_reader *reader, void **addr);
+
+/* grn_ja_reader_unref() frees refereces returned by grn_ja_reader_ref(). */
+grn_rc grn_ja_reader_unref(grn_ctx *ctx, grn_ja_reader *reader);
+
 /* grn_ja_reader_read() reads the current value to `buf`. */
 grn_rc grn_ja_reader_read(grn_ctx *ctx, grn_ja_reader *reader, void *buf);
 

  Modified: lib/store.c (+58 -0)
===================================================================
--- lib/store.c    2015-12-10 12:35:01 +0900 (3050d20)
+++ lib/store.c    2015-12-10 17:21:27 +0900 (0eac8da)
@@ -1580,6 +1580,11 @@ grn_ja_reader_init(grn_ctx *ctx, grn_ja_reader *reader, grn_ja *ja)
 {
   reader->ja = ja;
   reader->einfo_seg_id = JA_ESEG_VOID;
+  reader->ref_avail = GRN_FALSE;
+  reader->ref_seg_id = JA_ESEG_VOID;
+  reader->ref_seg_ids = NULL;
+  reader->nref_seg_ids = 0;
+  reader->ref_seg_ids_size = 0;
   reader->body_seg_id = JA_ESEG_VOID;
   reader->body_seg_addr = NULL;
   reader->packed_buf = NULL;
@@ -1610,6 +1615,10 @@ grn_ja_reader_fin(grn_ctx *ctx, grn_ja_reader *reader)
   if (reader->einfo_seg_id != JA_ESEG_VOID) {
     GRN_IO_SEG_UNREF(reader->ja->io, reader->einfo_seg_id);
   }
+  if (reader->ref_seg_ids) {
+    grn_ja_reader_unref(ctx, reader);
+    GRN_FREE(reader->ref_seg_ids);
+  }
   if (reader->body_seg_addr) {
     GRN_IO_SEG_UNREF(reader->ja->io, reader->body_seg_id);
   }
@@ -1729,11 +1738,14 @@ grn_ja_reader_seek_raw(grn_ctx *ctx, grn_ja_reader *reader, grn_id id)
   reader->einfo = einfo;
   if (ETINY_P(einfo)) {
     ETINY_DEC(einfo, reader->value_size);
+    reader->ref_avail = GRN_FALSE;
   } else {
     if (EHUGE_P(einfo)) {
       EHUGE_DEC(einfo, seg_id, reader->value_size);
+      reader->ref_avail = GRN_FALSE;
     } else {
       EINFO_DEC(einfo, seg_id, reader->body_seg_offset, reader->value_size);
+      reader->ref_avail = GRN_TRUE;
     }
     if (reader->body_seg_addr) {
       if (seg_id != reader->body_seg_id) {
@@ -1762,6 +1774,52 @@ grn_ja_reader_seek(grn_ctx *ctx, grn_ja_reader *reader, grn_id id)
   return grn_ja_reader_seek_raw(ctx, reader, id);
 }
 
+grn_rc grn_ja_reader_ref(grn_ctx *ctx, grn_ja_reader *reader, void **addr)
+{
+  if (!reader->ref_avail) {
+    return GRN_INVALID_ARGUMENT;
+  }
+  if (reader->body_seg_id != reader->ref_seg_id) {
+    void *seg_addr;
+    if (reader->nref_seg_ids == reader->ref_seg_ids_size) {
+      size_t n_bytes;
+      uint32_t new_size, *new_seg_ids;
+      if (reader->ref_seg_ids_size == 0) {
+        new_size = GRN_JA_READER_INITIAL_REF_SEG_IDS_SIZE;
+      } else {
+        new_size = reader->ref_seg_ids_size * 2;
+      }
+      n_bytes = sizeof(uint32_t) * new_size;
+      new_seg_ids = (uint32_t *)GRN_REALLOC(reader->ref_seg_ids, n_bytes);
+      if (!new_seg_ids) {
+        return GRN_NO_MEMORY_AVAILABLE;
+      }
+      reader->ref_seg_ids = new_seg_ids;
+      reader->ref_seg_ids_size = new_size;
+    }
+    GRN_IO_SEG_REF(reader->ja->io, reader->body_seg_id, seg_addr);
+    if (!seg_addr) {
+      return GRN_UNKNOWN_ERROR;
+    }
+    reader->ref_seg_id = reader->body_seg_id;
+    reader->ref_seg_addr = seg_addr;
+    reader->ref_seg_ids[reader->nref_seg_ids++] = reader->body_seg_id;
+  }
+  *addr = (char *)reader->ref_seg_addr + reader->body_seg_offset;
+  return GRN_SUCCESS;
+}
+
+grn_rc grn_ja_reader_unref(grn_ctx *ctx, grn_ja_reader *reader)
+{
+  uint32_t i;
+  for (i = 0; i < reader->nref_seg_ids; i++) {
+    GRN_IO_SEG_UNREF(reader->ja->io, reader->ref_seg_ids[i]);
+  }
+  reader->ref_seg_id = JA_ESEG_VOID;
+  reader->nref_seg_ids = 0;
+  return GRN_FUNCTION_NOT_IMPLEMENTED;
+}
+
 #ifdef GRN_WITH_ZLIB
 /* grn_ja_reader_read_zlib() reads a value compressed with zlib. */
 static grn_rc
-------------- next part --------------
HTML����������������������������...
Download 



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