[Groonga-commit] groonga/groonga at 7d44c23 [master] Support detecting changed database isn't closed

Back to archive index

Kouhei Sutou null+****@clear*****
Tue May 10 15:54:32 JST 2016


Kouhei Sutou	2016-05-10 15:54:32 +0900 (Tue, 10 May 2016)

  New Revision: 7d44c232ce421b00b4c51bbeea03356af48f10ee
  https://github.com/groonga/groonga/commit/7d44c232ce421b00b4c51bbeea03356af48f10ee

  Merged e8958bc: Merge pull request #543 from groonga/support-dirty-crash-detection

  Message:
    Support detecting changed database isn't closed
    
    It doesn't increase no overhead when the database isn't changed. For
    example, you have no overhead and no change when you only use select
    command.
    
    It doesn't flush many times. It flushes only at the first database
    change.

  Modified files:
    lib/dat.cpp
    lib/db.c
    lib/grn_dat.h
    lib/grn_pat.h
    lib/pat.c

  Modified: lib/dat.cpp (+27 -0)
===================================================================
--- lib/dat.cpp    2016-05-10 15:40:40 +0900 (51a84da)
+++ lib/dat.cpp    2016-05-10 15:54:32 +0900 (15001cf)
@@ -115,6 +115,7 @@ grn_dat_init(grn_ctx *, grn_dat *dat)
   dat->normalizer = NULL;
   GRN_PTR_INIT(&(dat->token_filters), GRN_OBJ_VECTOR, GRN_ID_NIL);
   CRITICAL_SECTION_INIT(dat->lock);
+  dat->is_dirty = GRN_FALSE;
 }
 
 void
@@ -126,6 +127,10 @@ grn_dat_fin(grn_ctx *ctx, grn_dat *dat)
   dat->old_trie = NULL;
   dat->trie = NULL;
   if (dat->io) {
+    if (dat->is_dirty) {
+      uint32_t n_dirty_opens;
+      GRN_ATOMIC_ADD_EX(&(dat->header->n_dirty_opens), -1, n_dirty_opens);
+    }
     grn_io_close(ctx, dat->io);
     dat->io = NULL;
   }
@@ -1142,4 +1147,26 @@ grn_dat_flush(grn_ctx *ctx, grn_dat *dat)
   return GRN_SUCCESS;
 }
 
+grn_rc
+grn_dat_dirty(grn_ctx *ctx, grn_dat *dat)
+{
+  if (!dat->io) {
+    return GRN_SUCCESS;
+  }
+
+  grn_rc rc = GRN_SUCCESS;
+
+  {
+    CriticalSection critical_section(&dat->lock);
+    if (!dat->is_dirty) {
+      uint32_t n_dirty_opens;
+      dat->is_dirty = GRN_TRUE;
+      GRN_ATOMIC_ADD_EX(&(dat->header->n_dirty_opens), 1, n_dirty_opens);
+      rc = grn_io_flush(ctx, dat->io);
+    }
+  }
+
+  return rc;
+}
+
 }  // extern "C"

  Modified: lib/db.c (+11 -0)
===================================================================
--- lib/db.c    2016-05-10 15:40:40 +0900 (0558bb2)
+++ lib/db.c    2016-05-10 15:54:32 +0900 (c849a22)
@@ -664,7 +664,18 @@ grn_db_touch(grn_ctx *ctx, grn_obj *s)
 static inline void
 grn_obj_touch_db(grn_ctx *ctx, grn_obj *obj, grn_timeval *tv)
 {
+  grn_db *db = (grn_db *)obj;
+
   grn_obj_io(obj)->header->lastmod = tv->tv_sec;
+
+  switch (db->keys->header.type) {
+  case GRN_TABLE_PAT_KEY :
+    grn_pat_dirty(ctx, (grn_pat *)(db->keys));
+    break;
+  case GRN_TABLE_DAT_KEY :
+    grn_dat_dirty(ctx, (grn_dat *)(db->keys));
+    break;
+  }
 }
 
 void

  Modified: lib/grn_dat.h (+5 -1)
