summaryrefslogtreecommitdiff
path: root/subversion/libsvn_fs_x/caching.c
diff options
context:
space:
mode:
Diffstat (limited to 'subversion/libsvn_fs_x/caching.c')
-rw-r--r--subversion/libsvn_fs_x/caching.c351
1 files changed, 154 insertions, 197 deletions
diff --git a/subversion/libsvn_fs_x/caching.c b/subversion/libsvn_fs_x/caching.c
index 17e80bddc6982..8c65ab11a2a84 100644
--- a/subversion/libsvn_fs_x/caching.c
+++ b/subversion/libsvn_fs_x/caching.c
@@ -23,8 +23,7 @@
#include "fs.h"
#include "fs_x.h"
#include "id.h"
-#include "dag.h"
-#include "tree.h"
+#include "dag_cache.h"
#include "index.h"
#include "changes.h"
#include "noderevs.h"
@@ -70,9 +69,9 @@ normalize_key_part(const char *original,
return normalized->data;
}
-/* *CACHE_TXDELTAS, *CACHE_FULLTEXTS and *CACHE_REVPROPS flags will be set
- according to FS->CONFIG. *CACHE_NAMESPACE receives the cache prefix
- to use.
+/* *CACHE_TXDELTAS, *CACHE_FULLTEXTS, *CACHE_REVPROPS and *CACHE_NODEPROPS
+ flags will be set according to FS->CONFIG. *CACHE_NAMESPACE receives
+ the cache prefix to use.
Allocate CACHE_NAMESPACE in RESULT_POOL. */
static svn_error_t *
@@ -80,6 +79,7 @@ read_config(const char **cache_namespace,
svn_boolean_t *cache_txdeltas,
svn_boolean_t *cache_fulltexts,
svn_boolean_t *cache_revprops,
+ svn_boolean_t *cache_nodeprops,
svn_fs_t *fs,
apr_pool_t *result_pool)
{
@@ -138,6 +138,15 @@ read_config(const char **cache_namespace,
else
*cache_revprops = TRUE;
+ /* by default, cache nodeprops: this will match pre-1.10
+ * behavior where node properties caching was controlled
+ * by SVN_FS_CONFIG_FSFS_CACHE_FULLTEXTS configuration option.
+ */
+ *cache_nodeprops
+ = svn_hash__get_bool(fs->config,
+ SVN_FS_CONFIG_FSFS_CACHE_NODEPROPS,
+ TRUE);
+
return SVN_NO_ERROR;
}
@@ -260,42 +269,42 @@ init_callbacks(svn_cache__t *cache,
svn_cache__error_handler_t error_handler,
apr_pool_t *pool)
{
- if (cache != NULL)
- {
#ifdef SVN_DEBUG_CACHE_DUMP_STATS
- /* schedule printing the access statistics upon pool cleanup,
- * i.e. end of FSX session.
- */
- dump_cache_baton_t *baton;
+ /* schedule printing the access statistics upon pool cleanup,
+ * i.e. end of FSX session.
+ */
+ dump_cache_baton_t *baton;
- baton = apr_palloc(pool, sizeof(*baton));
- baton->pool = pool;
- baton->cache = cache;
+ baton = apr_palloc(pool, sizeof(*baton));
+ baton->pool = pool;
+ baton->cache = cache;
- apr_pool_cleanup_register(pool,
- baton,
- dump_cache_statistics,
- apr_pool_cleanup_null);
+ apr_pool_cleanup_register(pool,
+ baton,
+ dump_cache_statistics,
+ apr_pool_cleanup_null);
#endif
- if (error_handler)
- SVN_ERR(svn_cache__set_error_handler(cache,
- error_handler,
- fs,
- pool));
-
- }
+ if (error_handler)
+ SVN_ERR(svn_cache__set_error_handler(cache,
+ error_handler,
+ fs,
+ pool));
return SVN_NO_ERROR;
}
/* Sets *CACHE_P to cache instance based on provided options.
- * Creates memcache if MEMCACHE is not NULL. Creates membuffer cache if
- * MEMBUFFER is not NULL. Fallbacks to inprocess cache if MEMCACHE and
- * MEMBUFFER are NULL and pages is non-zero. Sets *CACHE_P to NULL
- * otherwise. Use the given PRIORITY class for the new cache. If it
- * is 0, then use the default priority class.
+ *
+ * If DUMMY_CACHE is set, create a null cache. Otherwise, creates a memcache
+ * if MEMCACHE is not NULL or a membuffer cache if MEMBUFFER is not NULL.
+ * Falls back to inprocess cache if no other cache type has been selected
+ * and PAGES is not 0. Create a null cache otherwise.
+ *
+ * Use the given PRIORITY class for the new cache. If PRIORITY is 0, then
+ * use the default priority class. HAS_NAMESPACE indicates whether we
+ * prefixed this cache instance with a namespace.
*
* Unless NO_HANDLER is true, register an error handler that reports errors
* as warnings to the FS warning callback.
@@ -313,8 +322,10 @@ create_cache(svn_cache__t **cache_p,
apr_ssize_t klen,
const char *prefix,
apr_uint32_t priority,
+ svn_boolean_t has_namespace,
svn_fs_t *fs,
svn_boolean_t no_handler,
+ svn_boolean_t dummy_cache,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
@@ -324,7 +335,11 @@ create_cache(svn_cache__t **cache_p,
if (priority == 0)
priority = SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY;
- if (memcache)
+ if (dummy_cache)
+ {
+ SVN_ERR(svn_cache__create_null(cache_p, prefix, result_pool));
+ }
+ else if (memcache)
{
SVN_ERR(svn_cache__create_memcache(cache_p, memcache,
serializer, deserializer, klen,
@@ -335,9 +350,12 @@ create_cache(svn_cache__t **cache_p,
}
else if (membuffer)
{
+ /* We assume caches with namespaces to be relatively short-lived,
+ * i.e. their data will not be needed after a while. */
SVN_ERR(svn_cache__create_membuffer_cache(
cache_p, membuffer, serializer, deserializer,
- klen, prefix, priority, FALSE, result_pool, scratch_pool));
+ klen, prefix, priority, FALSE, has_namespace,
+ result_pool, scratch_pool));
}
else if (pages)
{
@@ -347,7 +365,7 @@ create_cache(svn_cache__t **cache_p,
}
else
{
- *cache_p = NULL;
+ SVN_ERR(svn_cache__create_null(cache_p, prefix, result_pool));
}
SVN_ERR(init_callbacks(*cache_p, fs, error_handler, result_pool));
@@ -362,6 +380,7 @@ svn_fs_x__initialize_caches(svn_fs_t *fs,
svn_fs_x__data_t *ffd = fs->fsap_data;
const char *prefix = apr_pstrcat(scratch_pool,
"fsx:", fs->uuid,
+ "--", ffd->instance_id,
"/", normalize_key_part(fs->path,
scratch_pool),
":",
@@ -371,25 +390,29 @@ svn_fs_x__initialize_caches(svn_fs_t *fs,
svn_boolean_t cache_txdeltas;
svn_boolean_t cache_fulltexts;
svn_boolean_t cache_revprops;
+ svn_boolean_t cache_nodeprops;
const char *cache_namespace;
+ svn_boolean_t has_namespace;
/* Evaluating the cache configuration. */
SVN_ERR(read_config(&cache_namespace,
&cache_txdeltas,
&cache_fulltexts,
&cache_revprops,
+ &cache_nodeprops,
fs,
scratch_pool));
prefix = apr_pstrcat(scratch_pool, "ns:", cache_namespace, ":", prefix,
SVN_VA_NULL);
+ has_namespace = strlen(cache_namespace) > 0;
membuffer = svn_cache__get_global_membuffer_cache();
/* General rules for assigning cache priorities:
*
* - Data that can be reconstructed from other elements has low prio
- * (e.g. fulltexts, directories etc.)
+ * (e.g. fulltexts etc.)
* - Index data required to find any of the other data has high prio
* (e.g. noderevs, L2P and P2L index pages)
* - everthing else should use default prio
@@ -407,21 +430,6 @@ svn_fs_x__initialize_caches(svn_fs_t *fs,
apr_pool_cleanup_null);
#endif
- /* Rough estimate: revision DAG nodes have size around 320 bytes, so
- * let's put 16 on a page. */
- SVN_ERR(create_cache(&(ffd->rev_node_cache),
- NULL,
- membuffer,
- 1024, 16,
- svn_fs_x__dag_serialize,
- svn_fs_x__dag_deserialize,
- APR_HASH_KEY_STRING,
- apr_pstrcat(scratch_pool, prefix, "DAG", SVN_VA_NULL),
- SVN_CACHE__MEMBUFFER_LOW_PRIORITY,
- fs,
- no_handler,
- fs->pool, scratch_pool));
-
/* 1st level DAG node cache */
ffd->dag_node_cache = svn_fs_x__create_dag_cache(fs->pool);
@@ -434,25 +442,10 @@ svn_fs_x__initialize_caches(svn_fs_t *fs,
svn_fs_x__deserialize_dir_entries,
sizeof(svn_fs_x__id_t),
apr_pstrcat(scratch_pool, prefix, "DIR", SVN_VA_NULL),
- SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
- fs,
- no_handler,
- fs->pool, scratch_pool));
-
- /* Only 16 bytes per entry (a revision number + the corresponding offset).
- Since we want ~8k pages, that means 512 entries per page. */
- SVN_ERR(create_cache(&(ffd->packed_offset_cache),
- NULL,
- membuffer,
- 32, 1,
- svn_fs_x__serialize_manifest,
- svn_fs_x__deserialize_manifest,
- sizeof(svn_revnum_t),
- apr_pstrcat(scratch_pool, prefix, "PACK-MANIFEST",
- SVN_VA_NULL),
SVN_CACHE__MEMBUFFER_HIGH_PRIORITY,
+ has_namespace,
fs,
- no_handler,
+ no_handler, FALSE,
fs->pool, scratch_pool));
/* initialize node revision cache, if caching has been enabled */
@@ -466,8 +459,9 @@ svn_fs_x__initialize_caches(svn_fs_t *fs,
apr_pstrcat(scratch_pool, prefix, "NODEREVS",
SVN_VA_NULL),
SVN_CACHE__MEMBUFFER_HIGH_PRIORITY,
+ has_namespace,
fs,
- no_handler,
+ no_handler, FALSE,
fs->pool, scratch_pool));
/* initialize representation header cache, if caching has been enabled */
@@ -481,8 +475,9 @@ svn_fs_x__initialize_caches(svn_fs_t *fs,
apr_pstrcat(scratch_pool, prefix, "REPHEADER",
SVN_VA_NULL),
SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
+ has_namespace,
fs,
- no_handler,
+ no_handler, FALSE,
fs->pool, scratch_pool));
/* initialize node change list cache, if caching has been enabled */
@@ -492,140 +487,94 @@ svn_fs_x__initialize_caches(svn_fs_t *fs,
1, 8, /* 1k / entry; 8 entries total, rarely used */
svn_fs_x__serialize_changes,
svn_fs_x__deserialize_changes,
- sizeof(svn_revnum_t),
+ sizeof(svn_fs_x__pair_cache_key_t),
apr_pstrcat(scratch_pool, prefix, "CHANGES",
SVN_VA_NULL),
0,
+ has_namespace,
fs,
- no_handler,
+ no_handler, FALSE,
fs->pool, scratch_pool));
/* if enabled, cache fulltext and other derived information */
- if (cache_fulltexts)
- {
- SVN_ERR(create_cache(&(ffd->fulltext_cache),
- ffd->memcache,
- membuffer,
- 0, 0, /* Do not use inprocess cache */
- /* Values are svn_stringbuf_t */
- NULL, NULL,
- sizeof(svn_fs_x__pair_cache_key_t),
- apr_pstrcat(scratch_pool, prefix, "TEXT",
- SVN_VA_NULL),
- SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
- fs,
- no_handler,
- fs->pool, scratch_pool));
-
- SVN_ERR(create_cache(&(ffd->properties_cache),
- NULL,
- membuffer,
- 0, 0, /* Do not use inprocess cache */
- svn_fs_x__serialize_properties,
- svn_fs_x__deserialize_properties,
- sizeof(svn_fs_x__pair_cache_key_t),
- apr_pstrcat(scratch_pool, prefix, "PROP",
- SVN_VA_NULL),
- SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
- fs,
- no_handler,
- fs->pool, scratch_pool));
-
- SVN_ERR(create_cache(&(ffd->mergeinfo_cache),
- NULL,
- membuffer,
- 0, 0, /* Do not use inprocess cache */
- svn_fs_x__serialize_mergeinfo,
- svn_fs_x__deserialize_mergeinfo,
- APR_HASH_KEY_STRING,
- apr_pstrcat(scratch_pool, prefix, "MERGEINFO",
- SVN_VA_NULL),
- 0,
- fs,
- no_handler,
- fs->pool, scratch_pool));
-
- SVN_ERR(create_cache(&(ffd->mergeinfo_existence_cache),
- NULL,
- membuffer,
- 0, 0, /* Do not use inprocess cache */
- /* Values are svn_stringbuf_t */
- NULL, NULL,
- APR_HASH_KEY_STRING,
- apr_pstrcat(scratch_pool, prefix, "HAS_MERGEINFO",
- SVN_VA_NULL),
- 0,
- fs,
- no_handler,
- fs->pool, scratch_pool));
- }
- else
- {
- ffd->fulltext_cache = NULL;
- ffd->properties_cache = NULL;
- ffd->mergeinfo_cache = NULL;
- ffd->mergeinfo_existence_cache = NULL;
- }
+ SVN_ERR(create_cache(&(ffd->fulltext_cache),
+ ffd->memcache,
+ membuffer,
+ 0, 0, /* Do not use inprocess cache */
+ /* Values are svn_stringbuf_t */
+ NULL, NULL,
+ sizeof(svn_fs_x__pair_cache_key_t),
+ apr_pstrcat(scratch_pool, prefix, "TEXT",
+ SVN_VA_NULL),
+ SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
+ has_namespace,
+ fs,
+ no_handler, !cache_fulltexts,
+ fs->pool, scratch_pool));
+
+ SVN_ERR(create_cache(&(ffd->properties_cache),
+ NULL,
+ membuffer,
+ 0, 0, /* Do not use inprocess cache */
+ svn_fs_x__serialize_properties,
+ svn_fs_x__deserialize_properties,
+ sizeof(svn_fs_x__pair_cache_key_t),
+ apr_pstrcat(scratch_pool, prefix, "PROP",
+ SVN_VA_NULL),
+ SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
+ has_namespace,
+ fs,
+ no_handler, !cache_nodeprops,
+ fs->pool, scratch_pool));
/* if enabled, cache revprops */
- if (cache_revprops)
- {
- SVN_ERR(create_cache(&(ffd->revprop_cache),
- NULL,
- membuffer,
- 0, 0, /* Do not use inprocess cache */
- svn_fs_x__serialize_properties,
- svn_fs_x__deserialize_properties,
- sizeof(svn_fs_x__pair_cache_key_t),
- apr_pstrcat(scratch_pool, prefix, "REVPROP",
- SVN_VA_NULL),
- SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
- fs,
- no_handler,
- fs->pool, scratch_pool));
- }
- else
- {
- ffd->revprop_cache = NULL;
- }
+ SVN_ERR(create_cache(&(ffd->revprop_cache),
+ NULL,
+ membuffer,
+ 0, 0, /* Do not use inprocess cache */
+ svn_fs_x__serialize_properties,
+ svn_fs_x__deserialize_properties,
+ sizeof(svn_fs_x__pair_cache_key_t),
+ apr_pstrcat(scratch_pool, prefix, "REVPROP",
+ SVN_VA_NULL),
+ SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
+ has_namespace,
+ fs,
+ no_handler, !cache_revprops,
+ fs->pool, scratch_pool));
/* if enabled, cache text deltas and their combinations */
- if (cache_txdeltas)
- {
- SVN_ERR(create_cache(&(ffd->txdelta_window_cache),
- NULL,
- membuffer,
- 0, 0, /* Do not use inprocess cache */
- svn_fs_x__serialize_txdelta_window,
- svn_fs_x__deserialize_txdelta_window,
- sizeof(svn_fs_x__window_cache_key_t),
- apr_pstrcat(scratch_pool, prefix, "TXDELTA_WINDOW",
- SVN_VA_NULL),
- SVN_CACHE__MEMBUFFER_LOW_PRIORITY,
- fs,
- no_handler,
- fs->pool, scratch_pool));
-
- SVN_ERR(create_cache(&(ffd->combined_window_cache),
- NULL,
- membuffer,
- 0, 0, /* Do not use inprocess cache */
- /* Values are svn_stringbuf_t */
- NULL, NULL,
- sizeof(svn_fs_x__window_cache_key_t),
- apr_pstrcat(scratch_pool, prefix, "COMBINED_WINDOW",
- SVN_VA_NULL),
- SVN_CACHE__MEMBUFFER_LOW_PRIORITY,
- fs,
- no_handler,
- fs->pool, scratch_pool));
- }
- else
- {
- ffd->txdelta_window_cache = NULL;
- ffd->combined_window_cache = NULL;
- }
+ SVN_ERR(create_cache(&(ffd->txdelta_window_cache),
+ NULL,
+ membuffer,
+ 0, 0, /* Do not use inprocess cache */
+ svn_fs_x__serialize_txdelta_window,
+ svn_fs_x__deserialize_txdelta_window,
+ sizeof(svn_fs_x__window_cache_key_t),
+ apr_pstrcat(scratch_pool, prefix, "TXDELTA_WINDOW",
+ SVN_VA_NULL),
+ SVN_CACHE__MEMBUFFER_LOW_PRIORITY,
+ has_namespace,
+ fs,
+ no_handler, !cache_txdeltas,
+ fs->pool, scratch_pool));
+
+ SVN_ERR(create_cache(&(ffd->combined_window_cache),
+ NULL,
+ membuffer,
+ 0, 0, /* Do not use inprocess cache */
+ /* Values are svn_stringbuf_t */
+ NULL, NULL,
+ sizeof(svn_fs_x__window_cache_key_t),
+ apr_pstrcat(scratch_pool, prefix, "COMBINED_WINDOW",
+ SVN_VA_NULL),
+ SVN_CACHE__MEMBUFFER_LOW_PRIORITY,
+ has_namespace,
+ fs,
+ no_handler, !cache_txdeltas,
+ fs->pool, scratch_pool));
+ /* Caches for our various container types. */
SVN_ERR(create_cache(&(ffd->noderevs_container_cache),
NULL,
membuffer,
@@ -636,8 +585,9 @@ svn_fs_x__initialize_caches(svn_fs_t *fs,
apr_pstrcat(scratch_pool, prefix, "NODEREVSCNT",
SVN_VA_NULL),
SVN_CACHE__MEMBUFFER_HIGH_PRIORITY,
+ has_namespace,
fs,
- no_handler,
+ no_handler, FALSE,
fs->pool, scratch_pool));
SVN_ERR(create_cache(&(ffd->changes_container_cache),
NULL,
@@ -649,8 +599,9 @@ svn_fs_x__initialize_caches(svn_fs_t *fs,
apr_pstrcat(scratch_pool, prefix, "CHANGESCNT",
SVN_VA_NULL),
0,
+ has_namespace,
fs,
- no_handler,
+ no_handler, FALSE,
fs->pool, scratch_pool));
SVN_ERR(create_cache(&(ffd->reps_container_cache),
NULL,
@@ -662,10 +613,12 @@ svn_fs_x__initialize_caches(svn_fs_t *fs,
apr_pstrcat(scratch_pool, prefix, "REPSCNT",
SVN_VA_NULL),
0,
+ has_namespace,
fs,
- no_handler,
+ no_handler, FALSE,
fs->pool, scratch_pool));
+ /* Cache index info. */
SVN_ERR(create_cache(&(ffd->l2p_header_cache),
NULL,
membuffer,
@@ -677,8 +630,9 @@ svn_fs_x__initialize_caches(svn_fs_t *fs,
apr_pstrcat(scratch_pool, prefix, "L2P_HEADER",
SVN_VA_NULL),
SVN_CACHE__MEMBUFFER_HIGH_PRIORITY,
+ has_namespace,
fs,
- no_handler,
+ no_handler, FALSE,
fs->pool, scratch_pool));
SVN_ERR(create_cache(&(ffd->l2p_page_cache),
NULL,
@@ -691,8 +645,9 @@ svn_fs_x__initialize_caches(svn_fs_t *fs,
apr_pstrcat(scratch_pool, prefix, "L2P_PAGE",
SVN_VA_NULL),
SVN_CACHE__MEMBUFFER_HIGH_PRIORITY,
+ has_namespace,
fs,
- no_handler,
+ no_handler, FALSE,
fs->pool, scratch_pool));
SVN_ERR(create_cache(&(ffd->p2l_header_cache),
NULL,
@@ -704,8 +659,9 @@ svn_fs_x__initialize_caches(svn_fs_t *fs,
apr_pstrcat(scratch_pool, prefix, "P2L_HEADER",
SVN_VA_NULL),
SVN_CACHE__MEMBUFFER_HIGH_PRIORITY,
+ has_namespace,
fs,
- no_handler,
+ no_handler, FALSE,
fs->pool, scratch_pool));
SVN_ERR(create_cache(&(ffd->p2l_page_cache),
NULL,
@@ -717,8 +673,9 @@ svn_fs_x__initialize_caches(svn_fs_t *fs,
apr_pstrcat(scratch_pool, prefix, "P2L_PAGE",
SVN_VA_NULL),
SVN_CACHE__MEMBUFFER_HIGH_PRIORITY,
+ has_namespace,
fs,
- no_handler,
+ no_handler, FALSE,
fs->pool, scratch_pool));
return SVN_NO_ERROR;