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 )