===================================================================
--- lib/grn_dat.h    2016-05-10 15:40:40 +0900 (2d4ac2a)
+++ lib/grn_dat.h    2016-05-10 15:54:32 +0900 (f68d760)
@@ -37,6 +37,7 @@ struct _grn_dat {
   grn_obj *normalizer;
   grn_obj token_filters;
   grn_critical_section lock;
+  grn_bool is_dirty;
 };
 
 struct grn_dat_header {
@@ -45,7 +46,8 @@ struct grn_dat_header {
   grn_id tokenizer;
   uint32_t file_id;
   grn_id normalizer;
-  uint32_t reserved[235];
+  uint32_t n_dirty_opens;
+  uint32_t reserved[234];
 };
 
 struct _grn_dat_cursor {
@@ -79,6 +81,8 @@ GRN_API grn_rc grn_dat_repair(grn_ctx *ctx, grn_dat *dat);
 
 GRN_API grn_rc grn_dat_flush(grn_ctx *ctx, grn_dat *dat);
 
+grn_rc grn_dat_dirty(grn_ctx *ctx, grn_dat *dat);
+
 #ifdef __cplusplus
 }
 #endif

  Modified: lib/grn_pat.h (+6 -1)
===================================================================
--- lib/grn_pat.h    2016-05-10 15:40:40 +0900 (10aa0f1)
+++ lib/grn_pat.h    2016-05-10 15:54:32 +0900 (aa66d52)
@@ -41,6 +41,8 @@ struct _grn_pat {
   grn_obj token_filters;
   grn_id *cache;
   uint32_t cache_size;
+  grn_bool is_dirty;
+  grn_critical_section lock;
 };
 
 #define GRN_PAT_NDELINFOS 0x100
@@ -68,7 +70,8 @@ struct grn_pat_header {
   uint32_t n_garbages;
   grn_id normalizer;
   uint32_t truncated;
-  uint32_t reserved[1003];
+  uint32_t n_dirty_opens;
+  uint32_t reserved[1002];
   grn_pat_delinfo delinfos[GRN_PAT_NDELINFOS];
   grn_id garbages[GRN_PAT_MAX_KEY_SIZE + 1];
 };
@@ -116,6 +119,8 @@ uint32_t grn_pat_total_key_size(grn_ctx *ctx, grn_pat *pat);
 
 grn_bool grn_pat_is_key_encoded(grn_ctx *ctx, grn_pat *pat);
 
+grn_rc grn_pat_dirty(grn_ctx *ctx, grn_pat *pat);
+
 #ifdef __cplusplus
 }
 #endif

  Modified: lib/pat.c (+30 -0)
===================================================================
--- lib/pat.c    2016-05-10 15:40:40 +0900 (9fbdac8)
+++ lib/pat.c    2016-05-10 15:54:32 +0900 (9db177c)
@@ -541,6 +541,8 @@ grn_pat_create(grn_ctx *ctx, const char *path, uint32_t key_size,
   }
   pat->cache = NULL;
   pat->cache_size = 0;
+  pat->is_dirty = GRN_FALSE;
+  CRITICAL_SECTION_INIT(pat->lock);
   return pat;
 }
 
@@ -623,6 +625,8 @@ grn_pat_open(grn_ctx *ctx, const char *path)
   }
   pat->cache = NULL;
   pat->cache_size = 0;
+  pat->is_dirty = GRN_FALSE;
+  CRITICAL_SECTION_INIT(pat->lock);
   return pat;
 }
 
@@ -649,6 +653,14 @@ grn_rc
 grn_pat_close(grn_ctx *ctx, grn_pat *pat)
 {
   grn_rc rc;
+
+  CRITICAL_SECTION_FIN(pat->lock);
+
+  if (pat->is_dirty) {
+    uint32_t n_dirty_opens;
+    GRN_ATOMIC_ADD_EX(&(pat->header->n_dirty_opens), -1, n_dirty_opens);
+  }
+
   if ((rc = grn_io_close(ctx, pat->io))) {
     ERR(rc, "grn_io_close failed");
   } else {
@@ -656,6 +668,7 @@ grn_pat_close(grn_ctx *ctx, grn_pat *pat)
     if (pat->cache) { grn_pat_cache_disable(ctx, pat); }
     GRN_FREE(pat);
   }
+
   return rc;
 }
 
@@ -3544,3 +3557,20 @@ grn_pat_is_key_encoded(grn_ctx *ctx, grn_pat *pat)
 
   return KEY_NEEDS_CONVERT(pat, key_size);
 }
+
+grn_rc
+grn_pat_dirty(grn_ctx *ctx, grn_pat *pat)
+{
+  grn_rc rc = GRN_SUCCESS;
+
+  CRITICAL_SECTION_ENTER(pat->lock);
+  if (!pat->is_dirty) {
+    uint32_t n_dirty_opens;
+    pat->is_dirty = GRN_TRUE;
+    GRN_ATOMIC_ADD_EX(&(pat->header->n_dirty_opens), 1, n_dirty_opens);
+    rc = grn_io_flush(ctx, pat->io);
+  }
+  CRITICAL_SECTION_LEAVE(pat->lock);
+
+  return rc;
+}
-------------- next part --------------
HTML����������������������������...
Télécharger 



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