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);
}