FreeBSD/contrib/subversion/subversion/libsvn_fs_fs/index.c
/* Utility function.  Read the l2p index pages for REVISION in FS from
 * REV_FILE and put them into the cache.  Skip page number EXLCUDED_PAGE_NO
 * (use -1 for 'skip none') and pages outside the MIN_OFFSET, MAX_OFFSET
 * range in the l2p index file.  The index is being identified by
 * FIRST_REVISION.  PAGES is a scratch container provided by the caller.
 * SCRATCH_POOL is used for temporary allocations.
 *
 * This function may be a no-op if the header cache lookup fails / misses.
 */
Utility function.  Read the l2p index pages for REVISION in FS from
REV_FILE and put them into the cache.  Skip page number EXLCUDED_PAGE_NO
(use -1 for 'skip none') and pages outside the MIN_OFFSET, MAX_OFFSET
range in the l2p index file.  The index is being identified by
FIRST_REVISION.  PAGES is a scratch container provided by the caller.
SCRATCH_POOL is used for temporary allocations.

This function may be a no-op if the header cache lookup fails / misses.
Utility function . Read the l2p index pages for REVISION in FS from REV_FILE and put them into the cache . Skip page number EXLCUDED_PAGE_NO ( use - 1 for ' skip none ' ) and pages outside the MIN_OFFSET MAX_OFFSET range in the l2p index file . The index is being identified by FIRST_REVISION . PAGES is a scratch container provided by the caller . SCRATCH_POOL is used for temporary allocations . This function may be a no - op if the header cache lookup fails / misses .
static svn_error_t *
prefetch_l2p_pages(svn_boolean_t *end,
                   svn_fs_t *fs,
                   svn_fs_fs__revision_file_t *rev_file,
                   svn_revnum_t first_revision,
                   svn_revnum_t revision,
                   apr_array_header_t *pages,
                   int exlcuded_page_no,
                   apr_off_t min_offset,
                   apr_off_t max_offset,
                   apr_pool_t *scratch_pool)
{
  fs_fs_data_t *ffd = fs->fsap_data;
  int i;
  apr_pool_t *iterpool;
  svn_fs_fs__page_cache_key_t key = { 0 };
  if (min_offset < 0)
    min_offset = 0;
  if (max_offset <= 0)
    {
      *end = TRUE;
      return SVN_NO_ERROR;
    }
  *end = FALSE;
  SVN_ERR(get_l2p_page_table(pages, fs, rev_file, revision, scratch_pool));
  if (pages->nelts == 0 || rev_file->l2p_stream == NULL)
    {
      *end = TRUE;
      return SVN_NO_ERROR;
    }
  iterpool = svn_pool_create(scratch_pool);
  assert(revision <= APR_UINT32_MAX);
  key.revision = (apr_uint32_t)revision;
  key.is_packed = rev_file->is_packed;
  for (i = 0; i < pages->nelts && !*end; ++i)
    {
      svn_boolean_t is_cached;
      l2p_page_table_entry_t *entry
        = &APR_ARRAY_IDX(pages, i, l2p_page_table_entry_t);
      svn_pool_clear(iterpool);
      if (i == exlcuded_page_no)
        continue;
      if (   entry->offset < (apr_uint64_t)min_offset
          || entry->offset + entry->size > (apr_uint64_t)max_offset)
        {
          *end = TRUE;
          continue;
        }
      key.page = i;
      SVN_ERR(svn_cache__has_key(&is_cached, ffd->l2p_page_cache,
                                 &key, iterpool));
      if (!is_cached)
        {
          l2p_page_t *page = NULL;
          SVN_ERR(get_l2p_page(&page, rev_file, fs, first_revision, entry,
                               iterpool));
          SVN_ERR(svn_cache__set(ffd->l2p_page_cache, &key, page,
                                 iterpool));
        }
    }
  svn_pool_destroy(iterpool);
  return SVN_NO_ERROR;
}
static svn_error_t * prefetch_l2p_pages ( svn_boolean_t * end , svn_fs_t * fs , svn_fs_fs__revision_file_t * rev_file , svn_revnum_t first_revision , svn_revnum_t revision , apr_array_header_t * pages , int exlcuded_page_no , apr_off_t min_offset , apr_off_t max_offset , apr_pool_t * scratch_pool ) { fs_fs_data_t * ffd = fs -> fsap_data ; int i ; apr_pool_t * iterpool ; svn_fs_fs__page_cache_key_t key = { 0 } ; if ( min_offset < 0 ) min_offset = 0 ; if ( max_offset <= 0 ) { * end = TRUE ; return SVN_NO_ERROR ; } * end = FALSE ; SVN_ERR ( get_l2p_page_table ( pages , fs , rev_file , revision , scratch_pool ) ) ; if ( pages -> nelts == 0 || rev_file -> l2p_stream == NULL ) { * end = TRUE ; return SVN_NO_ERROR ; } iterpool = svn_pool_create ( scratch_pool ) ; assert ( revision <= APR_UINT32_MAX ) ; key . revision = ( apr_uint32_t ) revision ; key . is_packed = rev_file -> is_packed ; for ( i = 0 ; i < pages -> nelts && ! * end ; ++ i ) { svn_boolean_t is_cached ; l2p_page_table_entry_t * entry = & APR_ARRAY_IDX ( pages , i , l2p_page_table_entry_t ) ; svn_pool_clear ( iterpool ) ; if ( i == exlcuded_page_no ) continue ; if ( entry -> offset < ( apr_uint64_t ) min_offset || entry -> offset + entry -> size > ( apr_uint64_t ) max_offset ) { * end = TRUE ; continue ; } key . page = i ; SVN_ERR ( svn_cache__has_key ( & is_cached , ffd -> l2p_page_cache , & key , iterpool ) ) ; if ( ! is_cached ) { l2p_page_t * page = NULL ; SVN_ERR ( get_l2p_page ( & page , rev_file , fs , first_revision , entry , iterpool ) ) ; SVN_ERR ( svn_cache__set ( ffd -> l2p_page_cache , & key , page , iterpool ) ) ; } } svn_pool_destroy ( iterpool ) ; return SVN_NO_ERROR ; }
Utility function.
Utility function .
/* Parameter check. */ /* Nothing to do */ /* get the page table for REVISION from cache */ /* not found -> we can't continue without hitting the disk again */ /* prefetch pages individually until all are done or we found one in
   * the cache */ /* skip pages outside the specified index file range */ /* page already in cache? */ /* no in cache -> read from stream (data already buffered in APR)
           * and cache the result */