Author: stefan2
Date: Sat Apr 27 19:39:47 2013
New Revision: 1476660

URL: http://svn.apache.org/r1476660
Log:
On the fsfs-format7 branch:  add P2L index access functions that allow
for returning single entries or even sub-items instead of whole page
descriptions.  This will be needed by the new index verification code
in fs_verify.

* subversion/libsvn_fs_fs/index.h
  (svn_fs_fs__p2l_entry_lookup,
   svn_fs_fs__p2l_item_lookup,
   svn_fs_fs__p2l_get_max_offset): declare new P2L index APIs

* subversion/libsvn_fs_fs/index.c
  (get_p2l_header): factored out from get_p2l_page_info
  (get_p2l_page_info): remainder adding cache access code
  (get_p2l_keys): new utility
  (p2l_index_lookup): factored out from svn_fs_fs__p2l_index_lookup
  (svn_fs_fs__p2l_index_lookup): remainder

  (compare_p2l_entry_offsets,
   get_p2l_entry_from_cached_page,
   p2l_entry_lookup_func): new partial cache access functions
  (p2l_entry_lookup): body of ...
  (svn_fs_fs__p2l_entry_lookup): ... this new API function

  (p2l_item_lookup_baton_t): new cache access baton type
  (p2l_item_lookup_func):  new partial cache access function
  (svn_fs_fs__p2l_item_lookup): implement new API function

  (p2l_get_max_offset_func): new partial cache access function
  (svn_fs_fs__p2l_get_max_offset): implement new API function

Modified:
    subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/index.c
    subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/index.h

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/index.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/index.c?rev=1476660&r1=1476659&r2=1476660&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/index.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/index.c Sat Apr 27 
19:39:47 2013
@@ -1926,20 +1926,20 @@ p2l_page_info_func(void **out,
   return SVN_NO_ERROR;
 }
 
-/* Read the header data structure of the phys-to-log index for revision
- * BATON->REVISION in FS.  Return in *BATON all info relevant to read the
- * index page for the rev / pack file offset BATON->OFFSET.
+/* Read the header data structure of the phys-to-log index for REVISION in
+ * FS and return it in *HEADER. 
  * 
  * To maximize efficiency, use or return the data stream in *STREAM.
  * If *STREAM is yet to be constructed, do so in STREAM_POOL.
  * Use POOL for allocations.
  */
 static svn_error_t *
