Author: stefan2
Date: Sat Apr 27 16:57:10 2013
New Revision: 1476623
URL: http://svn.apache.org/r1476623
Log:
On the fsfs-format7 branch: cache change list containters
* subversion/libsvn_fs_fs/fs.h
(fs_fs_data_t.changes_container_cache): add cache as new member
* subversion/libsvn_fs_fs/caching.c
(svn_fs_fs__initialize_caches): initialize the new cache for fsfs-f7
* subversion/libsvn_fs_fs/changes.h
(svn_fs_fs__serialize_changes_container,
svn_fs_fs__deserialize_changes_container): declare cache serialization /
deserialization functions
* subversion/libsvn_fs_fs/changes.c
(svn_fs_fs__serialize_changes_container,
svn_fs_fs__deserialize_changes_container): implement them
* subversion/libsvn_fs_fs/cached_data.c
(svn_fs_fs__get_changes): hit the right cache
(block_read_changes_container): populate the new cache
Modified:
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/cached_data.c
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/caching.c
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/changes.c
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/changes.h
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs.h
Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/cached_data.c
URL:
http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/cached_data.c?rev=1476623&r1=1476622&r2=1476623&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/cached_data.c
(original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/cached_data.c Sat
Apr 27 16:57:10 2013
@@ -2141,50 +2141,64 @@ svn_fs_fs__get_changes(apr_array_header_
/* try cache lookup first */
- if (ffd->changes_cache)
+ if (ffd->changes_container_cache && is_packed_rev(fs, rev))
{
- SVN_ERR(svn_cache__get((void **) changes, &found, ffd->changes_cache,
- &rev, pool));
- if (found)
- {
- SVN_ERR(dgb__log_access(fs, rev, SVN_FS_FS__ITEM_INDEX_CHANGES,
- *changes, SVN_FS_FS__ITEM_TYPE_CHANGES,
- pool));
+ svn_fs_fs__changes_t *container;
+ apr_off_t offset;
+ apr_uint32_t sub_item;
+ pair_cache_key_t key;
+
+ SVN_ERR(svn_fs_fs__item_offset(&offset, &sub_item, fs, rev, NULL,
+ SVN_FS_FS__ITEM_INDEX_CHANGES, pool));
+ key.revision = packed_base_rev(fs, rev);
+ key.second = offset;
- return SVN_NO_ERROR;
- }
+ SVN_ERR(svn_cache__get((void **)&container, &found,
+ ffd->changes_container_cache, &key, pool));
+ if (found)
+ SVN_ERR(svn_fs_fs__changes_get_list(changes, container, sub_item,
+ pool));
}
-
- /* read changes from revision file */
-
- SVN_ERR(svn_fs_fs__ensure_revision_exists(rev, fs, pool));
- SVN_ERR(svn_fs_fs__open_pack_or_rev_file(&revision_file, fs, rev, pool));
-
- if (ffd->format >= SVN_FS_FS__MIN_LOG_ADDRESSING_FORMAT)
+ else if (ffd->changes_cache)
{
- /* 'block-read' will also provide us with the desired data */
- SVN_ERR(block_read((void **)changes, fs,
- rev, SVN_FS_FS__ITEM_INDEX_CHANGES,
- revision_file, pool, pool));
+ SVN_ERR(svn_cache__get((void **) changes, &found, ffd->changes_cache,
+ &rev, pool));
}
- else
+
+ if (!found)
{
- /* pre-format7 code path */
- SVN_ERR(get_root_changes_offset(NULL, &changes_offset, revision_file,
- fs, rev, pool));
- SVN_ERR(svn_io_file_seek(revision_file, APR_SET, &changes_offset, pool));
- SVN_ERR(svn_fs_fs__read_changes(changes,
- svn_stream_from_aprfile2(revision_file,
- TRUE, pool),
- pool));
+ /* read changes from revision file */
- /* cache for future reference */
+ SVN_ERR(svn_fs_fs__ensure_revision_exists(rev, fs, pool));
+ SVN_ERR(svn_fs_fs__open_pack_or_rev_file(&revision_file, fs, rev,
+ pool));
- if (ffd->changes_cache)
- SVN_ERR(svn_cache__set(ffd->changes_cache, &rev, *changes, pool));
- }
+ if (ffd->format >= SVN_FS_FS__MIN_LOG_ADDRESSING_FORMAT)
+ {
+ /* 'block-read' will also provide us with the desired data */
+ SVN_ERR(block_read((void **)changes, fs,
+ rev, SVN_FS_FS__ITEM_INDEX_CHANGES,
+ revision_file, pool, pool));
+ }
+ else
+ {
+ /* pre-format7 code path */
+ SVN_ERR(get_root_changes_offset(NULL, &changes_offset,
+ revision_file, fs, rev, pool));
+ SVN_ERR(svn_io_file_seek(revision_file, APR_SET, &changes_offset,
+ pool));
+ SVN_ERR(svn_fs_fs__read_changes(changes,
+ svn_stream_from_aprfile2(revision_file, TRUE, pool),
+ pool));
+
+ /* cache for future reference */
- SVN_ERR(svn_io_file_close(revision_file, pool));
+ if (ffd->changes_cache)
+ SVN_ERR(svn_cache__set(ffd->changes_cache, &rev, *changes, pool));
+ }
+
+ SVN_ERR(svn_io_file_close(revision_file, pool));
+ }
SVN_ERR(dgb__log_access(fs, rev, SVN_FS_FS__ITEM_INDEX_CHANGES, *changes,
SVN_FS_FS__ITEM_TYPE_CHANGES, pool));
@@ -2419,10 +2433,23 @@ block_read_changes_container(apr_array_h
svn_boolean_t must_read,
apr_pool_t *pool)
{
+ fs_fs_data_t *ffd = fs->fsap_data;
svn_fs_fs__changes_t *container;
+ pair_cache_key_t key;
svn_stream_t *stream;
- if (!must_read)
- return SVN_NO_ERROR;
+
+ key.revision = packed_base_rev(fs, entry->items[0].revision);
+ key.second = entry->offset;
+
+ /* already in cache? */
+ if (!must_read && ffd->changes_container_cache)
+ {
+ svn_boolean_t is_cached = FALSE;
+ SVN_ERR(svn_cache__has_key(&is_cached, ffd->changes_container_cache,
+ &key, pool));
+ if (is_cached)
+ return SVN_NO_ERROR;
+ }
SVN_ERR(auto_select_stream(&stream, fs, file, file_stream, entry, pool));
@@ -2432,7 +2459,12 @@ block_read_changes_container(apr_array_h
/* extract requested data */
- SVN_ERR(svn_fs_fs__changes_get_list(changes, container, sub_item, pool));
+ if (must_read)
+ SVN_ERR(svn_fs_fs__changes_get_list(changes, container, sub_item, pool));
+
+ if (ffd->changes_container_cache)
+ SVN_ERR(svn_cache__set(ffd->changes_container_cache, &key, container,
+ pool));
return SVN_NO_ERROR;
}
Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/caching.c
URL:
http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/caching.c?rev=1476623&r1=1476622&r2=1476623&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/caching.c
(original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/caching.c Sat Apr
27 16:57:10 2013
@@ -26,6 +26,7 @@
#include "dag.h"
#include "tree.h"
#include "index.h"
+#include "changes.h"
#include "temp_serializer.h"
#include "../libsvn_fs/fs-loader.h"
@@ -581,6 +582,20 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
if (ffd->format >= SVN_FS_FS__MIN_LOG_ADDRESSING_FORMAT)
{
+ SVN_ERR(create_cache(&(ffd->changes_container_cache),
+ NULL,
+ membuffer,
+ 0, 0, /* Do not use inprocess cache */
+ svn_fs_fs__serialize_changes_container,
+ svn_fs_fs__deserialize_changes_container,
+ sizeof(pair_cache_key_t),
+ apr_pstrcat(pool, prefix, "CHANGESCNT",
+ (char *)NULL),
+ SVN_CACHE__MEMBUFFER_HIGH_PRIORITY,
+ fs,
+ no_handler,
+ fs->pool));
+
SVN_ERR(create_cache(&(ffd->l2p_header_cache),
NULL,
membuffer,
@@ -636,6 +651,8 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
}
else
{
+ ffd->changes_container_cache = NULL;
+
ffd->l2p_header_cache = NULL;
ffd->l2p_page_cache = NULL;
ffd->p2l_header_cache = NULL;
Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/changes.c
URL:
http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/changes.c?rev=1476623&r1=1476622&r2=1476623&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/changes.c
(original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/changes.c Sat Apr
27 16:57:10 2013
@@ -420,3 +420,57 @@ svn_fs_fs__read_changes_container(svn_fs
return SVN_NO_ERROR;
}
+
+svn_error_t *
+svn_fs_fs__serialize_changes_container(void **data,
+ apr_size_t *data_len,
+ void *in,
+ apr_pool_t *pool)
+{
+ svn_fs_fs__changes_t *changes = in;
+ svn_stringbuf_t *serialized;
+
+ /* make a guesstimate on the size of the serialized data. Erring on the
+ * low side will cause the serializer to re-alloc its buffer. */
+ apr_size_t size
+ = changes->changes->elt_size * changes->changes->nelts
+ + changes->offsets->elt_size * changes->offsets->nelts
+ + 10 * changes->changes->elt_size
+ + 100;
+
+ /* serialize array header and all its elements */
+ svn_temp_serializer__context_t *context
+ = svn_temp_serializer__init(changes, sizeof(*changes), size, pool);
+
+ /* serialize sub-structures */
+ svn_fs_fs__serialize_string_table(context, &changes->paths);
+ svn_fs_fs__serialize_apr_array(context, &changes->changes);
+ svn_fs_fs__serialize_apr_array(context, &changes->offsets);
+
+ /* return the serialized result */
+ serialized = svn_temp_serializer__get(context);
+
+ *data = serialized->data;
+ *data_len = serialized->len;
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_fs_fs__deserialize_changes_container(void **out,
+ void *data,
+ apr_size_t data_len,
+ apr_pool_t *pool)
+{
+ svn_fs_fs__changes_t *changes = (svn_fs_fs__changes_t *)data;
+
+ /* de-serialize sub-structures */
+ svn_fs_fs__deserialize_string_table(changes, &changes->paths);
+ svn_fs_fs__deserialize_apr_array(changes, &changes->changes, pool);
+ svn_fs_fs__deserialize_apr_array(changes, &changes->offsets, pool);
+
+ /* done */
+ *out = changes;
+
+ return SVN_NO_ERROR;
+}
Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/changes.h
URL:
http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/changes.h?rev=1476623&r1=1476622&r2=1476623&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/changes.h
(original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/changes.h Sat Apr
27 16:57:10 2013
@@ -98,4 +98,20 @@ svn_fs_fs__read_changes_container(svn_fs
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
+/* Implements #svn_cache__serialize_func_t for svn_fs_fs__changes_t objects.
+ */
+svn_error_t *
+svn_fs_fs__serialize_changes_container(void **data,
+ apr_size_t *data_len,
+ void *in,
+ apr_pool_t *pool);
+
+/* Implements #svn_cache__deserialize_func_t for svn_fs_fs__changes_t objects.
+ */
+svn_error_t *
+svn_fs_fs__deserialize_changes_container(void **out,
+ void *data,
+ apr_size_t data_len,
+ apr_pool_t *pool);
+
#endif
\ No newline at end of file
Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs.h
URL:
http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs.h?rev=1476623&r1=1476622&r2=1476623&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs.h (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs.h Sat Apr 27
16:57:10 2013
@@ -344,6 +344,10 @@ typedef struct fs_fs_data_t
is the revision */
svn_cache__t *changes_cache;
+ /* Cache for change_list_t conatiners;
+ the key is a (pack file revision, file offset) pair */
+ svn_cache__t *changes_container_cache;
+
/* Cache for svn_fs_fs__rep_header_t objects; the key is a
(revision, item index) pair */
svn_cache__t *rep_header_cache;