You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2010/08/09 00:00:32 UTC

svn commit: r983490 - in /subversion/branches/performance/subversion: include/private/svn_cache.h libsvn_fs_fs/caching.c libsvn_fs_fs/dag.c libsvn_fs_fs/dag.h libsvn_fs_fs/tree.c libsvn_subr/cache-inprocess.c tests/libsvn_subr/cache-test.c

Author: stefan2
Date: Sun Aug  8 22:00:32 2010
New Revision: 983490

URL: http://svn.apache.org/viewvc?rev=983490&view=rev
Log:
Unify cache interfaces: the in-process cache now uses the generally more efficient
(de-)serialization methods to copy data from / to the cache.

* subversion/include/svn_cache.h
  (svn_cache__create_inprocess): switch from duplication to (de-)serialization functions
* subversion/libsvn_subr/cache-inprocess.c
  (inprocess_cache_t): replace dup_func member with (de-)serialization function pointers
  (cache_entry): add size member (to be provided for the callbacks)
  (duplicate_value): remove now unused function
  (inprocess_cache_get, inprocess_cache_set): call (de-)serialization functions instead of duplication
  (svn_cache__create_inprocess): implement API changes
* subversion/tests/libsvn_subr/cache-test.c
  (dup_revnum): drop now unused function
  (test_inprocess_cache_basic): adapt to new API

* subversion/libsvn_fs_fs/tree.c
  (make_txn_root): adapt to new cache API
* subversion/libsvn_fs_fs/dag.h
  (svn_fs_fs__dag_dup_for_cache): remove now unused declaration
* subversion/libsvn_fs_fs/dag.c
  (svn_fs_fs__dag_dup_for_cache): remove now unused implementation
* subversion/libsvn_fs_fs/caching.c
  (dup_id, serialize_id, deserialize_id, dup_dir_listing, manifest_serialize, manifest_deserialize,
   dup_pack_manifest): remove unused functions
  (svn_fs_fs__initialize_caches): adapt to new cache API

* subversion/libsvn_fs_fs/dag.c

Modified:
    subversion/branches/performance/subversion/include/private/svn_cache.h
    subversion/branches/performance/subversion/libsvn_fs_fs/caching.c
    subversion/branches/performance/subversion/libsvn_fs_fs/dag.c
    subversion/branches/performance/subversion/libsvn_fs_fs/dag.h
    subversion/branches/performance/subversion/libsvn_fs_fs/tree.c
    subversion/branches/performance/subversion/libsvn_subr/cache-inprocess.c
    subversion/branches/performance/subversion/tests/libsvn_subr/cache-test.c

Modified: subversion/branches/performance/subversion/include/private/svn_cache.h
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/include/private/svn_cache.h?rev=983490&r1=983489&r2=983490&view=diff
==============================================================================
--- subversion/branches/performance/subversion/include/private/svn_cache.h (original)
+++ subversion/branches/performance/subversion/include/private/svn_cache.h Sun Aug  8 22:00:32 2010
@@ -107,7 +107,7 @@ typedef struct svn_cache__t svn_cache__t
  * for all of its storage needs.  The elements in the cache will be
  * indexed by keys of length @a klen, which may be APR_HASH_KEY_STRING
  * if they are strings.  Cached values will be copied in and out of
- * the cache using @a dup_func.
+ * the cache using @a serialize_func and @a deserialize_func, respectively.
  *
  * The cache stores up to @a pages * @a items_per_page items at a
  * time.  The exact cache invalidation strategy is not defined here,
