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����������������������������... 下載