FreeBSD/contrib/subversion/subversion/libsvn_fs_fs/index.c
/* If it cannot be found in FS's caches, read the p2l index page selected
 * by BATON->OFFSET from REV_FILE.  Don't read the page if it precedes
 * MIN_OFFSET.  Set *END to TRUE if the caller should stop refeching.
 *
 * *BATON will be updated with the selected page's info and SCRATCH_POOL
 * will be used for temporary allocations.  If the data is alread in the
 * cache, descrease *LEAKING_BUCKET and increase it otherwise.  With that
 * pattern we will still read all pages from the block even if some of
 * them survived in the cached.
 */
If it cannot be found in FS's caches, read the p2l index page selected
by BATON->OFFSET from REV_FILE.  Don't read the page if it precedes
MIN_OFFSET.  Set *END to TRUE if the caller should stop refeching.

*BATON will be updated with the selected page's info and SCRATCH_POOL
will be used for temporary allocations.  If the data is alread in the
cache, descrease *LEAKING_BUCKET and increase it otherwise.  With that
pattern we will still read all pages from the block even if some of
them survived in the cached.
If it cannot be found in FS ' s caches read the p2l index page selected by BATON - > OFFSET from REV_FILE . Don ' t read the page if it precedes MIN_OFFSET . Set * END to TRUE if the caller should stop refeching . * BATON will be updated with the selected page ' s info and SCRATCH_POOL will be used for temporary allocations . If the data is alread in the cache descrease * LEAKING_BUCKET and increase it otherwise . With that pattern we will still read all pages from the block even if some of them survived in the cached .
static svn_error_t *
prefetch_p2l_page(svn_boolean_t *end,
                  int *leaking_bucket,
                  svn_fs_t *fs,
                  svn_fs_fs__revision_file_t *rev_file,
                  p2l_page_info_baton_t *baton,
                  apr_off_t min_offset,
                  apr_pool_t *scratch_pool)
{
  fs_fs_data_t *ffd = fs->fsap_data;
  svn_boolean_t already_cached;
  apr_array_header_t *page;
  svn_fs_fs__page_cache_key_t key = { 0 };
  *end = FALSE;
  baton->revision = baton->first_revision;
  SVN_ERR(get_p2l_page_info(baton, rev_file, fs, scratch_pool));
  if (baton->start_offset < min_offset || !rev_file->p2l_stream)
    {
      *end = TRUE;
      return SVN_NO_ERROR;
    }
  assert(baton->first_revision <= APR_UINT32_MAX);
  key.revision = (apr_uint32_t)baton->first_revision;
  key.is_packed = svn_fs_fs__is_packed_rev(fs, baton->first_revision);
  key.page = baton->page_no;
  SVN_ERR(svn_cache__has_key(&already_cached, ffd->p2l_page_cache,
                             &key, scratch_pool));
  if (already_cached)
    {
      if (!--*leaking_bucket)
        *end = TRUE;
      return SVN_NO_ERROR;
    }
  ++*leaking_bucket;
  SVN_ERR(get_p2l_page(&page, rev_file, fs,
                       baton->first_revision,
                       baton->start_offset,
                       baton->next_offset,
                       baton->page_start,
                       baton->page_size,
                       scratch_pool));
  SVN_ERR(svn_cache__set(ffd->p2l_page_cache, &key, page, scratch_pool));
  return SVN_NO_ERROR;
}
static svn_error_t * prefetch_p2l_page ( svn_boolean_t * end , int * leaking_bucket , svn_fs_t * fs , svn_fs_fs__revision_file_t * rev_file , p2l_page_info_baton_t * baton , apr_off_t min_offset , apr_pool_t * scratch_pool ) { fs_fs_data_t * ffd = fs -> fsap_data ; svn_boolean_t already_cached ; apr_array_header_t * page ; svn_fs_fs__page_cache_key_t key = { 0 } ; * end = FALSE ; baton -> revision = baton -> first_revision ; SVN_ERR ( get_p2l_page_info ( baton , rev_file , fs , scratch_pool ) ) ; if ( baton -> start_offset < min_offset || ! rev_file -> p2l_stream ) { * end = TRUE ; return SVN_NO_ERROR ; } assert ( baton -> first_revision <= APR_UINT32_MAX ) ; key . revision = ( apr_uint32_t ) baton -> first_revision ; key . is_packed = svn_fs_fs__is_packed_rev ( fs , baton -> first_revision ) ; key . page = baton -> page_no ; SVN_ERR ( svn_cache__has_key ( & already_cached , ffd -> p2l_page_cache , & key , scratch_pool ) ) ; if ( already_cached ) { if ( ! -- * leaking_bucket ) * end = TRUE ; return SVN_NO_ERROR ; } ++ * leaking_bucket ; SVN_ERR ( get_p2l_page ( & page , rev_file , fs , baton -> first_revision , baton -> start_offset , baton -> next_offset , baton -> page_start , baton -> page_size , scratch_pool ) ) ; SVN_ERR ( svn_cache__set ( ffd -> p2l_page_cache , & key , page , scratch_pool ) ) ; return SVN_NO_ERROR ; }
If it cannot be found in FS's caches, read the p2l index page selected
 by BATON->OFFSET from REV_FILE.
If it cannot be found in FS ' s caches read the p2l index page selected by BATON - > OFFSET from REV_FILE .
/* fetch the page info */ /* page outside limits -> stop prefetching */ /* do we have that page in our caches already? */ /* yes, already cached */ /* stop prefetching if most pages are already cached. */ /* read from disk */ /* and put it into our cache */