[Groonga-commit] groonga/groonga at 0296d2f [master] cache: introduce cache backend changeable mechanism

Back to archive index

Kouhei Sutou null+****@clear*****
Thu Mar 30 17:27:35 JST 2017


Kouhei Sutou	2017-03-30 17:27:35 +0900 (Thu, 30 Mar 2017)

  New Revision: 0296d2f26804c89bc23dc6939f24347830c849b8
  https://github.com/groonga/groonga/commit/0296d2f26804c89bc23dc6939f24347830c849b8

  Message:
    cache: introduce cache backend changeable mechanism
    
    Persistent cache isn't implemented yet.

  Modified files:
    lib/cache.c

  Modified: lib/cache.c (+168 -47)
===================================================================
--- lib/cache.c    2017-03-30 16:51:25 +0900 (b8b852d)
+++ lib/cache.c    2017-03-30 17:27:35 +0900 (6db8798)
@@ -20,16 +20,28 @@
 #include "grn_ctx.h"
 #include "grn_ctx_impl.h"
 #include "grn_hash.h"
+#include "grn_pat.h"
+#include "grn_store.h"
 #include "grn_db.h"
 
 typedef struct _grn_cache_entry grn_cache_entry;
 
 struct _grn_cache {
-  grn_cache_entry *next;
-  grn_cache_entry *prev;
+  union {
+    struct {
+      grn_cache_entry *next;
+      grn_cache_entry *prev;
+      grn_hash *hash;
+      grn_mutex mutex;
+    } memory;
+    struct {
+      grn_hash *keys;
+      grn_ja *data;
+      grn_pat *timestamps;
+    } persistent;
+  } impl;
+  grn_bool is_memory;
   grn_ctx *ctx;
-  grn_hash *hash;
-  grn_mutex mutex;
   uint32_t max_nentries;
   uint32_t nfetches;
   uint32_t nhits;
@@ -47,6 +59,28 @@ static grn_ctx grn_cache_ctx;
 static grn_cache *grn_cache_current = NULL;
 static grn_cache *grn_cache_default = NULL;
 
+inline static void
+grn_cache_open_memory(grn_ctx *ctx, grn_cache *cache)
+{
+  cache->impl.memory.next = (grn_cache_entry *)cache;
+  cache->impl.memory.prev = (grn_cache_entry *)cache;
+  cache->impl.memory.hash = grn_hash_create(cache->ctx,
+                                            NULL,
+                                            GRN_CACHE_MAX_KEY_SIZE,
+                                            sizeof(grn_cache_entry),
+                                            GRN_OBJ_KEY_VAR_SIZE);
+  if (!cache->impl.memory.hash) {
+    ERR(GRN_NO_MEMORY_AVAILABLE, "[cache] failed to create hash table");
+    return;
+  }
+  MUTEX_INIT(cache->impl.memory.mutex);
+}
+
+inline static void
+grn_cache_open_persistent(grn_ctx *ctx, grn_cache *cache)
+{
+}
+
 grn_cache *
 grn_cache_open(grn_ctx *ctx)
 {
@@ -59,18 +93,28 @@ grn_cache_open(grn_ctx *ctx)
     goto exit;
   }
 
-  cache->next = (grn_cache_entry *)cache;
-  cache->prev = (grn_cache_entry *)cache;
+  {
+    char grn_cache_type_env[GRN_ENV_BUFFER_SIZE];
+    grn_getenv("GRN_CACHE_TYPE", grn_cache_type_env, GRN_ENV_BUFFER_SIZE);
+    if (strcmp(grn_cache_type_env, "persistent") == 0) {
+      cache->is_memory = GRN_FALSE;
+    } else {
+      cache->is_memory = GRN_TRUE;
+    }
+  }
+
   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 (cache->is_memory) {
+    grn_cache_open_memory(ctx, cache);
+  } else {
+    grn_cache_open_persistent(ctx, cache);
+  }
+  if (ctx->rc != GRN_SUCCESS) {
     GRN_FREE(cache);
     cache = NULL;
     goto exit;
   }
-  MUTEX_INIT(cache->mutex);
+
   cache->max_nentries = GRN_CACHE_DEFAULT_MAX_N_ENTRIES;
   cache->nfetches = 0;
   cache->nhits = 0;
@@ -79,19 +123,35 @@ exit :
   GRN_API_RETURN(cache);
 }
 
