[Groonga-commit] groonga/groonga at 820afdc [master] Clear dirty mark when io_flush is executed

Zurück zum Archiv-Index

Kouhei Sutou null+****@clear*****
Wed May 11 16:21:00 JST 2016


Kouhei Sutou	2016-05-11 16:21:00 +0900 (Wed, 11 May 2016)

  New Revision: 820afdcb5f2e66be4f295f9967f20d547bfa3dd5
  https://github.com/groonga/groonga/commit/820afdcb5f2e66be4f295f9967f20d547bfa3dd5

  Message:
    Clear dirty mark when io_flush is executed

  Modified files:
    lib/dat.cpp
    lib/db.c
    lib/grn_dat.h
    lib/grn_pat.h
    lib/pat.c
    test/command_line/suite/grndb/test_check.rb

  Modified: lib/dat.cpp (+21 -0)
===================================================================
--- lib/dat.cpp    2016-05-11 15:23:46 +0900 (1c9ba5b)
+++ lib/dat.cpp    2016-05-11 16:21:00 +0900 (ac3489e)
@@ -1180,4 +1180,25 @@ grn_dat_is_dirty(grn_ctx *ctx, grn_dat *dat)
   return dat->header->n_dirty_opens > 0;
 }
 
+grn_rc
+grn_dat_clean(grn_ctx *ctx, grn_dat *dat)
+{
+  if (!dat->io) {
+  }
+
+  grn_rc rc = GRN_SUCCESS;
+
+  {
+    CriticalSection critical_section(&dat->lock);
+    if (dat->is_dirty) {
+      uint32_t n_dirty_opens;
+      dat->is_dirty = GRN_FALSE;
+      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 (+51 -11)
===================================================================
--- lib/db.c    2016-05-11 15:23:46 +0900 (5f4d4c5)
+++ lib/db.c    2016-05-11 16:21:00 +0900 (4623f99)
@@ -677,6 +677,46 @@ grn_db_is_dirty(grn_ctx *ctx, grn_obj *db)
   }
 }
 
+static grn_rc
+grn_db_dirty(grn_ctx *ctx, grn_obj *db)
+{
+  grn_obj *keys;
+
+  if (!db) {
+    return GRN_SUCCESS;
+  }
+
+  keys = ((grn_db *)db)->keys;
+  switch (keys->header.type) {
+  case GRN_TABLE_PAT_KEY :
+    return grn_pat_dirty(ctx, (grn_pat *)keys);
+  case GRN_TABLE_DAT_KEY :
+    return grn_dat_dirty(ctx, (grn_dat *)keys);
+  default :
+    return GRN_SUCCESS;
+  }
+}
+
+static grn_rc
+grn_db_clean(grn_ctx *ctx, grn_obj *db)
+{
+  grn_obj *keys;
+
+  if (!db) {
+    return GRN_SUCCESS;
+  }
+
+  keys = ((grn_db *)db)->keys;
+  switch (keys->header.type) {
+  case GRN_TABLE_PAT_KEY :
+    return grn_pat_clean(ctx, (grn_pat *)keys);
+  case GRN_TABLE_DAT_KEY :
+    return grn_dat_clean(ctx, (grn_dat *)keys);
+  default :
+    return GRN_SUCCESS;
+  }
+}
+
 void
 grn_db_touch(grn_ctx *ctx, grn_obj *s)
 {
@@ -688,18 +728,8 @@ 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->last_modified = 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;
-  }
+  grn_db_dirty(ctx, obj);
 }
 
 void
