Kouhei Sutou
null+****@clear*****
Fri Aug 7 15:36:34 JST 2015
Kouhei Sutou 2015-08-07 15:36:34 +0900 (Fri, 07 Aug 2015) New Revision: b799b62541663be2804ea4ddf738ef6f29326aa2 https://github.com/groonga/groonga/commit/b799b62541663be2804ea4ddf738ef6f29326aa2 Message: Add grn_db_reopen() It just close and open internally. This is a thread unsafe operation. You should not touch the database from other thread while grn_db_reopen() is running. Modified files: include/groonga/groonga.h lib/db.c Modified: include/groonga/groonga.h (+1 -0) =================================================================== --- include/groonga/groonga.h 2015-08-07 15:31:59 +0900 (ebae344) +++ include/groonga/groonga.h 2015-08-07 15:36:34 +0900 (9a6df1f) @@ -434,6 +434,7 @@ GRN_API grn_obj *grn_db_create(grn_ctx *ctx, const char *path, grn_db_create_opt GRN_API grn_obj *grn_db_open(grn_ctx *ctx, const char *path); GRN_API void grn_db_touch(grn_ctx *ctx, grn_obj *db); GRN_API grn_rc grn_db_recover(grn_ctx *ctx, grn_obj *db); +GRN_API grn_rc grn_db_reopen(grn_ctx *ctx, grn_obj *db); GRN_API grn_rc grn_ctx_use(grn_ctx *ctx, grn_obj *db); GRN_API grn_obj *grn_ctx_db(grn_ctx *ctx); Modified: lib/db.c (+133 -53) =================================================================== --- lib/db.c 2015-08-07 15:31:59 +0900 (b1f9867) +++ lib/db.c 2015-08-07 15:36:34 +0900 (61e69f9) @@ -247,65 +247,92 @@ grn_db_create(grn_ctx *ctx, const char *path, grn_db_create_optarg *optarg) GRN_API_RETURN(NULL); } -grn_obj * -grn_db_open(grn_ctx *ctx, const char *path) +static grn_rc +grn_db_init(grn_ctx *ctx, grn_obj *db, const char *path) { - grn_db *s; + grn_db *s = (grn_db *)db; + uint32_t type; + GRN_API_ENTER; - if (path && strlen(path) <= PATH_MAX - 14) { - if ((s = GRN_MALLOC(sizeof(grn_db)))) { - uint32_t type = grn_io_detect_type(ctx, path); - grn_tiny_array_init(ctx, &s->values, sizeof(db_value), - GRN_TINY_ARRAY_CLEAR| - GRN_TINY_ARRAY_THREADSAFE| - GRN_TINY_ARRAY_USE_MALLOC); + + type = grn_io_detect_type(ctx, path); + grn_tiny_array_init(ctx, &s->values, sizeof(db_value), + GRN_TINY_ARRAY_CLEAR| + GRN_TINY_ARRAY_THREADSAFE| + GRN_TINY_ARRAY_USE_MALLOC); + switch (type) { + case GRN_TABLE_PAT_KEY : + s->keys = (grn_obj *)grn_pat_open(ctx, path); + break; + case GRN_TABLE_DAT_KEY : + s->keys = (grn_obj *)grn_dat_open(ctx, path); + break; + default : + s->keys = NULL; + if (ctx->rc == GRN_SUCCESS) { + ERR(GRN_INVALID_ARGUMENT, + "[db][init] invalid keys table's type: %#x", type); + } + break; + } + + if (!s->keys) { + grn_tiny_array_fin(&s->values); + GRN_API_RETURN(ctx->rc); + } + + { + char specs_path[PATH_MAX]; + + gen_pathname(path, specs_path, 0); + s->specs = grn_ja_open(ctx, specs_path); + + if (!s->specs) { + grn_tiny_array_fin(&s->values); switch (type) { case GRN_TABLE_PAT_KEY : - s->keys = (grn_obj *)grn_pat_open(ctx, path); + grn_pat_close(ctx, (grn_pat *)s->keys); break; case GRN_TABLE_DAT_KEY : - s->keys = (grn_obj *)grn_dat_open(ctx, path); - break; - default : - s->keys = NULL; - if (ctx->rc == GRN_SUCCESS) { - ERR(GRN_INVALID_ARGUMENT, - "[db][open] invalid keys table's type: %#x", type); - } + grn_dat_close(ctx, (grn_dat *)s->keys); break; } - if (s->keys) { - char specs_path[PATH_MAX]; - gen_pathname(path, specs_path, 0); - if ((s->specs = grn_ja_open(ctx, specs_path))) { - CRITICAL_SECTION_INIT(s->lock); - GRN_DB_OBJ_SET_TYPE(s, GRN_DB); - s->obj.db = (grn_obj *)s; - s->obj.header.domain = GRN_ID_NIL; - DB_OBJ(&s->obj)->range = GRN_ID_NIL; - grn_ctx_use(ctx, (grn_obj *)s); + GRN_API_RETURN(ctx->rc); + } + + CRITICAL_SECTION_INIT(s->lock); + GRN_DB_OBJ_SET_TYPE(s, GRN_DB); + s->obj.db = (grn_obj *)s; + s->obj.header.domain = GRN_ID_NIL; + DB_OBJ(&s->obj)->range = GRN_ID_NIL; + grn_ctx_use(ctx, (grn_obj *)s); #ifdef GRN_WITH_MECAB - if (grn_db_init_mecab_tokenizer(ctx)) { - ERRCLR(ctx); - } + if (grn_db_init_mecab_tokenizer(ctx)) { + ERRCLR(ctx); + } #endif - grn_db_init_builtin_tokenizers(ctx); - grn_db_init_builtin_normalizers(ctx); - grn_db_init_builtin_scorers(ctx); - grn_db_init_builtin_query(ctx); - GRN_API_RETURN((grn_obj *)s); - } - switch (type) { - case GRN_TABLE_PAT_KEY : - grn_pat_close(ctx, (grn_pat *)s->keys); - break; - case GRN_TABLE_DAT_KEY : - grn_dat_close(ctx, (grn_dat *)s->keys); - break; - } + grn_db_init_builtin_tokenizers(ctx); + grn_db_init_builtin_normalizers(ctx); + grn_db_init_builtin_scorers(ctx); + grn_db_init_builtin_query(ctx); + } + + GRN_API_RETURN(ctx->rc); +} + + +grn_obj * +grn_db_open(grn_ctx *ctx, const char *path) +{ + grn_obj *db; + GRN_API_ENTER; + if (path && strlen(path) <= PATH_MAX - 14) { + if ((db = GRN_MALLOC(sizeof(grn_db)))) { + if (grn_db_init(ctx, db, path) == GRN_SUCCESS) { + GRN_API_RETURN(db); + } else { + GRN_FREE(db); } - grn_tiny_array_fin(&s->values); - GRN_FREE(s); } else { ERR(GRN_NO_MEMORY_AVAILABLE, "grn_db alloc failed"); } @@ -331,15 +358,18 @@ grn_db_curr_id(grn_ctx *ctx, grn_obj *db) return curr_id; } -/* s must be validated by caller */ -grn_rc -grn_db_close(grn_ctx *ctx, grn_obj *db) +static grn_rc +grn_db_fin(grn_ctx *ctx, grn_obj *db) { grn_id id; db_value *vp; grn_db *s = (grn_db *)db; grn_bool ctx_used_db; - if (!s) { return GRN_INVALID_ARGUMENT; } + + if (!s->keys) { + return GRN_SUCCESS; + } + GRN_API_ENTER; ctx_used_db = ctx->impl && ctx->impl->db == db; @@ -383,7 +413,6 @@ grn_db_close(grn_ctx *ctx, grn_obj *db) } CRITICAL_SECTION_FIN(s->lock); if (s->specs) { grn_ja_close(ctx, s->specs); } - GRN_FREE(s); if (ctx_used_db) { grn_cache *cache; @@ -394,9 +423,60 @@ grn_db_close(grn_ctx *ctx, grn_obj *db) ctx->impl->db = NULL; } + s->keys = NULL; + GRN_API_RETURN(GRN_SUCCESS); } +/* s must be validated by caller */ +grn_rc +grn_db_close(grn_ctx *ctx, grn_obj *db) +{ + grn_rc rc; + + if (!db) { return GRN_INVALID_ARGUMENT; } + + GRN_API_ENTER; + rc = grn_db_fin(ctx, db); + GRN_FREE(db); + + GRN_API_RETURN(rc); +} + +grn_rc +grn_db_reopen(grn_ctx *ctx, grn_obj *db) +{ + grn_rc rc; + const char *path; + char copied_path[PATH_MAX]; + + if (!db) { + return GRN_INVALID_ARGUMENT; + } + + GRN_API_ENTER; + + path = grn_obj_path(ctx, db); + if (!path) { + GRN_API_RETURN(GRN_SUCCESS); + } + + grn_strcpy(copied_path, PATH_MAX, path); + + rc = grn_db_fin(ctx, db); + if (rc != GRN_SUCCESS) { + GRN_FREE(db); + GRN_API_RETURN(rc); + } + + rc = grn_db_init(ctx, db, copied_path); + if (rc != GRN_SUCCESS) { + GRN_FREE(db); + } + + GRN_API_RETURN(rc); +} + grn_obj * grn_ctx_get(grn_ctx *ctx, const char *name, int name_size) { -------------- next part -------------- HTML����������������������������...Download