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 2014/04/11 06:44:50 UTC
svn commit: r1586571 -
/subversion/branches/thunder/subversion/libsvn_fs_fs/cached_data.c
Author: stefan2
Date: Fri Apr 11 04:44:49 2014
New Revision: 1586571
URL: http://svn.apache.org/r1586571
Log:
On the thunder branch: Make our block_read feature THUNDER-aware.
Since this is a generic reader, we can't use our cache wrapper
functions here.
* subversion/libsvn_fs_fs/cached_data.c
(block_read): Callers need to provide the item type such that
we may retry the cache lookup later.
(get_node_revision_body,
create_rep_state_body,
read_delta_window,
svn_fs_fs__get_changes): Provide the extra parameter.
(block_read): Coordinate the data access with the THUNDER registry
and manually retry the cache-lookup.
Modified:
subversion/branches/thunder/subversion/libsvn_fs_fs/cached_data.c
Modified: subversion/branches/thunder/subversion/libsvn_fs_fs/cached_data.c
URL: http://svn.apache.org/viewvc/subversion/branches/thunder/subversion/libsvn_fs_fs/cached_data.c?rev=1586571&r1=1586570&r2=1586571&view=diff
==============================================================================
--- subversion/branches/thunder/subversion/libsvn_fs_fs/cached_data.c (original)
+++ subversion/branches/thunder/subversion/libsvn_fs_fs/cached_data.c Fri Apr 11 04:44:49 2014
@@ -52,6 +52,7 @@ block_read(void **result,
svn_fs_t *fs,
svn_revnum_t revision,
apr_uint64_t item_index,
+ int item_type,
svn_fs_fs__revision_file_t *revision_file,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
@@ -352,6 +353,7 @@ get_node_revision_body(node_revision_t *
SVN_ERR(block_read((void **)noderev_p, fs,
rev_item->revision,
rev_item->number,
+ SVN_FS_FS__ITEM_TYPE_NODEREV,
revision_file,
pool,
pool));
@@ -810,6 +812,7 @@ create_rep_state_body(rep_state_t **rep_
{
if (svn_fs_fs__use_log_addressing(fs, rep->revision))
SVN_ERR(block_read(NULL, fs, rep->revision, rep->item_index,
+ SVN_FS_FS__ITEM_TYPE_UNUSED,
rs->sfile->rfile, pool, pool));
else
if (ffd->rep_header_cache)
@@ -1431,6 +1434,7 @@ read_delta_window(svn_txdelta_window_t *
&& rs->raw_window_cache)
{
SVN_ERR(block_read(NULL, rs->sfile->fs, rs->revision, rs->item_index,
+ SVN_FS_FS__ITEM_TYPE_UNUSED,
rs->sfile->rfile, pool, pool));
/* reading the whole block probably also provided us with the
@@ -2471,6 +2475,7 @@ svn_fs_fs__get_changes(apr_array_header_
/* 'block-read' will also provide us with the desired data */
SVN_ERR(block_read((void **)changes, fs,
rev, SVN_FS_FS__ITEM_INDEX_CHANGES,
+ SVN_FS_FS__ITEM_TYPE_CHANGES,
revision_file, pool, pool));
}
else
@@ -2916,11 +2921,11 @@ block_read_noderev(node_revision_t **nod
return SVN_NO_ERROR;
}
-/* Read the whole (e.g. 64kB) block containing ITEM_INDEX of REVISION in FS
- * and put all data into cache. If necessary and depending on heuristics,
- * neighboring blocks may also get read. The data is being read from
- * already open REVISION_FILE, which must be the correct rev / pack file
- * w.r.t. REVISION.
+/* Read the whole (e.g. 64kB) block containing ITEM_INDEX of REVISION and
+ * type ITEM_TYPE in FS and put all data into cache. If necessary and
+ * depending on heuristics, neighboring blocks may also get read. The data
+ * is being read from already open REVISION_FILE, which must be the correct
+ * rev / pack file w.r.t. REVISION.
*
* For noderevs and changed path lists, the item fetched can be allocated
* RESULT_POOL and returned in *RESULT. Otherwise, RESULT must be NULL.
@@ -2930,6 +2935,7 @@ block_read(void **result,
svn_fs_t *fs,
svn_revnum_t revision,
apr_uint64_t item_index,
+ int item_type,
svn_fs_fs__revision_file_t *revision_file,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
@@ -2944,7 +2950,7 @@ block_read(void **result,
/* don't try this on transaction protorev files */
SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(revision));
-
+
/* index lookup: find the OFFSET of the item we *must* read plus (in the
* "do-while" block) the list of items in the same block. */
SVN_ERR(svn_fs_fs__item_offset(&wanted_offset, fs, revision_file,
@@ -2963,9 +2969,64 @@ block_read(void **result,
do
{
svn_error_t *err;
+ svn_fs__thunder_access_t *access;
+ const char *filename;
- /* fetch list of items in the block surrounding OFFSET */
+ /* Begin coordinated thunder-aware access. */
block_start = offset - (offset % ffd->block_size);
+ SVN_ERR(svn_io_file_name_get(&filename, revision_file->file,
+ scratch_pool));
+ SVN_ERR(svn_fs__thunder_begin_access(&access, svn_fs_fs__get_thunder(),
+ filename, block_start,
+ scratch_pool));
+
+ /* If we did not get the access token, retry the cache access if we
+ * need to data at all. */
+ if (!access)
+ {
+ pair_cache_key_t key = { 0 };
+ svn_boolean_t found = FALSE;
+
+ /* We don't actually need to return data, just exit. */
+ if (!result)
+ break;
+
+ /* Retry cache lookup only on the first pass. Otherwise, we might
+ overwrite data explicitly read in the first iteration if its
+ not in cache anymore. */
+ if (run_count == 0)
+ {
+ key.revision = revision;
+ key.second = item_index;
+
+ switch (item_type)
+ {
+ case SVN_FS_FS__ITEM_TYPE_NODEREV:
+ if (ffd->node_revision_cache)
+ SVN_ERR(svn_cache__get(result, &found,
+ ffd->node_revision_cache,
+ &key, result_pool));
+ break;
+
+ case SVN_FS_FS__ITEM_TYPE_CHANGES:
+ if (ffd->changes_cache)
+ SVN_ERR(svn_cache__get(result, &found,
+ ffd->changes_cache,
+ &key, result_pool));
+ break;
+
+ default:
+ found = FALSE;
+ break;
+ }
+ }
+
+ /* If the data has been found in cache, we are done. */
+ if (found)
+ break;
+ }
+
+ /* fetch list of items in the block surrounding OFFSET */
err = svn_fs_fs__p2l_index_lookup(&entries, fs, revision_file,
revision, block_start,
ffd->block_size, scratch_pool);
@@ -2974,6 +3035,10 @@ block_read(void **result,
* to actually read some item, we retry the whole process */
if (err)
{
+ /* Abort the current attempt at accessing data.
+ * We will retry in the recursive call. */
+ SVN_ERR(svn_fs__thunder_end_access(access));
+
/* We failed for the first time. Refresh cache & retry. */
SVN_ERR(svn_fs_fs__update_min_unpacked_rev(fs, scratch_pool));
if ( revision_file->is_packed
@@ -2984,7 +3049,7 @@ block_read(void **result,
SVN_ERR(svn_fs_fs__reopen_revision_file(revision_file, fs,
revision));
SVN_ERR(block_read(result, fs, revision, item_index,
- revision_file, result_pool,
+ item_type, revision_file, result_pool,
scratch_pool));
}
@@ -3069,6 +3134,8 @@ block_read(void **result,
}
}
+ /* We sync for the first block only and that has been read now. */
+ SVN_ERR(svn_fs__thunder_end_access(access));
}
while(run_count++ == 1); /* can only be true once and only if a block
* boundary got crossed */