@@ -10757,7 +10787,9 @@ grn_rc
 grn_obj_flush(grn_ctx *ctx, grn_obj *obj)
 {
   grn_rc rc = GRN_SUCCESS;
+
   GRN_API_ENTER;
+
   switch (obj->header.type) {
   case GRN_DB :
     {
@@ -10781,6 +10813,14 @@ grn_obj_flush(grn_ctx *ctx, grn_obj *obj)
     rc = grn_io_flush(ctx, grn_obj_io(obj));
     break;
   }
+
+  if (rc == GRN_SUCCESS &&
+      GRN_DB_OBJP(obj) &&
+      DB_OBJ(obj)->id != GRN_ID_NIL &&
+      !IS_TEMP(obj)) {
+    rc = grn_db_clean(ctx, DB_OBJ(obj)->db);
+  }
+
   GRN_API_RETURN(rc);
 }
 

  Modified: lib/grn_dat.h (+1 -0)
===================================================================
--- lib/grn_dat.h    2016-05-11 15:23:46 +0900 (00720fb)
+++ lib/grn_dat.h    2016-05-11 16:21:00 +0900 (337c251)
@@ -83,6 +83,7 @@ GRN_API grn_rc grn_dat_flush(grn_ctx *ctx, grn_dat *dat);
 
 grn_rc grn_dat_dirty(grn_ctx *ctx, grn_dat *dat);
 grn_bool grn_dat_is_dirty(grn_ctx *ctx, grn_dat *dat);
+grn_rc grn_dat_clean(grn_ctx *ctx, grn_dat *dat);
 
 #ifdef __cplusplus
 }

  Modified: lib/grn_pat.h (+1 -0)
===================================================================
--- lib/grn_pat.h    2016-05-11 15:23:46 +0900 (35e8ac0)
+++ lib/grn_pat.h    2016-05-11 16:21:00 +0900 (46ee2c9)
@@ -121,6 +121,7 @@ grn_bool grn_pat_is_key_encoded(grn_ctx *ctx, grn_pat *pat);
 
 grn_rc grn_pat_dirty(grn_ctx *ctx, grn_pat *pat);
 grn_bool grn_pat_is_dirty(grn_ctx *ctx, grn_pat *pat);
+grn_rc grn_pat_clean(grn_ctx *ctx, grn_pat *pat);
 
 #ifdef __cplusplus
 }

  Modified: lib/pat.c (+17 -0)
===================================================================
--- lib/pat.c    2016-05-11 15:23:46 +0900 (f019bec)
+++ lib/pat.c    2016-05-11 16:21:00 +0900 (8d1c105)
@@ -3580,3 +3580,20 @@ grn_pat_is_dirty(grn_ctx *ctx, grn_pat *pat)
 {
   return pat->header->n_dirty_opens > 0;
 }
+
+grn_rc
+grn_pat_clean(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_FALSE;
+    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;
+}

  Modified: test/command_line/suite/grndb/test_check.rb (+28 -0)
===================================================================
--- test/command_line/suite/grndb/test_check.rb    2016-05-11 15:23:46 +0900 (2a2445d)
+++ test/command_line/suite/grndb/test_check.rb    2016-05-11 16:21:00 +0900 (b2718fd)
@@ -40,6 +40,34 @@ Database wasn't closed successfully. It may be broken. Re-create the database.
     MESSAGE
   end
 
+  def test_cleaned_database
+    groonga("table_create", "Users", "TABLE_HASH_KEY", "ShortText")
+    IO.pipe do |to_groonga_read, to_groonga_write|
+      IO.pipe do |from_groonga_read, from_groonga_write|
+        pid = spawn("groonga", @database_path.to_s,
+                    :in => to_groonga_read,
+                    :out => from_groonga_write)
+        to_groonga_read.close
+        from_groonga_write.close
+        to_groonga_write.puts(<<-COMMAND)
+load --table Users
+[
+{"_key": "Alice"}
+]
+        COMMAND
+        to_groonga_write.flush
+        from_groonga_read.gets
+        to_groonga_write.puts("io_flush Users")
+        to_groonga_write.flush
+        from_groonga_read.gets
+        Process.kill(:KILL, pid)
+      end
+    end
+    result = grndb("check")
+    assert_equal(["", ""],
+                 [result.output, result.error_output])
+  end
+
   def test_nonexistent_table
     groonga("table_create", "Users", "TABLE_HASH_KEY", "ShortText")
     _id, _name, path, *_ = JSON.parse(groonga("table_list").output)[1][1]
-------------- next part --------------
HTML����������������������������...
Download 



More information about the Groonga-commit mailing list
Zurück zum Archiv-Index