+inline static void
+grn_cache_close_memory(grn_ctx *ctx, grn_cache *cache)
+{
+  grn_cache_entry *vp;
+
+  GRN_HASH_EACH(ctx, cache->impl.memory.hash, id, NULL, NULL, &vp, {
+    grn_obj_close(ctx, vp->value);
+  });
+  grn_hash_close(ctx, cache->impl.memory.hash);
+  MUTEX_FIN(cache->impl.memory.mutex);
+}
+
+inline static void
+grn_cache_close_persistent(grn_ctx *tx, grn_cache *cache)
+{
+}
+
 grn_rc
 grn_cache_close(grn_ctx *ctx_not_used, grn_cache *cache)
 {
   grn_ctx *ctx = cache->ctx;
-  grn_cache_entry *vp;
 
   GRN_API_ENTER;
 
-  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);
+  if (cache->is_memory) {
+    grn_cache_close_memory(ctx, cache);
+  } else {
+    grn_cache_close_persistent(ctx, cache);
+  }
   GRN_FREE(cache);
 
   GRN_API_RETURN(ctx->rc);
@@ -152,37 +212,38 @@ void
 grn_cache_get_statistics(grn_ctx *ctx, grn_cache *cache,
                          grn_cache_statistics *statistics)
 {
-  MUTEX_LOCK(cache->mutex);
-  statistics->nentries = GRN_HASH_SIZE(cache->hash);
+  MUTEX_LOCK(cache->impl.memory.mutex);
+  statistics->nentries = GRN_HASH_SIZE(cache->impl.memory.hash);
   statistics->max_nentries = cache->max_nentries;
   statistics->nfetches = cache->nfetches;
   statistics->nhits = cache->nhits;
-  MUTEX_UNLOCK(cache->mutex);
+  MUTEX_UNLOCK(cache->impl.memory.mutex);
 }
 
 static void
-grn_cache_expire_entry(grn_cache *cache, grn_cache_entry *ce)
+grn_cache_expire_entry_memory(grn_cache *cache, grn_cache_entry *ce)
 {
   ce->prev->next = ce->next;
   ce->next->prev = ce->prev;
   grn_obj_close(cache->ctx, ce->value);
-  grn_hash_delete_by_id(cache->ctx, cache->hash, ce->id, NULL);
+  grn_hash_delete_by_id(cache->ctx, cache->impl.memory.hash, ce->id, NULL);
 }
 
