[Groonga-commit] groonga/groonga at e6a7dfd [persistent-cache] Don't work :<

Back to archive index

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 



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