@@ -127,7 +127,8 @@ typedef struct svn_cache__t svn_cache__t
  */
 svn_error_t *
 svn_cache__create_inprocess(svn_cache__t **cache_p,
-                            svn_cache__dup_func_t dup_func,
+                            svn_cache__serialize_func_t serialize_func,
+                            svn_cache__deserialize_func_t deserialize_func,
                             apr_ssize_t klen,
                             apr_int64_t pages,
                             apr_int64_t items_per_page,
@@ -194,7 +195,7 @@ svn_cache__make_memcache_from_config(svn
  *
  * Allocations will be made in @a pool, in particular the data buffers.
  */
-svn_error_t* 
+svn_error_t *
 svn_cache__membuffer_cache_create(svn_membuffer_t **cache,
                                   apr_size_t total_size,
                                   apr_size_t directory_size,

Modified: subversion/branches/performance/subversion/libsvn_fs_fs/caching.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_fs_fs/caching.c?rev=983490&r1=983489&r2=983490&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_fs_fs/caching.c (original)
+++ subversion/branches/performance/subversion/libsvn_fs_fs/caching.c Sun Aug  8 22:00:32 2010
@@ -24,6 +24,7 @@
 #include "fs_fs.h"
 #include "id.h"
 #include "dag.h"
+#include "temp_serializer.h"
 #include "../libsvn_fs/fs-loader.h"
 
 #include "svn_config.h"
@@ -33,130 +34,6 @@
 
 /*** Dup/serialize/deserialize functions. ***/
 
-
-/** Caching SVN_FS_ID_T values. **/
-/* Implements svn_cache__dup_func_t */
-static svn_error_t *
-dup_id(void **out,
-       const void *in,
-       apr_pool_t *pool)
-{
-  const svn_fs_id_t *id = in;
-  *out = svn_fs_fs__id_copy(id, pool);
-  return SVN_NO_ERROR;
-}
-
-/* Implements svn_cache__serialize_func_t */
-static svn_error_t *
-serialize_id(char **data,
-             apr_size_t *data_len,
-             void *in,
-             apr_pool_t *pool)
-{
-  svn_fs_id_t *id = in;
-  svn_string_t *id_str = svn_fs_fs__id_unparse(id, pool);
-  *data = (char *) id_str->data;
-  *data_len = id_str->len;
-
-  return SVN_NO_ERROR;
-}
-
-
-/* Implements svn_cache__deserialize_func_t */
-static svn_error_t *
-deserialize_id(void **out,
-               const char *data,
-               apr_size_t data_len,
-               apr_pool_t *pool)
-{
-  svn_fs_id_t *id = svn_fs_fs__id_parse(data, data_len, pool);
-  if (id == NULL)
-    {
-      return svn_error_create(SVN_ERR_FS_NOT_ID, NULL,
-                              _("Bad ID in cache"));
-    }
-
-  *out = id;
-  return SVN_NO_ERROR;
-}
-
-
-/** Caching directory listings. **/
-/* Implements svn_cache__dup_func_t */
-static svn_error_t *
-dup_dir_listing(void **out,
-                const void *in,
-                apr_pool_t *pool)
-{
-  apr_hash_t *new_entries = apr_hash_make(pool);
-  apr_hash_t *entries = (void*)in; /* Cast away const only */
-  apr_hash_index_t *hi;
-
-  for (hi = apr_hash_first(pool, entries); hi; hi = apr_hash_next(hi))
-    {
-      svn_fs_dirent_t *dirent = svn__apr_hash_index_val(hi);
-      svn_fs_dirent_t *new_dirent;
-
-      new_dirent = apr_palloc(pool, sizeof(*new_dirent));
-      new_dirent->name = apr_pstrdup(pool, dirent->name);
-      new_dirent->kind = dirent->kind;
-      new_dirent->id = svn_fs_fs__id_copy(dirent->id, pool);
-      apr_hash_set(new_entries, new_dirent->name, APR_HASH_KEY_STRING,
-                   new_dirent);
-    }
-
-  *out = new_entries;
-  return SVN_NO_ERROR;
-}
-
-
-/** Caching packed rev offsets. **/
-/* Implements svn_cache__serialize_func_t */
-static svn_error_t *
-manifest_serialize(char **data,
-                   apr_size_t *data_len,
-                   void *in,
-                   apr_pool_t *pool)
-{
-  apr_array_header_t *manifest = in;
-
-  *data_len = sizeof(apr_off_t) *manifest->nelts;
-  *data = apr_palloc(pool, *data_len);
-  memcpy(*data, manifest->elts, *data_len);
-
-  return SVN_NO_ERROR;
-}
-
-/* Implements svn_cache__deserialize_func_t */
-static svn_error_t *
-manifest_deserialize(void **out,
-                     const char *data,
-                     apr_size_t data_len,
-                     apr_pool_t *pool)
-{
-  apr_array_header_t *manifest = apr_array_make(pool,
-                                                data_len / sizeof(apr_off_t),
-                                                sizeof(apr_off_t));
-  memcpy(manifest->elts, data, data_len);
-  manifest->nelts = data_len / sizeof(apr_off_t);
-  *out = manifest;
-
-  return SVN_NO_ERROR;
-}
-
-/* Implements svn_cache__dup_func_t */
-static svn_error_t *
-dup_pack_manifest(void **out,
-                  const void *in,
-                  apr_pool_t *pool)
-{
-  const apr_array_header_t *manifest = in;
-
-  *out = apr_array_copy(pool, manifest);
-  return SVN_NO_ERROR;
-}
-
-
 /* Return a memcache in *MEMCACHE_P for FS if it's configured to use
    memcached, or NULL otherwise.  Also, sets *FAIL_STOP to a boolean
    indicating whether cache errors should be returned to the caller or
@@ -313,7 +190,9 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
                                               fs->pool));
   else
     SVN_ERR(svn_cache__create_inprocess(&(ffd->rev_root_id_cache),
-                                        dup_id, sizeof(svn_revnum_t),
+                                        svn_fs_fs__serialize_id,
+                                        svn_fs_fs__deserialize_id,
+                                        sizeof(svn_revnum_t),
                                         1, 100, FALSE, fs->pool));
   if (! no_handler)
     SVN_ERR(svn_cache__set_error_handler(ffd->rev_root_id_cache,
@@ -333,7 +212,8 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
                                               fs->pool));
   else
     SVN_ERR(svn_cache__create_inprocess(&(ffd->rev_node_cache),
-                                        svn_fs_fs__dag_dup_for_cache,
+                                        svn_fs_fs__dag_serialize,
+                                        svn_fs_fs__dag_deserialize,
                                         APR_HASH_KEY_STRING,
                                         1024, 16, FALSE, fs->pool));
   if (! no_handler)
@@ -353,7 +233,9 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
                                               fs->pool));
   else
     SVN_ERR(svn_cache__create_inprocess(&(ffd->dir_cache),
-                                        dup_dir_listing, APR_HASH_KEY_STRING,
+                                        svn_fs_fs__dir_entries_serialize,
+                                        svn_fs_fs__dir_entries_deserialize,
+                                        APR_HASH_KEY_STRING,
                                         1024, 8, FALSE, fs->pool));
 
   if (! no_handler)
@@ -373,7 +255,9 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
                                               fs->pool));
   else
     SVN_ERR(svn_cache__create_inprocess(&(ffd->packed_offset_cache),
-                                        dup_pack_manifest, sizeof(svn_revnum_t),
+                                        svn_fs_fs__serialize_manifest,
+                                        svn_fs_fs__deserialize_manifest,
+                                        sizeof(svn_revnum_t),
                                         32, 1, FALSE, fs->pool));
 
   if (! no_handler)

Modified: subversion/branches/performance/subversion/libsvn_fs_fs/dag.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_fs_fs/dag.c?rev=983490&r1=983489&r2=983490&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_fs_fs/dag.c (original)
+++ subversion/branches/performance/subversion/libsvn_fs_fs/dag.c Sun Aug  8 22:00:32 2010
@@ -1065,20 +1065,6 @@ svn_fs_fs__dag_dup(const dag_node_t *nod
 }
 
 svn_error_t *
-svn_fs_fs__dag_dup_for_cache(void **out,
-                             const void *in,
-                             apr_pool_t *pool)
-{
-  const dag_node_t *in_node = in;
-  dag_node_t *out_node;
-
-  out_node = svn_fs_fs__dag_dup(in_node, pool);
-  out_node->fs = NULL;
-  *out = out_node;
-  return SVN_NO_ERROR;
-}
-
-svn_error_t *
 svn_fs_fs__dag_serialize(char **data,
                          apr_size_t *data_len,
                          void *in,

Modified: subversion/branches/performance/subversion/libsvn_fs_fs/dag.h
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_fs_fs/dag.h?rev=983490&r1=983489&r2=983490&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_fs_fs/dag.h (original)
+++ subversion/branches/performance/subversion/libsvn_fs_fs/dag.h Sun Aug  8 22:00:32 2010
@@ -78,13 +78,6 @@ dag_node_t *
 svn_fs_fs__dag_dup(const dag_node_t *node,
                    apr_pool_t *pool);
 
-/* Like svn_fs_fs__dag_dup, but implementing the svn_cache__dup_func_t
-   prototype, and NULLing the FS field. */
-svn_error_t *
-svn_fs_fs__dag_dup_for_cache(void **out,
-                             const void *in,
-                             apr_pool_t *pool);
-
 /* Serialize a DAG node.
    Implements svn_cache__serialize_func_t */
 svn_error_t *

Modified: subversion/branches/performance/subversion/libsvn_fs_fs/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_fs_fs/tree.c?rev=983490&r1=983489&r2=983490&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/branches/performance/subversion/libsvn_fs_fs/tree.c Sun Aug  8 22:00:32 2010
@@ -3781,9 +3781,10 @@ make_txn_root(svn_fs_root_t **root_p,
      Note that since dag_node_cache_invalidate uses svn_cache__iter,
      this *cannot* be a memcache-based cache.  */
   SVN_ERR(svn_cache__create_inprocess(&(frd->txn_node_cache),
-                                     svn_fs_fs__dag_dup_for_cache,
-                                     APR_HASH_KEY_STRING,
-                                     32, 20, FALSE, root->pool));
+                                      svn_fs_fs__dag_serialize,
+                                      svn_fs_fs__dag_deserialize,
+                                      APR_HASH_KEY_STRING,
+                                      32, 20, FALSE, root->pool));
 
   root->fsap_data = frd;
 

Modified: subversion/branches/performance/subversion/libsvn_subr/cache-inprocess.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_subr/cache-inprocess.c?rev=983490&r1=983489&r2=983490&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_subr/cache-inprocess.c (original)
+++ subversion/branches/performance/subversion/libsvn_subr/cache-inprocess.c Sun Aug  8 22:00:32 2010
@@ -37,8 +37,11 @@ typedef struct {
   apr_hash_t *hash;
   apr_ssize_t klen;
 
-  /* Used to copy values in and out of the cache. */
-  svn_cache__dup_func_t dup_func;
+  /* Used to copy values into the cache. */
+  svn_cache__serialize_func_t serialize_func;
+
+  /* Used to copy values out of the cache. */
+  svn_cache__deserialize_func_t deserialize_func;
 
   /* The number of pages we're allowed to allocate before having to
    * try to reuse one. */
@@ -94,8 +97,13 @@ struct cache_page {
 /* An cache entry. */
 struct cache_entry {
   const void *key;
+
+  /* serialized value */
   void *value;
 
+  /* length of the serialized value in bytes */
+  apr_size_t size;
+
   /* The page it's on (needed so that the LRU list can be
    * maintained). */
   struct cache_page *page;
@@ -142,21 +150,6 @@ move_page_to_front(inprocess_cache_t *ca
   insert_page(cache, page);
 }
 
-/* Uses CACHE->dup_func to copy VALUE into *VALUE_P inside POOL, or
-   just sets *VALUE_P to NULL if VALUE is NULL. */
-static svn_error_t *
-duplicate_value(void **value_p,
-                inprocess_cache_t *cache,
-                void *value,
-                apr_pool_t *pool)
-{
-  if (value)
-    SVN_ERR((cache->dup_func)(value_p, value, pool));
-  else
-    *value_p = NULL;
-  return SVN_NO_ERROR;
-}
-
 /* Return a copy of KEY inside POOL, using CACHE->KLEN to figure out
  * how. */
 static const void *
@@ -214,7 +207,7 @@ inprocess_cache_get(void **value_p,
 {
   inprocess_cache_t *cache = cache_void;
   struct cache_entry *entry;
-  svn_error_t *err;
+  svn_error_t *err = SVN_NO_ERROR;
 
   SVN_ERR(lock_cache(cache));
 
@@ -228,7 +221,11 @@ inprocess_cache_get(void **value_p,
   move_page_to_front(cache, entry->page);
 
   *found = TRUE;
-  err = duplicate_value(value_p, cache, entry->value, pool);
+  if (entry->value)
+    err = cache->deserialize_func(value_p, entry->value, entry->size, pool);
+  else
+    *value_p = NULL;
+
   return unlock_cache(cache, err);
 }
 
@@ -302,8 +299,19 @@ inprocess_cache_set(void *cache_void,
       struct cache_page *page = existing_entry->page;
 
       move_page_to_front(cache, page);
-      err = duplicate_value(&(existing_entry->value), cache,
-                            value, page->page_pool);
+      if (value)
+        {
+          err = cache->serialize_func((char **)&existing_entry->value,
+                                      &existing_entry->size,
+                                      value,
+                                      page->page_pool);
+        }
+      else
+        {
+          existing_entry->value = NULL;
+          existing_entry->size = 0;
+        }
+
       goto cleanup;
     }
 
@@ -340,8 +348,19 @@ inprocess_cache_set(void *cache_void,
 
     /* Copy the key and value into the page's pool.  */
     new_entry->key = duplicate_key(cache, key, page->page_pool);
-    err = duplicate_value(&(new_entry->value), cache, value,
-                          page->page_pool);
+    if (value)
+      {
+        err = cache->serialize_func((char **)&new_entry->value,
+                                    &new_entry->size,
+                                    value,
+                                    page->page_pool);
+      }
+    else
+      {
+        new_entry->value = NULL;
+        new_entry->size = 0;
+      }
+
     if (err)
       goto cleanup;
 
@@ -417,7 +436,8 @@ static svn_cache__vtable_t inprocess_cac
 
 svn_error_t *
 svn_cache__create_inprocess(svn_cache__t **cache_p,
-                            svn_cache__dup_func_t dup_func,
+                            svn_cache__serialize_func_t serialize,
+                            svn_cache__deserialize_func_t deserialize,
                             apr_ssize_t klen,
                             apr_int64_t pages,
                             apr_int64_t items_per_page,
@@ -430,7 +450,8 @@ svn_cache__create_inprocess(svn_cache__t
   cache->hash = apr_hash_make(pool);
   cache->klen = klen;
 
-  cache->dup_func = dup_func;
+  cache->serialize_func = serialize;
+  cache->deserialize_func = deserialize;
 
   SVN_ERR_ASSERT(pages >= 1);
   cache->unallocated_pages = pages;

Modified: subversion/branches/performance/subversion/tests/libsvn_subr/cache-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/tests/libsvn_subr/cache-test.c?rev=983490&r1=983489&r2=983490&view=diff
==============================================================================
--- subversion/branches/performance/subversion/tests/libsvn_subr/cache-test.c (original)
+++ subversion/branches/performance/subversion/tests/libsvn_subr/cache-test.c Sun Aug  8 22:00:32 2010
@@ -34,22 +34,6 @@
 
 #include "../svn_test.h"
 
-/* Implements svn_cache__dup_func_t */
-static svn_error_t *
-dup_revnum(void **out,
-           const void *in,
-           apr_pool_t *pool)
-{
-  const svn_revnum_t *in_rn = in;
-  svn_revnum_t *duped = apr_palloc(pool, sizeof(*duped));
-
-  *duped = *in_rn;
-
-  *out = duped;
-
-  return SVN_NO_ERROR;
-}
-
 /* Implements svn_cache__serialize_func_t */
 static svn_error_t *
 serialize_revnum(char **data,
@@ -145,12 +129,13 @@ test_inprocess_cache_basic(apr_pool_t *p
 
   /* Create a cache with just one entry. */
   SVN_ERR(svn_cache__create_inprocess(&cache,
-                                     dup_revnum,
-                                     APR_HASH_KEY_STRING,
-                                     1,
-                                     1,
-                                     TRUE,
-                                     pool));
+                                      serialize_revnum,
+                                      deserialize_revnum,
+                                      APR_HASH_KEY_STRING,
+                                      1,
+                                      1,
+                                      TRUE,
+                                      pool));
 
   return basic_cache_test(cache, TRUE, pool);
 }