-grn_rc
-grn_cache_fetch(grn_ctx *ctx, grn_cache *cache,
-                const char *key, uint32_t key_len,
-                grn_obj *output)
+inline static grn_rc
+grn_cache_fetch_memory(grn_ctx *ctx, grn_cache *cache,
+                       const char *key, uint32_t key_len,
+                       grn_obj *output)
 {
   /* TODO: How about GRN_NOT_FOUND? */
   grn_rc rc = GRN_INVALID_ARGUMENT;
   grn_cache_entry *ce;
-  if (!ctx->impl || !ctx->impl->db) { return GRN_INVALID_ARGUMENT; }
-  MUTEX_LOCK(cache->mutex);
+
+  MUTEX_LOCK(cache->impl.memory.mutex);
   cache->nfetches++;
-  if (grn_hash_get(cache->ctx, cache->hash, key, key_len, (void **)&ce)) {
+  if (grn_hash_get(cache->ctx, cache->impl.memory.hash, key, key_len,
+                   (void **)&ce)) {
     if (ce->tv.tv_sec <= grn_db_get_last_modified(ctx, ctx->impl->db)) {
-      grn_cache_expire_entry(cache, ce);
+      grn_cache_expire_entry_memory(cache, ce);
       goto exit;
     }
     rc = GRN_SUCCESS;
@@ -193,7 +254,7 @@ grn_cache_fetch(grn_ctx *ctx, grn_cache *cache,
     ce->prev->next = ce->next;
     ce->next->prev = ce->prev;
     {
-      grn_cache_entry *ce0 = (grn_cache_entry *)cache;
+      grn_cache_entry *ce0 = (grn_cache_entry *)(&(cache->impl.memory));
       ce->next = ce0->next;
       ce->prev = ce0;
       ce0->next->prev = ce;
@@ -202,13 +263,38 @@ grn_cache_fetch(grn_ctx *ctx, grn_cache *cache,
     cache->nhits++;
   }
 exit :
-  MUTEX_UNLOCK(cache->mutex);
+  MUTEX_UNLOCK(cache->impl.memory.mutex);
   return rc;
 }
 
-void
-grn_cache_update(grn_ctx *ctx, grn_cache *cache,
-                 const char *key, uint32_t key_len, grn_obj *value)
+inline static grn_rc
+grn_cache_fetch_persistent(grn_ctx *ctx, grn_cache *cache,
+                           const char *key, uint32_t key_len,
+                           grn_obj *output)
+{
+  /* TODO: How about GRN_NOT_FOUND? */
+  grn_rc rc = GRN_INVALID_ARGUMENT;
+  return rc;
+}
+
+grn_rc
+grn_cache_fetch(grn_ctx *ctx, grn_cache *cache,
+                const char *key, uint32_t key_len,
+                grn_obj *output)
+{
+  if (!ctx->impl || !ctx->impl->db) { return GRN_INVALID_ARGUMENT; }
+
+  if (cache->is_memory) {
+    return grn_cache_fetch_memory(ctx, cache, key, key_len, output);
+  } else {
+    return grn_cache_fetch_persistent(ctx, cache, key, key_len, output);
+  }
+}
+
+inline static void
+grn_cache_update_memory(grn_ctx *ctx, grn_cache *cache,
+                        const char *key, uint32_t key_len,
+                        grn_obj *value)
 {
   grn_id id;
   int added = 0;
@@ -217,15 +303,15 @@ grn_cache_update(grn_ctx *ctx, grn_cache *cache,
   grn_obj *old = NULL;
   grn_obj *obj = NULL;
 
-  if (!ctx->impl || !cache->max_nentries) { return; }
 
-  MUTEX_LOCK(cache->mutex);
+  MUTEX_LOCK(cache->impl.memory.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, key, key_len, (void **)&ce, &added);
+  id = grn_hash_add(cache->ctx, cache->impl.memory.hash, key, key_len,
+                    (void **)&ce, &added);
   if (id) {
     if (!added) {
       old = ce->value;
@@ -236,14 +322,14 @@ grn_cache_update(grn_ctx *ctx, grn_cache *cache,
     ce->value = obj;
     ce->tv = ctx->impl->tv;
     {
-      grn_cache_entry *ce0 = (grn_cache_entry *)cache;
+      grn_cache_entry *ce0 = (grn_cache_entry *)(&(cache->impl.memory));
       ce->next = ce0->next;
       ce->prev = ce0;
       ce0->next->prev = ce;
       ce0->next = ce;
     }
-    if (GRN_HASH_SIZE(cache->hash) > cache->max_nentries) {
-      grn_cache_expire_entry(cache, cache->prev);
+    if (GRN_HASH_SIZE(cache->impl.memory.hash) > cache->max_nentries) {
+      grn_cache_expire_entry_memory(cache, cache->impl.memory.prev);
     }
   } else {
     rc = GRN_NO_MEMORY_AVAILABLE;
@@ -251,18 +337,53 @@ grn_cache_update(grn_ctx *ctx, grn_cache *cache,
 exit :
   if (rc) { grn_obj_close(cache->ctx, obj); }
   if (old) { grn_obj_close(cache->ctx, old); }
-  MUTEX_UNLOCK(cache->mutex);
+  MUTEX_UNLOCK(cache->impl.memory.mutex);
+}
+
+inline static void
+grn_cache_update_persistent(grn_ctx *ctx, grn_cache *cache,
+                            const char *key, uint32_t key_len,
+                            grn_obj *value)
+{
 }
 
 void
-grn_cache_expire(grn_cache *cache, int32_t size)
+grn_cache_update(grn_ctx *ctx, grn_cache *cache,
+                 const char *key, uint32_t key_len, grn_obj *value)
+{
+  if (!ctx->impl || !cache->max_nentries) { return; }
+
+  if (cache->is_memory) {
+    grn_cache_update_memory(ctx, cache, key, key_len, value);
+  } else {
+    grn_cache_update_persistent(ctx, cache, key, key_len, value);
+  }
+}
+
+inline static void
+grn_cache_expire_memory(grn_cache *cache, int32_t size)
 {
-  grn_cache_entry *ce0 = (grn_cache_entry *)cache;
-  MUTEX_LOCK(cache->mutex);
+  grn_cache_entry *ce0 = (grn_cache_entry *)(&(cache->impl.memory));
+  MUTEX_LOCK(cache->impl.memory.mutex);
   while (ce0 != ce0->prev && size--) {
-    grn_cache_expire_entry(cache, ce0->prev);
+    grn_cache_expire_entry_memory(cache, ce0->prev);
+  }
+  MUTEX_UNLOCK(cache->impl.memory.mutex);
+}
+
+inline static void
+grn_cache_expire_persistent(grn_cache *cache, int32_t size)
+{
+}
+
+void
+grn_cache_expire(grn_cache *cache, int32_t size)
+{
+  if (cache->is_memory) {
+    grn_cache_expire_memory(cache, size);
+  } else {
+    grn_cache_expire_persistent(cache, size);
   }
-  MUTEX_UNLOCK(cache->mutex);
 }
 
 void
-------------- next part --------------
HTML����������������������������...
Download 



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