Alien-SVN
view release on metacpan or search on metacpan
src/subversion/subversion/libsvn_fs_fs/fs_fs.c view on Meta::CPAN
SVN_ERR(svn_cache__get((void **) root_id_p, &is_cached,
ffd->rev_root_id_cache, &rev, pool));
if (is_cached)
return SVN_NO_ERROR;
SVN_ERR(open_pack_or_rev_file(&revision_file, fs, rev, pool));
SVN_ERR(get_root_changes_offset(&root_offset, NULL, revision_file, fs, rev,
pool));
SVN_ERR(get_fs_id_at_offset(&root_id, revision_file, fs, rev,
root_offset, pool));
SVN_ERR(svn_io_file_close(revision_file, pool));
SVN_ERR(svn_cache__set(ffd->rev_root_id_cache, &rev, root_id, pool));
*root_id_p = root_id;
return SVN_NO_ERROR;
}
/* Revprop caching management.
*
* Mechanism:
* ----------
*
* Revprop caching needs to be activated and will be deactivated for the
* respective FS instance if the necessary infrastructure could not be
* initialized. In deactivated mode, there is almost no runtime overhead
* associated with revprop caching. As long as no revprops are being read
* or changed, revprop caching imposes no overhead.
*
* When activated, we cache revprops using (revision, generation) pairs
* as keys with the generation being incremented upon every revprop change.
* Since the cache is process-local, the generation needs to be tracked
* for at least as long as the process lives but may be reset afterwards.
*
* To track the revprop generation, we use two-layer approach. On the lower
* level, we use named atomics to have a system-wide consistent value for
* the current revprop generation. However, those named atomics will only
* remain valid for as long as at least one process / thread in the system
* accesses revprops in the respective repository. The underlying shared
* memory gets cleaned up afterwards.
*
* On the second level, we will use a persistent file to track the latest
* revprop generation. It will be written upon each revprop change but
* only be read if we are the first process to initialize the named atomics
* with that value.
*
* The overhead for the second and following accesses to revprops is
* almost zero on most systems.
*
*
* Tech aspects:
* -------------
*
* A problem is that we need to provide a globally available file name to
* back the SHM implementation on OSes that need it. We can only assume
* write access to some file within the respective repositories. Because
* a given server process may access thousands of repositories during its
* lifetime, keeping the SHM data alive for all of them is also not an
* option.
*
* So, we store the new revprop generation on disk as part of each
* setrevprop call, i.e. this write will be serialized and the write order
* be guaranteed by the repository write lock.
*
* The only racy situation occurs when the data is being read again by two
* processes concurrently but in that situation, the first process to
* finish that procedure is guaranteed to be the only one that initializes
* the SHM data. Since even writers will first go through that
* initialization phase, they will never operate on stale data.
*/
/* Read revprop generation as stored on disk for repository FS. The result
* is returned in *CURRENT. Default to 2 if no such file is available.
*/
static svn_error_t *
read_revprop_generation_file(apr_int64_t *current,
svn_fs_t *fs,
apr_pool_t *pool)
{
svn_error_t *err;
apr_file_t *file;
char buf[80];
apr_size_t len;
const char *path = path_revprop_generation(fs, pool);
err = svn_io_file_open(&file, path,
APR_READ | APR_BUFFERED,
APR_OS_DEFAULT, pool);
if (err && APR_STATUS_IS_ENOENT(err->apr_err))
{
svn_error_clear(err);
*current = 2;
return SVN_NO_ERROR;
}
SVN_ERR(err);
len = sizeof(buf);
SVN_ERR(svn_io_read_length_line(file, buf, &len, pool));
/* Check that the first line contains only digits. */
SVN_ERR(check_file_buffer_numeric(buf, 0, path,
"Revprop Generation", pool));
SVN_ERR(svn_cstring_atoi64(current, buf));
return svn_io_file_close(file, pool);
}
/* Write the CURRENT revprop generation to disk for repository FS.
*/
static svn_error_t *
write_revprop_generation_file(svn_fs_t *fs,
apr_int64_t current,
apr_pool_t *pool)
{
apr_file_t *file;
const char *tmp_path;
( run in 0.808 second using v1.01-cache-2.11-cpan-df04353d9ac )