-get_p2l_page_info(p2l_page_info_baton_t *baton,
-                  packed_number_stream_t **stream,
-                  svn_fs_t *fs,
-                  apr_pool_t *stream_pool,
-                  apr_pool_t *pool)
+get_p2l_header(p2l_header_t **header,
+               packed_number_stream_t **stream,
+               svn_fs_t *fs,
+               svn_revnum_t revision,
+               apr_pool_t *stream_pool,
+               apr_pool_t *pool)
 {
   fs_fs_data_t *ffd = fs->fsap_data;
   apr_uint64_t value;
@@ -1947,15 +1947,14 @@ get_p2l_page_info(p2l_page_info_baton_t 
   apr_off_t offset;
   p2l_header_t *result;
   svn_boolean_t is_cached = FALSE;
-  void *dummy = NULL;
 
   /* look for the header data in our cache */
   pair_cache_key_t key;
-  key.revision = base_revision(fs, baton->revision);
-  key.second = is_packed_rev(fs, baton->revision);
+  key.revision = base_revision(fs, revision);
+  key.second = is_packed_rev(fs, revision);
 
-  SVN_ERR(svn_cache__get_partial(&dummy, &is_cached, ffd->p2l_header_cache,
-                                 &key, p2l_page_info_func, baton, pool));
+  SVN_ERR(svn_cache__get((void**)header, &is_cached, ffd->p2l_header_cache,
+                         &key, pool));
   if (is_cached)
     return SVN_NO_ERROR;
 
@@ -1963,7 +1962,7 @@ get_p2l_page_info(p2l_page_info_baton_t 
    * Open index file or position read pointer to the begin of the file */
   if (*stream == NULL)
     SVN_ERR(packed_stream_open(stream,
-                               path_p2l_index(fs, baton->revision, pool),
+                               path_p2l_index(fs, key.revision, pool),
                                ffd->block_size, stream_pool));
   else
     packed_stream_seek(*stream, 0);
@@ -1994,12 +1993,51 @@ get_p2l_page_info(p2l_page_info_baton_t 
   for (i = 0; i <= result->page_count; ++i)
     result->offsets[i] += offset;
 
-  /* copy the requested info into *BATON */
-  p2l_page_info_copy(baton, result, result->offsets);
-
   /* cache the header data */
   SVN_ERR(svn_cache__set(ffd->p2l_header_cache, &key, result, pool));
 
+  /* return the result */
+  *header = result;
+
+  return SVN_NO_ERROR;
+}
+
+/* Read the header data structure of the phys-to-log index for revision
+ * BATON->REVISION in FS.  Return in *BATON all info relevant to read the
+ * index page for the rev / pack file offset BATON->OFFSET.
+ * 
+ * To maximize efficiency, use or return the data stream in *STREAM.
+ * If *STREAM is yet to be constructed, do so in STREAM_POOL.
+ * Use POOL for allocations.
+ */
+static svn_error_t *
+get_p2l_page_info(p2l_page_info_baton_t *baton,
+                  packed_number_stream_t **stream,
+                  svn_fs_t *fs,
+                  apr_pool_t *stream_pool,
+                  apr_pool_t *pool)
+{
+  fs_fs_data_t *ffd = fs->fsap_data;
+  p2l_header_t *header;
+  svn_boolean_t is_cached = FALSE;
+  void *dummy = NULL;
+
+  /* look for the header data in our cache */
+  pair_cache_key_t key;
+  key.revision = base_revision(fs, baton->revision);
+  key.second = is_packed_rev(fs, baton->revision);
+
+  SVN_ERR(svn_cache__get_partial(&dummy, &is_cached, ffd->p2l_header_cache,
+                                 &key, p2l_page_info_func, baton, pool));
+  if (is_cached)
+    return SVN_NO_ERROR;
+
+  SVN_ERR(get_p2l_header(&header, stream, fs, baton->revision,
+                         stream_pool, pool));
+
+  /* copy the requested info into *BATON */
+  p2l_page_info_copy(baton, header, header->offsets);
+
   return SVN_NO_ERROR;
 }
 
@@ -2192,46 +2230,80 @@ prefetch_p2l_page(svn_boolean_t *end,
   return SVN_NO_ERROR;
 }
 
-svn_error_t *
-svn_fs_fs__p2l_index_lookup(apr_array_header_t **entries,
-                            svn_fs_t *fs,
-                            svn_revnum_t revision,
-                            apr_off_t offset,
-                            apr_pool_t *pool)
+/* Lookup & construct the baton and key information that we will need for
+ * a P2L page cache lookup.  We want the page covering OFFSET in the rev /
+ * pack file containing REVSION in FS.  Return the results in *PAGE_INFO_P
+ * and *KEY_P.  Read data through the auto-allocated *STREAM.
+ * Use POOL for allocations.
+ */
+static svn_error_t *
+get_p2l_keys(p2l_page_info_baton_t *page_info_p,
+             svn_fs_fs__page_cache_key_t *key_p,
+             packed_number_stream_t **stream,
+             svn_fs_t *fs,
+             svn_revnum_t revision,
+             apr_off_t offset,
+             apr_pool_t *pool)
 {
-  fs_fs_data_t *ffd = fs->fsap_data;
-  packed_number_stream_t *stream = NULL;
-  svn_fs_fs__page_cache_key_t key = { 0 };
-  svn_boolean_t is_cached = FALSE;
   p2l_page_info_baton_t page_info;
-
+  
   /* request info for the index pages that describes the pack / rev file
    * contents at pack / rev file position OFFSET. */
   page_info.offset = offset;
   page_info.revision = revision;
-  SVN_ERR(get_p2l_page_info(&page_info, &stream, fs, pool, pool));
+  SVN_ERR(get_p2l_page_info(&page_info, stream, fs, pool, pool));
 
   /* if the offset refers to a non-existent page, bail out */
   if (page_info.page_count <= page_info.page_no)
     {
-      SVN_ERR(packed_stream_close(stream));
+      SVN_ERR(packed_stream_close(*stream));
       return svn_error_createf(SVN_ERR_FS_ITEM_INDEX_OVERFLOW , NULL,
                                _("Offset %" APR_OFF_T_FMT
                                  " too large in revision %ld"),
                                offset, revision);
     }
 
-  /* look for this page in our cache */
-  key.revision = page_info.first_revision;
-  key.is_packed = is_packed_rev(fs, revision);
-  key.page = page_info.page_no;
+  /* return results */
+  if (page_info_p)
+    *page_info_p = page_info;
+  
+  /* construct cache key */
+  if (key_p)
+    {
+      svn_fs_fs__page_cache_key_t key = { 0 };
+      key.revision = page_info.first_revision;
+      key.is_packed = is_packed_rev(fs, revision);
+      key.page = page_info.page_no;
 
+      *key_p = key;  
+    }
+
+  return SVN_NO_ERROR;
+}
+
+/* Body of svn_fs_fs__p2l_index_lookup.  Use / autoconstruct *STREAM as
+ * your input based on REVISION.
+ */
+svn_error_t *
+p2l_index_lookup(apr_array_header_t **entries,
+                 packed_number_stream_t **stream,
+                 svn_fs_t *fs,
+                 svn_revnum_t revision,
+                 apr_off_t offset,
+                 apr_pool_t *pool)
+{
+  fs_fs_data_t *ffd = fs->fsap_data;
+  svn_fs_fs__page_cache_key_t key;
+  svn_boolean_t is_cached = FALSE;
+  p2l_page_info_baton_t page_info;
+
+  /* look for this page in our cache */
+  SVN_ERR(get_p2l_keys(&page_info, &key, stream, fs, revision, offset,
+                       pool));
   SVN_ERR(svn_cache__get((void**)entries, &is_cached, ffd->p2l_page_cache,
                          &key, pool));
   if (!is_cached)
     {
-      apr_off_t max_offset = APR_ALIGN(page_info.next_offset, ffd->block_size);
-      apr_off_t min_offset = max_offset - ffd->block_size;
       svn_boolean_t end;
       apr_pool_t *iterpool = svn_pool_create(pool);
       apr_off_t original_page_start = page_info.page_start;
@@ -2254,14 +2326,14 @@ svn_fs_fs__p2l_index_lookup(apr_array_he
       while (prefetch_info.offset >= prefetch_info.page_size && !end)
         {
           prefetch_info.offset -= prefetch_info.page_size;
-          SVN_ERR(prefetch_p2l_page(&end, &leaking_bucket, fs, &stream,
+          SVN_ERR(prefetch_p2l_page(&end, &leaking_bucket, fs, stream,
                                     &prefetch_info, min_offset,
                                     pool, iterpool));
           svn_pool_clear(iterpool);
         }
 
       /* fetch page from disk and put it into the cache */
-      SVN_ERR(get_p2l_page(entries, &stream, fs,
+      SVN_ERR(get_p2l_page(entries, stream, fs,
                            page_info.first_revision,
                            page_info.start_offset,
                            page_info.next_offset,
@@ -2280,7 +2352,7 @@ svn_fs_fs__p2l_index_lookup(apr_array_he
              && !end)
         {
           prefetch_info.offset += prefetch_info.page_size;
-          SVN_ERR(prefetch_p2l_page(&end, &leaking_bucket, fs, &stream,
+          SVN_ERR(prefetch_p2l_page(&end, &leaking_bucket, fs, stream,
                                     &prefetch_info, min_offset,
                                     pool, iterpool));
           svn_pool_clear(iterpool);
@@ -2289,12 +2361,297 @@ svn_fs_fs__p2l_index_lookup(apr_array_he
       svn_pool_destroy(iterpool);
     }
 
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_fs_fs__p2l_index_lookup(apr_array_header_t **entries,
+                            svn_fs_t *fs,
+                            svn_revnum_t revision,
+                            apr_off_t offset,
+                            apr_pool_t *pool)
+{
+  packed_number_stream_t *stream = NULL;
+
+  /* look for this page in our cache */
+  SVN_ERR(p2l_index_lookup(entries, &stream, fs, revision, offset, pool));
+
+  /* make sure we close files after usage */
+  SVN_ERR(packed_stream_close(stream));
+
+  return SVN_NO_ERROR;
+}
+
+/* compare_fn_t comparing a svn_fs_fs__p2l_entry_t at LHS with an offset
+ * RHS.
+ */
+static int
+compare_p2l_entry_offsets(const void *lhs, const void *rhs)
+{
+  const svn_fs_fs__p2l_entry_t *entry = (const svn_fs_fs__p2l_entry_t *)lhs;
+  apr_off_t offset = *(const apr_off_t *)rhs;
+
+  return entry->offset < offset ? -1 : (entry->offset == offset ? 0 : 1);
+}
+
+/* Cached data extraction utility.  DATA is a P2L index page, e.g. an APR
+ * array of svn_fs_fs__p2l_entry_t elements.  Return the entry for the item
+ * starting at OFFSET or NULL if that's not an the start offset of any item.
+ */
+static svn_fs_fs__p2l_entry_t *
+get_p2l_entry_from_cached_page(const void *data,
+                               apr_off_t offset,
+                               apr_pool_t *pool)
+{
+  /* resolve all pointer values of in-cache data */
+  const apr_array_header_t *page = data;
+  apr_array_header_t *entries = apr_pmemdup(pool, page, sizeof(*page));
+  int idx;
+
+  entries->elts = (char *)svn_temp_deserializer__ptr(page,
+                                     (const void *const *)&page->elts);
+
+  /* search of the offset we want */
+  idx = svn_sort__bsearch_lower_bound(&offset, entries,
+      (int (*)(const void *, const void *))compare_p2l_entry_offsets);
+
+  /* return it, if it is a perfect match */
+  if (idx < entries->nelts)
+    {
+      svn_fs_fs__p2l_entry_t *entry
+        = &APR_ARRAY_IDX(entries, idx, svn_fs_fs__p2l_entry_t);
+      if (entry->offset == offset)
+        {
+          svn_fs_fs__p2l_entry_t *result
+            = apr_pmemdup(pool, entry, sizeof(*result));
+          result->items
+            = (svn_fs_fs__id_part_t *)svn_temp_deserializer__ptr(entries->elts,
+                                     (const void *const *)&entry->items);
+          return result;
+        }
+    }
+
+  return NULL;
+}
+
+/* Implements svn_cache__partial_getter_func_t for P2L index pages, copying
+ * the entry for the apr_off_t at BATON into *OUT.  *OUT will be NULL if
+ * there is no matching entry in the index page at DATA.
+ */
+static svn_error_t *
+p2l_entry_lookup_func(void **out,
+                      const void *data,
+                      apr_size_t data_len,
+                      void *baton,
+                      apr_pool_t *result_pool)
+{
+  svn_fs_fs__p2l_entry_t *entry
+    = get_p2l_entry_from_cached_page(data, *(apr_off_t *)baton, result_pool);
+
+  *out = entry && entry->offset == *(apr_off_t *)baton
+       ? svn_fs_fs__p2l_entry_dup(entry, result_pool)
+       : NULL;
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+p2l_entry_lookup(svn_fs_fs__p2l_entry_t **entry_p,
+                 packed_number_stream_t **stream,
+                 svn_fs_t *fs,
+                 svn_revnum_t revision,
+                 apr_off_t offset,
+                 apr_pool_t *pool)
+{
+  fs_fs_data_t *ffd = fs->fsap_data;
+  svn_fs_fs__page_cache_key_t key = { 0 };
+  svn_boolean_t is_cached = FALSE;
+  p2l_page_info_baton_t page_info;
+
+  *entry_p = NULL;
+
+  /* look for this info in our cache */
+  SVN_ERR(get_p2l_keys(&page_info, &key, stream, fs, revision, offset, pool));
+  SVN_ERR(svn_cache__get_partial((void**)entry_p, &is_cached,
+                                 ffd->p2l_page_cache, &key,
+                                 p2l_entry_lookup_func, &offset, pool));
+  if (!is_cached)
+    {
+      int idx;
+
+      /* do a standard index lookup.  This is will automatically prefetch
+       * data to speed up future lookups. */
+      apr_array_header_t *entries;
+      SVN_ERR(p2l_index_lookup(&entries, stream, fs, revision, offset, pool));
+
+      /* Find the entry that we want. */
+      idx = svn_sort__bsearch_lower_bound(&offset, entries, 
+          (int (*)(const void *, const void *))compare_p2l_entry_offsets);
+
+      /* return it, if it is a perfect match */
+      if (idx < entries->nelts)
+        {
+          svn_fs_fs__p2l_entry_t *entry
+            = &APR_ARRAY_IDX(entries, idx, svn_fs_fs__p2l_entry_t);
+          if (entry->offset == offset)
+            *entry_p = entry;
+        }
+    }
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_fs_fs__p2l_entry_lookup(svn_fs_fs__p2l_entry_t **entry_p,
+                            svn_fs_t *fs,
+                            svn_revnum_t revision,
+                            apr_off_t offset,
+                            apr_pool_t *pool)
+{
+  packed_number_stream_t *stream = NULL;
+
+  /* look for this info in our cache */
+  SVN_ERR(p2l_entry_lookup(entry_p, &stream, fs, revision, offset, pool));
+
+  /* make sure we close files after usage */
+  SVN_ERR(packed_stream_close(stream));
+
+  return SVN_NO_ERROR;
+}
+
+/* Baton structure for p2l_item_lookup_func.  It describes which sub_item
+ * info shall be returned.
+ */
+typedef struct p2l_item_lookup_baton_t
+{
+  /* file offset to find the P2L index entry for */
+  apr_off_t offset;
+
+  /* return the sub-item at this position within that entry */
+  apr_uint32_t sub_item;
+} p2l_item_lookup_baton_t;
+
+/* Implements svn_cache__partial_getter_func_t for P2L index pages, copying
+ * the svn_fs_fs__id_part_t for the item described 2l_item_lookup_baton_t
+ * *BATON.  *OUT will be NULL if there is no matching index entry or the
+ * sub-item is out of range.
+ */
+static svn_error_t *
+p2l_item_lookup_func(void **out,
+                     const void *data,
+                     apr_size_t data_len,
+                     void *baton,
+                     apr_pool_t *result_pool)
+{
+  p2l_item_lookup_baton_t *lookup_baton = baton;
+  svn_fs_fs__p2l_entry_t *entry
+    = get_p2l_entry_from_cached_page(data, lookup_baton->offset, result_pool);
+
+  *out =    entry
+         && entry->offset == lookup_baton->offset
+         && entry->item_count > lookup_baton->sub_item
+       ? apr_pmemdup(result_pool,
+                     entry->items + lookup_baton->sub_item,
+                     sizeof(*entry->items))
+       : NULL;
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_fs_fs__p2l_item_lookup(svn_fs_fs__id_part_t **item,
+                           svn_fs_t *fs,
+                           svn_revnum_t revision,
+                           apr_off_t offset,
+                           apr_uint32_t sub_item,
+                           apr_pool_t *pool)
+{
+  fs_fs_data_t *ffd = fs->fsap_data;
+  packed_number_stream_t *stream = NULL;
+  svn_fs_fs__page_cache_key_t key = { 0 };
+  svn_boolean_t is_cached = FALSE;
+  p2l_page_info_baton_t page_info;
+  p2l_item_lookup_baton_t baton;
+
+  *item = NULL;
+
+  /* look for this info in our cache */
+  SVN_ERR(get_p2l_keys(&page_info, &key, &stream, fs, revision, offset,
+                       pool));
+  baton.offset = offset;
+  baton.sub_item = sub_item;
+  SVN_ERR(svn_cache__get_partial((void**)item, &is_cached,
+                                 ffd->p2l_page_cache, &key,
+                                 p2l_item_lookup_func, &baton, pool));
+  if (!is_cached)
+    {
+      /* do a standard index lookup.  This is will automatically prefetch
+       * data to speed up future lookups. */
+      svn_fs_fs__p2l_entry_t *entry;
+      SVN_ERR(p2l_entry_lookup(&entry, &stream, fs, revision, offset, pool));
+
+      /* return result */
+      if (entry && entry->item_count > sub_item)
+        *item = apr_pmemdup(pool, entry->items + sub_item, sizeof(**item));
+    }
+
   /* make sure we close files after usage */
   SVN_ERR(packed_stream_close(stream));
 
   return SVN_NO_ERROR;
 }
 
+/* Implements svn_cache__partial_getter_func_t for P2L headers, setting *OUT
+ * to the largest the first offset not covered by this P2L index.
+ */
+static svn_error_t *
+p2l_get_max_offset_func(void **out,
+                        const void *data,
+                        apr_size_t data_len,
+                        void *baton,
+                        apr_pool_t *result_pool)
+{
+  const p2l_header_t *header = data;
+  apr_off_t max_offset = header->page_size * header->page_count;
+  *out = apr_pmemdup(result_pool, &max_offset, sizeof(max_offset));
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_fs_fs__p2l_get_max_offset(apr_off_t *offset,
+                              svn_fs_t *fs,
+                              svn_revnum_t revision,
+                              apr_pool_t *pool)
+{
+  fs_fs_data_t *ffd = fs->fsap_data;
+  packed_number_stream_t *stream = NULL;
+  p2l_header_t *header;
+  svn_boolean_t is_cached = FALSE;
+  apr_off_t *offset_p;
+
+  /* look for the header data in our cache */
+  pair_cache_key_t key;
+  key.revision = base_revision(fs, revision);
+  key.second = is_packed_rev(fs, revision);
+
+  SVN_ERR(svn_cache__get_partial((void **)&offset_p, &is_cached,
+                                 ffd->p2l_header_cache, &key,
+                                 p2l_get_max_offset_func, NULL, pool));
+  if (is_cached)
+    {
+      *offset = *offset_p;
+      return SVN_NO_ERROR;
+    }
+
+  SVN_ERR(get_p2l_header(&header, &stream, fs, revision, pool, pool));
+  *offset = header->page_count * header->page_size;
+  
+  /* make sure we close files after usage */
+  SVN_ERR(packed_stream_close(stream));
+
+  return SVN_NO_ERROR;
+}
 
 svn_error_t *
 svn_fs_fs__item_offset(apr_off_t *offset,

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/index.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/index.h?rev=1476660&r1=1476659&r2=1476660&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/index.h (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/index.h Sat Apr 27 
19:39:47 2013
@@ -172,6 +172,32 @@ svn_fs_fs__p2l_index_lookup(apr_array_he
                             apr_off_t offset,
                             apr_pool_t *pool);
 
+/* Use the phys-to-log mapping files in FS to return the entry for the
+ * container or single item starting at global OFFSET in the rep file
+ * containing REVISION in *ENTRY.  Sets *ENTRY to NULL if no item starts
+ * at exactly that offset.  Use POOL for allocations.
+ */
+svn_error_t *
+svn_fs_fs__p2l_entry_lookup(svn_fs_fs__p2l_entry_t **entry,
+                            svn_fs_t *fs,
+                            svn_revnum_t revision,
+                            apr_off_t offset,
+                            apr_pool_t *pool);
+
+/* Use the phys-to-log mapping files in FS to return the svn_fs_fs__id_part_t
+ * for the SUB_ITEM of the container starting at global OFFSET in the rep /
+ * pack file containing REVISION in *ITEM.  Sets *ITEM to NULL if no element
+ * starts at exactly that offset or if it contains no more than SUB_ITEM
+ * sub-items.  Use POOL for allocations.
+ */
+svn_error_t *
+svn_fs_fs__p2l_item_lookup(svn_fs_fs__id_part_t **item,
+                           svn_fs_t *fs,
+                           svn_revnum_t revision,
+                           apr_off_t offset,
+                           apr_uint32_t sub_item,
+                           apr_pool_t *pool);
+
 /* Use the log-to-phys mapping files in FS to find the packed / non-packed /
  * proto-rev file offset and container sub-item of either (REVISION,
  * ITEM_INDEX) or (TXN_ID, ITEM_INDEX).  *SUB_ITEM will be 0 for non-
@@ -201,6 +227,10 @@ svn_fs_fs__l2p_get_max_ids(apr_array_hea
                            apr_size_t count,
                            apr_pool_t *pool);
 
+/* In *OFFSET, return the first OFFSET in the pack / rev file containing
+ * REVISION in FS not covered by the log-to-phys index.
+ * Use POOL for allocations.
+ */
 svn_error_t *
 svn_fs_fs__p2l_get_max_offset(apr_off_t *offset,
                               svn_fs_t *fs,


Reply via email to