Kouhei Sutou
null+****@clear*****
Thu Nov 10 15:05:25 JST 2016
Kouhei Sutou 2016-11-10 15:05:25 +0900 (Thu, 10 Nov 2016) New Revision: e6a7dfd2053c4e8dec42952402f3ee595b92bedb https://github.com/groonga/groonga/commit/e6a7dfd2053c4e8dec42952402f3ee595b92bedb Message: Don't work :< We need more works: * Make cache entry link list persistent * Make cached value persistent Modified files: include/groonga/groonga.h lib/cache.c src/groonga.c Modified: include/groonga/groonga.h (+5 -0) =================================================================== --- include/groonga/groonga.h 2016-11-10 12:00:16 +0900 (57265f9) +++ include/groonga/groonga.h 2016-11-10 15:05:25 +0900 (5cda912) @@ -278,7 +278,12 @@ GRN_API grn_rc grn_set_lock_timeout(int timeout); #define GRN_CACHE_DEFAULT_MAX_N_ENTRIES 100 typedef struct _grn_cache grn_cache; +GRN_API void grn_set_default_cache_path(const char *path); +GRN_API const char *grn_get_default_cache_path(void); + GRN_API grn_cache *grn_cache_open(grn_ctx *ctx); +GRN_API grn_cache *grn_cache_open_persistent(grn_ctx *ctx, + const char *path); GRN_API grn_rc grn_cache_close(grn_ctx *ctx, grn_cache *cache); GRN_API grn_rc grn_cache_current_set(grn_ctx *ctx, grn_cache *cache); Modified: lib/cache.c (+147 -25) =================================================================== --- lib/cache.c 2016-11-10 12:00:16 +0900 (6e2e34a) +++ lib/cache.c 2016-11-10 15:05:25 +0900 (3d35952) @@ -22,6 +22,8 @@ #include "grn_hash.h" #include "grn_db.h" +#include <sys/stat.h> + typedef struct _grn_cache_entry grn_cache_entry; struct _grn_cache { @@ -29,6 +31,7 @@ struct _grn_cache { grn_cache_entry *prev; grn_ctx *ctx; grn_hash *hash; + grn_bool is_persistent; grn_mutex mutex; uint32_t max_nentries; uint32_t nfetches; @@ -38,7 +41,7 @@ struct _grn_cache { struct _grn_cache_entry { grn_cache_entry *next; grn_cache_entry *prev; - grn_obj *value; + grn_obj value; grn_timeval tv; grn_id id; uint32_t nref; @@ -47,9 +50,64 @@ struct _grn_cache_entry { static grn_ctx grn_cache_ctx; static grn_cache *grn_cache_current = NULL; static grn_cache *grn_cache_default = NULL; +static char *grn_cache_default_path = NULL; -grn_cache * -grn_cache_open(grn_ctx *ctx) +static grn_bool +grn_cache_open_hash(grn_ctx *ctx, grn_cache *cache, const char *path) +{ + if (path) { + struct stat stat_buffer; + + if (stat(path, &stat_buffer) == 0) { + cache->hash = grn_hash_open(cache->ctx, path); + if (!cache->hash) { + grn_rc rc = ctx->rc; + if (rc == GRN_SUCCESS) { + rc = GRN_NO_MEMORY_AVAILABLE; + } + ERR(rc, + "[cache] failed to open persistent hash table: <%s>%s%s", + path, + ctx->errbuf[0] == '\0' ? "" : ": ", + ctx->errbuf); + return GRN_FALSE; + } + } else { + cache->hash = grn_hash_create(cache->ctx, + path, + GRN_CACHE_MAX_KEY_SIZE, + sizeof(grn_cache_entry), + GRN_OBJ_KEY_VAR_SIZE); + if (!cache->hash) { + grn_rc rc = ctx->rc; + if (rc == GRN_SUCCESS) { + rc = GRN_NO_MEMORY_AVAILABLE; + } + ERR(rc, + "[cache] failed to create persistent hash table: <%s>%s%s", + path, + ctx->errbuf[0] == '\0' ? "" : ": ", + ctx->errbuf); + return GRN_FALSE; + } + } + cache->is_persistent = GRN_TRUE; + } else { + cache->hash = grn_hash_create(cache->ctx, NULL, GRN_CACHE_MAX_KEY_SIZE, + sizeof(grn_cache_entry), GRN_OBJ_KEY_VAR_SIZE); + if (!cache->hash) { + ERR(GRN_NO_MEMORY_AVAILABLE, + "[cache] failed to create in memory hash table"); + return GRN_FALSE; + } + cache->is_persistent = GRN_FALSE; + } + + return GRN_TRUE; +} + +static grn_cache * +grn_cache_open_raw(grn_ctx *ctx, const char *path) { grn_cache *cache = NULL; @@ -63,10 +121,7 @@ grn_cache_open(grn_ctx *ctx) cache->next = (grn_cache_entry *)cache; cache->prev = (grn_cache_entry *)cache; cache->ctx = ctx; - cache->hash = grn_hash_create(cache->ctx, NULL, GRN_CACHE_MAX_KEY_SIZE, - sizeof(grn_cache_entry), GRN_OBJ_KEY_VAR_SIZE); - if (!cache->hash) { - ERR(GRN_NO_MEMORY_AVAILABLE, "[cache] failed to create hash table"); + if (!grn_cache_open_hash(ctx, cache, path)) { GRN_FREE(cache); cache = NULL; goto exit; @@ -80,6 +135,18 @@ exit : GRN_API_RETURN(cache); } +grn_cache * +grn_cache_open(grn_ctx *ctx) +{ + return grn_cache_open_raw(ctx, NULL); +} + +grn_cache * +grn_cache_open_persistent(grn_ctx *ctx, const char *path) +{ + return grn_cache_open_raw(ctx, path); +} + grn_rc grn_cache_close(grn_ctx *ctx_not_used, grn_cache *cache) { @@ -88,9 +155,11 @@ grn_cache_close(grn_ctx *ctx_not_used, grn_cache *cache) GRN_API_ENTER; - GRN_HASH_EACH(ctx, cache->hash, id, NULL, NULL, &vp, { - grn_obj_close(ctx, vp->value); - }); + if (!cache->is_persistent) { + GRN_HASH_EACH(ctx, cache->hash, id, NULL, NULL, &vp, { + grn_obj_close(ctx, &(vp->value)); + }); + } grn_hash_close(ctx, cache->hash); MUTEX_FIN(cache->mutex); GRN_FREE(cache); @@ -112,13 +181,68 @@ grn_cache_current_get(grn_ctx *ctx) } void +grn_set_default_cache_path(const char *path) +{ + if (!grn_cache_default_path && !path) { + return; + } + + if (grn_cache_default_path && + path && + strcmp(grn_cache_default_path, path) == 0) { + return; + } + + free(grn_cache_default_path); + if (path) { + grn_cache_default_path = strdup(path); + } else { + grn_cache_default_path = NULL; + } + + if (grn_cache_default) { + grn_ctx *ctx = &grn_cache_ctx; + grn_cache *grn_cache_default_old; + grn_cache *grn_cache_default_new; + + if (grn_cache_default_path) { + grn_cache_default_new = grn_cache_open_persistent(ctx, + grn_cache_default_path); + } else { + grn_cache_default_new = grn_cache_open(ctx); + } + if (!grn_cache_default_new) { + return; + } + + if (grn_cache_default == grn_cache_current_get(ctx)) { + grn_cache_current_set(ctx, grn_cache_default_new); + } + grn_cache_default_old = grn_cache_default; + grn_cache_default = grn_cache_default_new; + grn_cache_close(ctx, grn_cache_default_old); + } +} + +const char * +grn_get_default_cache_path(void) +{ + return grn_cache_default_path; +} + +void grn_cache_init(void) { grn_ctx *ctx = &grn_cache_ctx; grn_ctx_init(ctx, 0); - grn_cache_default = grn_cache_open(ctx); + if (grn_cache_default_path) { + grn_cache_default = grn_cache_open_persistent(ctx, + grn_cache_default_path); + } else { + grn_cache_default = grn_cache_open(ctx); + } grn_cache_current_set(ctx, grn_cache_default); } @@ -167,7 +291,7 @@ grn_cache_expire_entry(grn_cache *cache, grn_cache_entry *ce) if (!ce->nref) { ce->prev->next = ce->next; ce->next->prev = ce->prev; - grn_obj_close(cache->ctx, ce->value); + grn_obj_close(cache->ctx, &(ce->value)); grn_hash_delete_by_id(cache->ctx, cache->hash, ce->id, NULL); } } @@ -187,7 +311,7 @@ grn_cache_fetch(grn_ctx *ctx, grn_cache *cache, goto exit; } ce->nref++; - obj = ce->value; + obj = &(ce->value); ce->prev->next = ce->next; ce->next->prev = ce->prev; { @@ -224,30 +348,27 @@ grn_cache_update(grn_ctx *ctx, grn_cache *cache, int added = 0; grn_cache_entry *ce; grn_rc rc = GRN_SUCCESS; - grn_obj *old = NULL; - grn_obj *obj = NULL; if (!ctx->impl || !cache->max_nentries) { return; } MUTEX_LOCK(cache->mutex); - obj = grn_obj_open(cache->ctx, GRN_BULK, 0, GRN_DB_TEXT); - if (!obj) { - goto exit; - } - GRN_TEXT_PUT(cache->ctx, obj, GRN_TEXT_VALUE(value), GRN_TEXT_LEN(value)); id = grn_hash_add(cache->ctx, cache->hash, str, str_len, (void **)&ce, &added); if (id) { - if (!added) { + if (added) { + GRN_TEXT_INIT(&(ce->value), 0); + } else { if (ce->nref) { rc = GRN_RESOURCE_BUSY; goto exit; } - old = ce->value; ce->prev->next = ce->next; ce->next->prev = ce->prev; } ce->id = id; - ce->value = obj; + GRN_TEXT_SET(cache->ctx, + &(ce->value), + GRN_TEXT_VALUE(value), + GRN_TEXT_LEN(value)); ce->tv = ctx->impl->tv; ce->nref = 0; { @@ -264,8 +385,6 @@ grn_cache_update(grn_ctx *ctx, grn_cache *cache, rc = GRN_NO_MEMORY_AVAILABLE; } exit : - if (rc) { grn_obj_close(cache->ctx, obj); } - if (old) { grn_obj_close(cache->ctx, old); } MUTEX_UNLOCK(cache->mutex); } @@ -290,5 +409,8 @@ grn_cache_fin(void) grn_cache_close(ctx, grn_cache_default); grn_cache_default = NULL; + free(grn_cache_default_path); + grn_cache_default_path = NULL; + grn_ctx_fin(ctx); } Modified: src/groonga.c (+10 -0) =================================================================== --- src/groonga.c 2016-11-10 12:00:16 +0900 (3bb90a9) +++ src/groonga.c 2016-11-10 15:05:25 +0900 (981bdde) @@ -3166,6 +3166,9 @@ show_usage(FILE *output) " --default-match-escalation-threshold <threshold>:\n" " specify default match escalation threshold" " (default: %" GRN_FMT_LLD ")\n" + " --cache-path <path>:\n" + " specify cache path for persistent cache\n" + " (none)\n" "\n" " --show-config: show config\n" " -h, --help: show usage\n" @@ -3210,6 +3213,7 @@ main(int argc, char **argv) const char *working_directory_arg = NULL; const char *config_path = NULL; const char *default_request_timeout_arg = NULL; + const char *cache_path = NULL; int exit_code = EXIT_SUCCESS; int i; int flags = 0; @@ -3251,6 +3255,7 @@ main(int argc, char **argv) FLAG_USE_WINDOWS_EVENT_LOG, GETOPT_OP_ON}, {'\0', "memcached-column", NULL, 0, GETOPT_OP_NONE}, {'\0', "default-request-timeout", NULL, 0, GETOPT_OP_NONE}, + {'\0', "cache-path", NULL, 0, GETOPT_OP_NONE}, {'\0', NULL, NULL, 0, 0} }; opts[0].arg = &port_arg; @@ -3276,6 +3281,7 @@ main(int argc, char **argv) opts[27].arg = &working_directory_arg; opts[29].arg = &memcached_column_name; opts[30].arg = &default_request_timeout_arg; + opts[31].arg = &cache_path; reset_ready_notify_pipe(); @@ -3634,6 +3640,10 @@ main(int argc, char **argv) default_request_timeout = default_default_request_timeout; } + if (cache_path) { + grn_set_default_cache_path(cache_path); + } + grn_gctx.errbuf[0] = '\0'; if (grn_init()) { fprintf(stderr, "failed to initialize Groonga: %s\n", grn_gctx.errbuf); -------------- next part -------------- HTML����������������������������...Download