/* index.c indexing support for FSFS support
 *
 * ====================================================================
 *    Licensed to the Apache Software Foundation (ASF) under one
 *    or more contributor license agreements.  See the NOTICE file
 *    distributed with this work for additional information
 *    regarding copyright ownership.  The ASF licenses this file
 *    to you under the Apache License, Version 2.0 (the
 *    "License"); you may not use this file except in compliance
 *    with the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing,
 *    software distributed under the License is distributed on an
 *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *    KIND, either express or implied.  See the License for the
 *    specific language governing permissions and limitations
 *    under the License.
 * ====================================================================
 */

#include <assert.h>

#include "svn_io.h"
#include "svn_pools.h"
#include "svn_sorts.h"

#include "svn_private_config.h"

#include "private/svn_sorts_private.h"
#include "private/svn_subr_private.h"
#include "private/svn_temp_serializer.h"

#include "index.h"
#include "pack.h"
#include "temp_serializer.h"
#include "util.h"
#include "fs_fs.h"

#include "../libsvn_fs/fs-loader.h"

/* maximum length of a uint64 in an 7/8b encoding */
#define ENCODED_INT_LENGTH 10

/* APR is missing an APR_OFF_T_MAX.  So, define one.  We will use it to
 * limit file offsets stored in the indexes.
 *
 * We assume that everything shorter than 64 bits, it is at least 32 bits.
 * We also assume that the type is always signed meaning we only have an
 * effective positive range of 63 or 31 bits, respectively.
 */
static
const apr_uint64_t off_t_max = (sizeof(apr_off_t) == sizeof(apr_int64_t))
                             ? APR_INT64_MAX
                             : APR_INT32_MAX;

/* We store P2L proto-index entries as 6 values, 64 bits each on disk.
 * See also svn_fs_fs__p2l_proto_index_add_entry().
 */
#define P2L_PROTO_INDEX_ENTRY_SIZE (6 * sizeof(apr_uint64_t))

/* We put this string in front of the L2P index header. */
#define L2P_STREAM_PREFIX "L2P-INDEX\n"

/* We put this string in front of the P2L index header. */
#define P2L_STREAM_PREFIX "P2L-INDEX\n"

/* Size of the buffer that will fit the index header prefixes. */
#define STREAM_PREFIX_LEN MAX(sizeof(L2P_STREAM_PREFIX), \
                              sizeof(P2L_STREAM_PREFIX))

/* Page tables in the log-to-phys index file exclusively contain entries
 * of this type to describe position and size of a given page.
 */
typedef struct l2p_page_table_entry_t
{
  /* global offset on the page within the index file */
  apr_uint64_t offset;

  /* number of mapping entries in that page */
  apr_uint32_t entry_count;

  /* size of the page on disk (in the index file) */
  apr_uint32_t size;
} l2p_page_table_entry_t;

/* Master run-time data structure of an log-to-phys index.  It contains
 * the page tables of every revision covered by that index - but not the
 * pages themselves.
 */
typedef struct l2p_header_t
{
  /* first revision covered by this index */
  svn_revnum_t first_revision;

  /* number of revisions covered */
  apr_size_t revision_count;

  /* (max) number of entries per page */
  apr_uint32_t page_size;

  /* indexes into PAGE_TABLE that mark the first page of the respective
   * revision.  PAGE_TABLE_INDEX[REVISION_COUNT] points to the end of
   * PAGE_TABLE.
   */
  apr_size_t * page_table_index;

  /* Page table covering all pages in the index */
  l2p_page_table_entry_t * page_table;
} l2p_header_t;

/* Run-time data structure containing a single log-to-phys index page.
 */
typedef struct l2p_page_t
{
  /* number of entries in the OFFSETS array */
  apr_uint32_t entry_count;

  /* global file offsets (item index is the array index) within the
   * packed or non-packed rev file.  Offset will be -1 for unused /
   * invalid item index values. */
  apr_uint64_t *offsets;
} l2p_page_t;

/* All of the log-to-phys proto index file consist of entries of this type.
 */
typedef struct l2p_proto_entry_t
{
  /* phys offset + 1 of the data container. 0 for "new revision" entries. */
  apr_uint64_t offset;

  /* corresponding item index. 0 for "new revision" entries. */
  apr_uint64_t item_index;
} l2p_proto_entry_t;

/* Master run-time data structure of an phys-to-log index.  It contains
 * an array with one offset value for each rev file cluster.
 */
typedef struct p2l_header_t
{
  /* first revision covered by the index (and rev file) */
  svn_revnum_t first_revision;

  /* number of bytes in the rev files covered by each p2l page */
  apr_uint64_t page_size;

  /* number of pages / clusters in that rev file */
  apr_size_t page_count;

  /* number of bytes in the rev file */
  apr_uint64_t file_size;

  /* offsets of the pages / cluster descriptions within the index file */
  apr_off_t *offsets;
} p2l_header_t;

/*
 * packed stream
 *
 * This is a utility object that will read files containing 7b/8b encoded
 * unsigned integers.  It decodes them in batches to minimize overhead
 * and supports random access to random file locations.
 */

/* How many numbers we will pre-fetch and buffer in a packed number stream.
 */
enum { MAX_NUMBER_PREFETCH = 64 };

/* Prefetched number entry in a packed number stream.
 */
typedef struct value_position_pair_t
{
  /* prefetched number */
  apr_uint64_t value;

  /* number of bytes read, *including* this number, since the buffer start */
  apr_size_t total_len;
} value_position_pair_t;

/* State of a prefetching packed number stream.  It will read compressed
 * index data efficiently and present it as a series of non-packed uint64.
 */
struct svn_fs_fs__packed_number_stream_t
{
  /* underlying data file containing the packed values */
  apr_file_t *file;

  /* Offset within FILE at which the stream data starts
   * (i.e. which offset will reported as offset 0 by packed_stream_offset). */
  apr_off_t stream_start;

  /* First offset within FILE after the stream data.
   * Attempts to read beyond this will cause an "Unexpected End Of Stream"
   * error. */
  apr_off_t stream_end;

  /* number of used entries in BUFFER (starting at index 0) */
  apr_size_t used;

  /* index of the next number to read from the BUFFER (0 .. USED).
   * If CURRENT == USED, we need to read more data upon get() */
  apr_size_t current;

  /* offset in FILE from which the first entry in BUFFER has been read */
  apr_off_t start_offset;

  /* offset in FILE from which the next number has to be read */
  apr_off_t next_offset;

  /* read the file in chunks of this size */
  apr_size_t block_size;

  /* pool to be used for file ops etc. */
  apr_pool_t *pool;

  /* buffer for prefetched values */
  value_position_pair_t buffer[MAX_NUMBER_PREFETCH];
};

/* Return an svn_error_t * object for error ERR on STREAM with the given
 * MESSAGE string.  The latter must have a placeholder for the index file
 * name ("%s") and the current read offset (e.g. "0x%lx").
 */
static svn_error_t *
stream_error_create(svn_fs_fs__packed_number_stream_t *stream,
                    apr_status_t err,
                    const char *message)
{
  const char *file_name;
  apr_off_t offset;
  SVN_ERR(svn_io_file_name_get(&file_name, stream->file,
                               stream->pool));
  SVN_ERR(svn_io_file_get_offset(&offset, stream->file, stream->pool));

  return svn_error_createf(err, NULL, message, file_name,
                           apr_psprintf(stream->pool,
                                        "%" APR_UINT64_T_HEX_FMT,
                                        (apr_uint64_t)offset));
}

/* Read up to MAX_NUMBER_PREFETCH numbers from the STREAM->NEXT_OFFSET in
 * STREAM->FILE and buffer them.
 *
 * We don't want GCC and others to inline this (infrequently called)
 * function into packed_stream_get() because it prevents the latter from
 * being inlined itself.
 */
SVN__PREVENT_INLINE
static svn_error_t *
packed_stream_read(svn_fs_fs__packed_number_stream_t *stream)
{
  unsigned char buffer[MAX_NUMBER_PREFETCH];
  apr_size_t bytes_read = 0;
  apr_size_t i;
  value_position_pair_t *target;
  apr_off_t block_start = 0;
  apr_off_t block_left = 0;
  apr_status_t err;

  /* all buffered data will have been read starting here */
  stream->start_offset = stream->next_offset;

  /* packed numbers are usually not aligned to MAX_NUMBER_PREFETCH blocks,
   * i.e. the last number has been incomplete (and not buffered in stream)
   * and need to be re-read.  Therefore, always correct the file pointer.
   */
  SVN_ERR(svn_io_file_aligned_seek(stream->file, stream->block_size,
                                   &block_start, stream->next_offset,
                                   stream->pool));

  /* prefetch at least one number but, if feasible, don't cross block
   * boundaries.  This shall prevent jumping back and forth between two
   * blocks because the extra data was not actually request _now_.
   */
  bytes_read = sizeof(buffer);
  block_left = stream->block_size - (stream->next_offset - block_start);
  if (block_left >= 10 && block_left < bytes_read)
    bytes_read = (apr_size_t)block_left;

  /* Don't read beyond the end of the file section that belongs to this
   * index / stream. */
  bytes_read = (apr_size_t)MIN(bytes_read,
                               stream->stream_end - stream->next_offset);

  err = apr_file_read(stream->file, buffer, &bytes_read);
  if (err && !APR_STATUS_IS_EOF(err))
    return stream_error_create(stream, err,
      _("Can't read index file '%s' at offset 0x%s"));

  /* if the last number is incomplete, trim it from the buffer */
  while (bytes_read > 0 && buffer[bytes_read-1] >= 0x80)
    --bytes_read;

  /* we call read() only if get() requires more data.  So, there must be
   * at least *one* further number. */
  if SVN__PREDICT_FALSE(bytes_read == 0)
    return stream_error_create(stream, err,
      _("Unexpected end of index file %s at offset 0x%s"));

  /* parse file buffer and expand into stream buffer */
  target = stream->buffer;
  for (i = 0; i < bytes_read;)
    {
      if (buffer[i] < 0x80)
        {
          /* numbers < 128 are relatively frequent and particularly easy
           * to decode.  Give them special treatment. */
          target->value = buffer[i];
          ++i;
          target->total_len = i;
          ++target;
        }
      else
        {
          apr_uint64_t value = 0;
          apr_uint64_t shift = 0;
          while (buffer[i] >= 0x80)
            {
              value += ((apr_uint64_t)buffer[i] & 0x7f) << shift;
              shift += 7;
              ++i;
            }

          target->value = value + ((apr_uint64_t)buffer[i] << shift);
          ++i;
          target->total_len = i;
          ++target;

          /* let's catch corrupted data early.  It would surely cause
           * havoc further down the line. */
          if SVN__PREDICT_FALSE(shift > 8 * sizeof(value))
            return svn_error_createf(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
                                     _("Corrupt index: number too large"));
       }
    }

  /* update stream state */
  stream->used = target - stream->buffer;
  stream->next_offset = stream->start_offset + i;
  stream->current = 0;

  return SVN_NO_ERROR;
}

/* Create and open a packed number stream reading from offsets START to
 * END in FILE and return it in *STREAM.  Access the file in chunks of
 * BLOCK_SIZE bytes.  Expect the stream to be prefixed by STREAM_PREFIX.
 * Allocate *STREAM in RESULT_POOL and use SCRATCH_POOL for temporaries.
 */
static svn_error_t *
packed_stream_open(svn_fs_fs__packed_number_stream_t **stream,
                   apr_file_t *file,
                   apr_off_t start,
                   apr_off_t end,
                   const char *stream_prefix,
                   apr_size_t block_size,
                   apr_pool_t *result_pool,
                   apr_pool_t *scratch_pool)
{
  char buffer[STREAM_PREFIX_LEN + 1] = { 0 };
  apr_size_t len = strlen(stream_prefix);
  svn_fs_fs__packed_number_stream_t *result;

  /* If this is violated, we forgot to adjust STREAM_PREFIX_LEN after
   * changing the index header prefixes. */
  SVN_ERR_ASSERT(len < sizeof(buffer));

  /* Read the header prefix and compare it with the expected prefix */
  SVN_ERR(svn_io_file_aligned_seek(file, block_size, NULL, start,
                                   scratch_pool));
  SVN_ERR(svn_io_file_read_full2(file, buffer, len, NULL, NULL,
                                 scratch_pool));

  if (strncmp(buffer, stream_prefix, len))
    return svn_error_createf(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
                             _("Index stream header prefix mismatch.\n"
                               "  expected: %s"
                               "  found: %s"), stream_prefix, buffer);

  /* Construct the actual stream object. */
  result = apr_palloc(result_pool, sizeof(*result));

  result->pool = result_pool;
  result->file = file;
  result->stream_start = start + len;
  result->stream_end = end;

  result->used = 0;
  result->current = 0;
  result->start_offset = result->stream_start;
  result->next_offset = result->stream_start;
  result->block_size = block_size;

  *stream = result;

  return SVN_NO_ERROR;
}

/*
 * The forced inline is required for performance reasons:  This is a very
 * hot code path (called for every item we read) but e.g. GCC would rather
 * chose to inline packed_stream_read() here, preventing packed_stream_get
 * from being inlined itself.
 */
SVN__FORCE_INLINE
static svn_error_t*
packed_stream_get(apr_uint64_t *value,
                  svn_fs_fs__packed_number_stream_t *stream)
{
  if (stream->current == stream->used)
    SVN_ERR(packed_stream_read(stream));

  *value = stream->buffer[stream->current].value;
  ++stream->current;

  return SVN_NO_ERROR;
}

/* Navigate STREAM to packed stream offset OFFSET.  There will be no checks
 * whether the given OFFSET is valid.
 */
static void
packed_stream_seek(svn_fs_fs__packed_number_stream_t *stream,
                   apr_off_t offset)
{
  apr_off_t file_offset = offset + stream->stream_start;

  if (   stream->used == 0
      || offset < stream->start_offset
      || offset >= stream->next_offset)
    {
      /* outside buffered data.  Next get() will read() from OFFSET. */
      stream->start_offset = file_offset;
      stream->next_offset = file_offset;
      stream->current = 0;
      stream->used = 0;
    }
  else
    {
      /* Find the suitable location in the stream buffer.
       * Since our buffer is small, it is efficient enough to simply scan
       * it for the desired position. */
      apr_size_t i;
      for (i = 0; i < stream->used; ++i)
        if (stream->buffer[i].total_len > file_offset - stream->start_offset)
          break;

      stream->current = i;
    }
}

/* Return the packed stream offset of at which the next number in the stream
 * can be found.
 */
static apr_off_t
packed_stream_offset(svn_fs_fs__packed_number_stream_t *stream)
{
  apr_off_t file_offset
       = stream->current == 0
       ? stream->start_offset
       : stream->buffer[stream->current-1].total_len + stream->start_offset;

  return file_offset - stream->stream_start;
}

/* Encode VALUE as 7/8b into P and return the number of bytes written.
 * This will be used when _writing_ packed data.  packed_stream_* is for
 * read operations only.
 */
static apr_size_t
encode_uint(unsigned char *p, apr_uint64_t value)
{
  unsigned char *start = p;
  while (value >= 0x80)
    {
      *p = (unsigned char)((value % 0x80) + 0x80);
      value /= 0x80;
      ++p;
    }

  *p = (unsigned char)(value % 0x80);
  return (p - start) + 1;
}

/* Encode VALUE as 7/8b into P and return the number of bytes written.
 * This maps signed ints onto unsigned ones.
 */
static apr_size_t
encode_int(unsigned char *p, apr_int64_t value)
{
  return encode_uint(p, (apr_uint64_t)(value < 0 ? -1 - 2*value : 2*value));
}

/* Append VALUE to STREAM in 7/8b encoding.
 */
static svn_error_t *
stream_write_encoded(svn_stream_t *stream,
                     apr_uint64_t value)
{
  unsigned char encoded[ENCODED_INT_LENGTH];

  apr_size_t len = encode_uint(encoded, value);
  return svn_error_trace(svn_stream_write(stream, (char *)encoded, &len));
}

/* Map unsigned VALUE back to signed integer.
 */
static apr_int64_t
decode_int(apr_uint64_t value)
{
  return (apr_int64_t)(value % 2 ? -1 - value / 2 : value / 2);
}

/* Write VALUE to the PROTO_INDEX file, using SCRATCH_POOL for temporary
 * allocations.
 *
 * The point of this function is to ensure an architecture-independent
 * proto-index file format.  All data is written as unsigned 64 bits ints
 * in little endian byte order.  64 bits is the largest portable integer
 * we have and unsigned values have well-defined conversions in C.
 */
static svn_error_t *
write_uint64_to_proto_index(apr_file_t *proto_index,
                            apr_uint64_t value,
                            apr_pool_t *scratch_pool)
{
  apr_byte_t buffer[sizeof(value)];
  int i;
  apr_size_t written;

  /* Split VALUE into 8 bytes using LE ordering. */
  for (i = 0; i < sizeof(buffer); ++i)
    {
      /* Unsigned conversions are well-defined ... */
      buffer[i] = (apr_byte_t)value;
      value >>= CHAR_BIT;
    }

  /* Write it all to disk. */
  SVN_ERR(svn_io_file_write_full(proto_index, buffer, sizeof(buffer),
                                 &written, scratch_pool));
  SVN_ERR_ASSERT(written == sizeof(buffer));

  return SVN_NO_ERROR;
}

/* Read one unsigned 64 bit value from PROTO_INDEX file and return it in
 * *VALUE_P.  If EOF is NULL, error out when trying to read beyond EOF.
 * Use SCRATCH_POOL for temporary allocations.
 *
 * This function is the inverse to write_uint64_to_proto_index (see there),
 * reading the external LE byte order and convert it into host byte order.
 */
static svn_error_t *
read_uint64_from_proto_index(apr_file_t *proto_index,
                             apr_uint64_t *value_p,
                             svn_boolean_t *eof,
                             apr_pool_t *scratch_pool)
{
  apr_byte_t buffer[sizeof(*value_p)];
  apr_size_t bytes_read;

  /* Read the full 8 bytes or our 64 bit value, unless we hit EOF.
   * Assert that we never read partial values. */
  SVN_ERR(svn_io_file_read_full2(proto_index, buffer, sizeof(buffer),
                                 &bytes_read, eof, scratch_pool));
  SVN_ERR_ASSERT((eof && *eof) || bytes_read == sizeof(buffer));

  /* If we did not hit EOF, reconstruct the uint64 value and return it. */
  if (!eof || !*eof)
    {
      int i;
      apr_uint64_t value;

      /* This could only overflow if CHAR_BIT had a value that is not
       * a divisor of 64. */
      value = 0;
      for (i = sizeof(buffer) - 1; i >= 0; --i)
        value = (value << CHAR_BIT) + buffer[i];

      *value_p = value;
    }

  return SVN_NO_ERROR;
}

/* Convenience function similar to read_uint64_from_proto_index, but returns
 * an uint32 value in VALUE_P.  Return an error if the value does not fit.
 */
static svn_error_t *
read_uint32_from_proto_index(apr_file_t *proto_index,
                             apr_uint32_t *value_p,
                             svn_boolean_t *eof,
                             apr_pool_t *scratch_pool)
{
  apr_uint64_t value;
  SVN_ERR(read_uint64_from_proto_index(proto_index, &value, eof,
                                       scratch_pool));
  if (!eof || !*eof)
    {
      if (value > APR_UINT32_MAX)
        return svn_error_createf(SVN_ERR_FS_INDEX_OVERFLOW, NULL,
                                _("UINT32 0x%s too large, max = 0x%s"),
                                apr_psprintf(scratch_pool,
                                             "%" APR_UINT64_T_HEX_FMT,
                                             value),
                                apr_psprintf(scratch_pool,
                                             "%" APR_UINT64_T_HEX_FMT,
                                             (apr_uint64_t)APR_UINT32_MAX));

      /* This conversion is not lossy because the value can be represented
       * in the target type. */
      *value_p = (apr_uint32_t)value;
    }

  return SVN_NO_ERROR;
}

/* Convenience function similar to read_uint64_from_proto_index, but returns
 * an off_t value in VALUE_P.  Return an error if the value does not fit.
 */
static svn_error_t *
read_off_t_from_proto_index(apr_file_t *proto_index,
                            apr_off_t *value_p,
                            svn_boolean_t *eof,
                            apr_pool_t *scratch_pool)
{
  apr_uint64_t value;
  SVN_ERR(read_uint64_from_proto_index(proto_index, &value, eof,
                                       scratch_pool));
  if (!eof || !*eof)
    {
      if (value > off_t_max)
        return svn_error_createf(SVN_ERR_FS_INDEX_OVERFLOW, NULL,
                                _("File offset 0x%s too large, max = 0x%s"),
                                apr_psprintf(scratch_pool,
                                             "%" APR_UINT64_T_HEX_FMT,
                                             value),
                                apr_psprintf(scratch_pool,
                                             "%" APR_UINT64_T_HEX_FMT,
                                             off_t_max));

      /* Shortening conversion from unsigned to signed int is well-defined
       * and not lossy in C because the value can be represented in the
       * target type. */
      *value_p = (apr_off_t)value;
    }

  return SVN_NO_ERROR;
}

/*
 * log-to-phys index
 */

/* Append ENTRY to log-to-phys PROTO_INDEX file.
 * Use SCRATCH_POOL for temporary allocations.
 */
static svn_error_t *
write_l2p_entry_to_proto_index(apr_file_t *proto_index,
                               l2p_proto_entry_t entry,
                               apr_pool_t *scratch_pool)
{
  SVN_ERR(write_uint64_to_proto_index(proto_index, entry.offset,
                                      scratch_pool));
  SVN_ERR(write_uint64_to_proto_index(proto_index, entry.item_index,
                                      scratch_pool));

  return SVN_NO_ERROR;
}

/* Read *ENTRY from log-to-phys PROTO_INDEX file and indicate end-of-file
 * in *EOF, or error out in that case if EOF is NULL.  *ENTRY is in an
 * undefined state if an end-of-file occurred.
 * Use SCRATCH_POOL for temporary allocations.
 */
static svn_error_t *
read_l2p_entry_from_proto_index(apr_file_t *proto_index,
                                l2p_proto_entry_t *entry,
                                svn_boolean_t *eof,
                                apr_pool_t *scratch_pool)
{
  SVN_ERR(read_uint64_from_proto_index(proto_index, &entry->offset, eof,
                                       scratch_pool));
  SVN_ERR(read_uint64_from_proto_index(proto_index, &entry->item_index, eof,
                                       scratch_pool));

  return SVN_NO_ERROR;
}

/* Write the log-2-phys index page description for the l2p_page_entry_t
 * array ENTRIES, starting with element START up to but not including END.
 * Write the resulting representation into BUFFER.  Use SCRATCH_POOL for
 * temporary allocations.
 */
static svn_error_t *
encode_l2p_page(apr_array_header_t *entries,
                int start,
                int end,
                svn_spillbuf_t *buffer,
                apr_pool_t *scratch_pool)
{
  unsigned char encoded[ENCODED_INT_LENGTH];
  int i;
  const apr_uint64_t *values = (const apr_uint64_t *)entries->elts;
  apr_uint64_t last_value = 0;

  /* encode items */
  for (i = start; i < end; ++i)
    {
      apr_int64_t diff = values[i] - last_value;
      last_value = values[i];
      SVN_ERR(svn_spillbuf__write(buffer, (const char *)encoded,
                                  encode_int(encoded, diff), scratch_pool));
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_fs__l2p_proto_index_open(apr_file_t **proto_index,
                                const char *file_name,
                                apr_pool_t *result_pool)
{
  SVN_ERR(svn_io_file_open(proto_index, file_name, APR_READ | APR_WRITE
                           | APR_CREATE | APR_APPEND | APR_BUFFERED,
                           APR_OS_DEFAULT, result_pool));

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_fs__l2p_proto_index_add_revision(apr_file_t *proto_index,
                                        apr_pool_t *scratch_pool)
{
  l2p_proto_entry_t entry;
  entry.offset = 0;
  entry.item_index = 0;

  return svn_error_trace(write_l2p_entry_to_proto_index(proto_index, entry,
                                                        scratch_pool));
}

svn_error_t *
svn_fs_fs__l2p_proto_index_add_entry(apr_file_t *proto_index,
                                     apr_off_t offset,
                                     apr_uint64_t item_index,
                                     apr_pool_t *scratch_pool)
{
  l2p_proto_entry_t entry;

  /* make sure the conversion to uint64 works */
  SVN_ERR_ASSERT(offset >= -1);

  /* we support offset '-1' as a "not used" indication */
  entry.offset = (apr_uint64_t)offset + 1;

  /* make sure we can use item_index as an array index when building the
   * final index file */
  SVN_ERR_ASSERT(item_index < UINT_MAX / 2);
  entry.item_index = item_index;

  return svn_error_trace(write_l2p_entry_to_proto_index(proto_index, entry,
                                                        scratch_pool));
}

svn_error_t *
svn_fs_fs__l2p_index_append(svn_checksum_t **checksum,
                            svn_fs_t *fs,
                            apr_file_t *index_file,
                            const char *proto_file_name,
                            svn_revnum_t revision,
                            apr_pool_t * result_pool,
                            apr_pool_t *scratch_pool)
{
  fs_fs_data_t *ffd = fs->fsap_data;
  apr_file_t *proto_index = NULL;
  svn_stream_t *stream;
  int i;
  apr_uint64_t entry;
  svn_boolean_t eof = FALSE;

  int last_page_count = 0;          /* total page count at the start of
                                       the current revision */

  /* temporary data structures that collect the data which will be moved
     to the target file in a second step */
  apr_pool_t *local_pool = svn_pool_create(scratch_pool);
  apr_pool_t *iterpool = svn_pool_create(local_pool);
  apr_array_header_t *page_counts
    = apr_array_make(local_pool, 16, sizeof(apr_uint64_t));
  apr_array_header_t *page_sizes
    = apr_array_make(local_pool, 16, sizeof(apr_uint64_t));
  apr_array_header_t *entry_counts
    = apr_array_make(local_pool, 16, sizeof(apr_uint64_t));

  /* collect the item offsets and sub-item value for the current revision */
  apr_array_header_t *entries
    = apr_array_make(local_pool, 256, sizeof(apr_uint64_t));

  /* 64k blocks, spill after 16MB */
  svn_spillbuf_t *buffer
    = svn_spillbuf__create(0x10000, 0x1000000, local_pool);

  /* Paranoia check that makes later casting to int32 safe.
   * The current implementation is limited to 2G entries per page. */
  if (ffd->l2p_page_size > APR_INT32_MAX)
    return svn_error_createf(SVN_ERR_FS_INDEX_OVERFLOW , NULL,
                            _("L2P index page size  %s"
                              " exceeds current limit of 2G entries"),
                            apr_psprintf(local_pool, "%" APR_UINT64_T_FMT,
                                         ffd->l2p_page_size));

  /* start at the beginning of the source file */
  SVN_ERR(svn_io_file_open(&proto_index, proto_file_name,
                           APR_READ | APR_CREATE | APR_BUFFERED,
                           APR_OS_DEFAULT, scratch_pool));

  /* process all entries until we fail due to EOF */
  for (entry = 0; !eof; ++entry)
    {
      l2p_proto_entry_t proto_entry;

      /* (attempt to) read the next entry from the source */
      SVN_ERR(read_l2p_entry_from_proto_index(proto_index, &proto_entry,
                                              &eof, local_pool));

      /* handle new revision */
      if (eof || (entry > 0 && proto_entry.offset == 0))
        {
          /* dump entries, grouped into pages */

          int entry_count = 0;
          for (i = 0; i < entries->nelts; i += entry_count)
            {
              /* 1 page with up to L2P_PAGE_SIZE entries.
               * fsfs.conf settings validation guarantees this to fit into
               * our address space. */
              apr_uint64_t last_buffer_size
                = (apr_uint64_t)svn_spillbuf__get_size(buffer);

              svn_pool_clear(iterpool);

              entry_count = ffd->l2p_page_size < entries->nelts - i
                          ? (int)ffd->l2p_page_size
                          : entries->nelts - i;
              SVN_ERR(encode_l2p_page(entries, i, i + entry_count,
                                      buffer, iterpool));

              APR_ARRAY_PUSH(entry_counts, apr_uint64_t) = entry_count;
              APR_ARRAY_PUSH(page_sizes, apr_uint64_t)
                = svn_spillbuf__get_size(buffer) - last_buffer_size;
            }

          apr_array_clear(entries);

          /* store the number of pages in this revision */
          APR_ARRAY_PUSH(page_counts, apr_uint64_t)
            = page_sizes->nelts - last_page_count;

          last_page_count = page_sizes->nelts;
        }
      else
        {
          int idx;

          /* store the mapping in our array */
          if (proto_entry.item_index > APR_INT32_MAX)
            return svn_error_createf(SVN_ERR_FS_INDEX_OVERFLOW , NULL,
                                    _("Item index %s too large "
                                      "in l2p proto index for revision %ld"),
                                    apr_psprintf(local_pool, "%" APR_UINT64_T_FMT,
                                                 proto_entry.item_index),
                                    revision + page_counts->nelts);

          idx = (int)proto_entry.item_index;
          while (idx >= entries->nelts)
            APR_ARRAY_PUSH(entries, apr_uint64_t) = 0;

          APR_ARRAY_IDX(entries, idx, apr_uint64_t) = proto_entry.offset;
        }
    }

  /* close the source file */
  SVN_ERR(svn_io_file_close(proto_index, local_pool));

  /* Paranoia check that makes later casting to int32 safe.
   * The current implementation is limited to 2G pages per index. */
  if (page_counts->nelts > APR_INT32_MAX)
    return svn_error_createf(SVN_ERR_FS_INDEX_OVERFLOW , NULL,
                            _("L2P index page count  %d"
                              " exceeds current limit of 2G pages"),
                            page_counts->nelts);

  /* open target stream. */
  stream = svn_stream_checksummed2(svn_stream_from_aprfile2(index_file, TRUE,
                                                            local_pool),
                                   NULL, checksum, svn_checksum_md5, FALSE,
                                   result_pool);


  /* write header info */
  SVN_ERR(svn_stream_puts(stream, L2P_STREAM_PREFIX));
  SVN_ERR(stream_write_encoded(stream, revision));
  SVN_ERR(stream_write_encoded(stream, ffd->l2p_page_size));
  SVN_ERR(stream_write_encoded(stream, page_counts->nelts));
  SVN_ERR(stream_write_encoded(stream, page_sizes->nelts));

  /* write the revision table */
  for (i = 0; i < page_counts->nelts; ++i)
    {
      apr_uint64_t value = APR_ARRAY_IDX(page_counts, i, apr_uint64_t);
      SVN_ERR(stream_write_encoded(stream, value));
    }

  /* write the page table */
  for (i = 0; i < page_sizes->nelts; ++i)
    {
      apr_uint64_t value = APR_ARRAY_IDX(page_sizes, i, apr_uint64_t);
      SVN_ERR(stream_write_encoded(stream, value));
      value = APR_ARRAY_IDX(entry_counts, i, apr_uint64_t);
      SVN_ERR(stream_write_encoded(stream, value));
    }

  /* append page contents and implicitly close STREAM */
  SVN_ERR(svn_stream_copy3(svn_stream__from_spillbuf(buffer, local_pool),
                           stream, NULL, NULL, local_pool));

  svn_pool_destroy(local_pool);

  return SVN_NO_ERROR;
}

/* If REV_FILE->L2P_STREAM is NULL, create a new stream for the log-to-phys
 * index for REVISION in FS and return it in REV_FILE.
 */
static svn_error_t *
auto_open_l2p_index(svn_fs_fs__revision_file_t *rev_file,
                    svn_fs_t *fs,
                    svn_revnum_t revision)
{
  if (rev_file->l2p_stream == NULL)
    {
      fs_fs_data_t *ffd = fs->fsap_data;

      SVN_ERR(svn_fs_fs__auto_read_footer(rev_file));
      SVN_ERR(packed_stream_open(&rev_file->l2p_stream,
                                 rev_file->file,
                                 rev_file->l2p_offset,
                                 rev_file->p2l_offset,
                                 L2P_STREAM_PREFIX,
                                 (apr_size_t)ffd->block_size,
                                 rev_file->pool,
                                 rev_file->pool));
    }

  return SVN_NO_ERROR;
}

/* Read the header data structure of the log-to-phys index for REVISION
 * in FS and return it in *HEADER, allocated in RESULT_POOL.  Use REV_FILE
 * to access on-disk data.  Use SCRATCH_POOL for temporary allocations.
 */
static svn_error_t *
get_l2p_header_body(l2p_header_t **header,
                    svn_fs_fs__revision_file_t *rev_file,
                    svn_fs_t *fs,
                    svn_revnum_t revision,
                    apr_pool_t *result_pool,
                    apr_pool_t *scratch_pool)
{
  fs_fs_data_t *ffd = fs->fsap_data;
  apr_uint64_t value;
  apr_size_t i;
  apr_size_t page, page_count;
  apr_off_t offset;
  l2p_header_t *result = apr_pcalloc(result_pool, sizeof(*result));
  apr_size_t page_table_index;
  svn_revnum_t next_rev;

  pair_cache_key_t key;
  key.revision = rev_file->start_revision;
  key.second = rev_file->is_packed;

  SVN_ERR(auto_open_l2p_index(rev_file, fs, revision));
  packed_stream_seek(rev_file->l2p_stream, 0);

  /* Read the table sizes.  Check the data for plausibility and
   * consistency with other bits. */
  SVN_ERR(packed_stream_get(&value, rev_file->l2p_stream));
  result->first_revision = (svn_revnum_t)value;
  if (result->first_revision != rev_file->start_revision)
    return svn_error_create(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
                  _("Index rev / pack file revision numbers do not match"));

  SVN_ERR(packed_stream_get(&value, rev_file->l2p_stream));
  result->page_size = (apr_uint32_t)value;
  if (!result->page_size || (result->page_size & (result->page_size - 1)))
    return svn_error_create(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
                            _("L2P index page size is not a power of two"));

  SVN_ERR(packed_stream_get(&value, rev_file->l2p_stream));
  result->revision_count = (int)value;
  if (   result->revision_count != 1
      && result->revision_count != (apr_uint64_t)ffd->max_files_per_dir)
    return svn_error_create(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
                            _("Invalid number of revisions in L2P index"));

  SVN_ERR(packed_stream_get(&value, rev_file->l2p_stream));
  page_count = (apr_size_t)value;
  if (page_count < result->revision_count)
    return svn_error_create(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
                            _("Fewer L2P index pages than revisions"));
  if (page_count > (rev_file->p2l_offset - rev_file->l2p_offset) / 2)
    return svn_error_create(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
                            _("L2P index page count implausibly large"));

  next_rev = result->first_revision + (svn_revnum_t)result->revision_count;
  if (result->first_revision > revision || next_rev <= revision)
    return svn_error_createf(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
                      _("Corrupt L2P index for r%ld only covers r%ld:%ld"),
                      revision, result->first_revision, next_rev);

  /* allocate the page tables */
  result->page_table
    = apr_pcalloc(result_pool, page_count * sizeof(*result->page_table));
  result->page_table_index
    = apr_pcalloc(result_pool, (result->revision_count + 1)
                             * sizeof(*result->page_table_index));

  /* read per-revision page table sizes (i.e. number of pages per rev) */
  page_table_index = 0;
  result->page_table_index[0] = page_table_index;

  for (i = 0; i < result->revision_count; ++i)
    {
      SVN_ERR(packed_stream_get(&value, rev_file->l2p_stream));
      if (value == 0)
        return svn_error_create(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
                                _("Revision with no L2P index pages"));

      page_table_index += (apr_size_t)value;
      if (page_table_index > page_count)
        return svn_error_create(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
                                _("L2P page table exceeded"));

      result->page_table_index[i+1] = page_table_index;
    }

  if (page_table_index != page_count)
    return svn_error_create(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
                 _("Revisions do not cover the full L2P index page table"));

  /* read actual page tables */
  for (page = 0; page < page_count; ++page)
    {
      SVN_ERR(packed_stream_get(&value, rev_file->l2p_stream));
      if (value == 0)
        return svn_error_create(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
                                _("Empty L2P index page"));

      result->page_table[page].size = (apr_uint32_t)value;
      SVN_ERR(packed_stream_get(&value, rev_file->l2p_stream));
      if (value > result->page_size)
        return svn_error_create(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
                                _("Page exceeds L2P index page size"));

      result->page_table[page].entry_count = (apr_uint32_t)value;
    }

  /* correct the page description offsets */
  offset = packed_stream_offset(rev_file->l2p_stream);
  for (page = 0; page < page_count; ++page)
    {
      result->page_table[page].offset = offset;
      offset += result->page_table[page].size;
    }

  /* return and cache the header */
  *header = result;
  SVN_ERR(svn_cache__set(ffd->l2p_header_cache, &key, result, scratch_pool));

  return SVN_NO_ERROR;
}

/* Data structure that describes which l2p page info shall be extracted
 * from the cache and contains the fields that receive the result.
 */
typedef struct l2p_page_info_baton_t
{
  /* input data: we want the page covering (REVISION,ITEM_INDEX) */
  svn_revnum_t revision;
  apr_uint64_t item_index;

  /* out data */
  /* page location and size of the page within the l2p index file */
  l2p_page_table_entry_t entry;

  /* page number within the pages for REVISION (not l2p index global!) */
  apr_uint32_t page_no;

  /* offset of ITEM_INDEX within that page */
  apr_uint32_t page_offset;

  /* revision identifying the l2p index file, also the first rev in that */
  svn_revnum_t first_revision;
} l2p_page_info_baton_t;


/* Utility function that copies the info requested by BATON->REVISION and
 * BATON->ITEM_INDEX and from HEADER and PAGE_TABLE into the output fields
 * of *BATON.  Use SCRATCH_POOL for temporary allocations.
 */
static svn_error_t *
l2p_page_info_copy(l2p_page_info_baton_t *baton,
                   const l2p_header_t *header,
                   const l2p_page_table_entry_t *page_table,
                   const apr_size_t *page_table_index,
                   apr_pool_t *scratch_pool)
{
  /* revision offset within the index file */
  apr_size_t rel_revision = baton->revision - header->first_revision;
  if (rel_revision >= header->revision_count)
    return svn_error_createf(SVN_ERR_FS_INDEX_REVISION , NULL,
                             _("Revision %ld not covered by item index"),
                             baton->revision);

  /* select the relevant page */
  if (baton->item_index < header->page_size)
    {
      /* most revs fit well into a single page */
      baton->page_offset = (apr_uint32_t)baton->item_index;
      baton->page_no = 0;
      baton->entry = page_table[page_table_index[rel_revision]];
    }
  else
    {
      const l2p_page_table_entry_t *first_entry;
      const l2p_page_table_entry_t *last_entry;
      apr_uint64_t max_item_index;

      /* range of pages for this rev */
      first_entry = page_table + page_table_index[rel_revision];
      last_entry = page_table + page_table_index[rel_revision + 1];

      /* do we hit a valid index page? */
      max_item_index =   (apr_uint64_t)header->page_size
                       * (last_entry - first_entry);
      if (baton->item_index >= max_item_index)
        return svn_error_createf(SVN_ERR_FS_INDEX_OVERFLOW , NULL,
                                _("Item index %s exceeds l2p limit "
                                  "of %s for revision %ld"),
                                apr_psprintf(scratch_pool,
                                             "%" APR_UINT64_T_FMT,
                                             baton->item_index),
                                apr_psprintf(scratch_pool,
                                             "%" APR_UINT64_T_FMT,
                                             max_item_index),
                                baton->revision);

      /* all pages are of the same size and full, except for the last one */
      baton->page_offset = (apr_uint32_t)(baton->item_index % header->page_size);
      baton->page_no = (apr_uint32_t)(baton->item_index / header->page_size);
      baton->entry = first_entry[baton->page_no];
    }

  baton->first_revision = header->first_revision;

  return SVN_NO_ERROR;
}

/* Implement svn_cache__partial_getter_func_t: copy the data requested in
 * l2p_page_info_baton_t *BATON from l2p_header_t *DATA into the output
 * fields in *BATON.
 */
static svn_error_t *
l2p_page_info_access_func(void **out,
                          const void *data,
                          apr_size_t data_len,
                          void *baton,
                          apr_pool_t *result_pool)
{
  /* resolve all pointer values of in-cache data */
  const l2p_header_t *header = data;
  const l2p_page_table_entry_t *page_table
    = svn_temp_deserializer__ptr(header,
                                 (const void *const *)&header->page_table);
  const apr_size_t *page_table_index
    = svn_temp_deserializer__ptr(header,
                           (const void *const *)&header->page_table_index);

  /* copy the info */
  return l2p_page_info_copy(baton, header, page_table, page_table_index,
                            result_pool);
}

/* Get the page info requested in *BATON from FS and set the output fields
 * in *BATON.  Use REV_FILE for on-disk file access.
 * Use SCRATCH_POOL for temporary allocations.
 */
static svn_error_t *
get_l2p_page_info(l2p_page_info_baton_t *baton,
                  svn_fs_fs__revision_file_t *rev_file,
                  svn_fs_t *fs,
                  apr_pool_t *scratch_pool)
{
  fs_fs_data_t *ffd = fs->fsap_data;
  l2p_header_t *result;
  svn_boolean_t is_cached = FALSE;
  void *dummy = NULL;

  /* try to find the info in the cache */
  pair_cache_key_t key;
  key.revision = rev_file->start_revision;
  key.second = rev_file->is_packed;
  SVN_ERR(svn_cache__get_partial((void**)&dummy, &is_cached,
                                 ffd->l2p_header_cache, &key,
                                 l2p_page_info_access_func, baton,
                                 scratch_pool));
  if (is_cached)
    return SVN_NO_ERROR;

  /* read from disk, cache and copy the result */
  SVN_ERR(get_l2p_header_body(&result, rev_file, fs, baton->revision,
                              scratch_pool, scratch_pool));
  SVN_ERR(l2p_page_info_copy(baton, result, result->page_table,
                             result->page_table_index, scratch_pool));

  return SVN_NO_ERROR;
}

/* Data request structure used by l2p_page_table_access_func.
 */
typedef struct l2p_page_table_baton_t
{
  /* revision for which to read the page table */
  svn_revnum_t revision;

  /* page table entries (of type l2p_page_table_entry_t).
   * Must be created by caller and will be filled by callee. */
  apr_array_header_t *pages;
} l2p_page_table_baton_t;

/* Implement svn_cache__partial_getter_func_t: copy the data requested in
 * l2p_page_baton_t *BATON from l2p_page_t *DATA into BATON->PAGES and *OUT.
 */
static svn_error_t *
l2p_page_table_access_func(void **out,
                           const void *data,
                           apr_size_t data_len,
                           void *baton,
                           apr_pool_t *result_pool)
{
  /* resolve in-cache pointers */
  l2p_page_table_baton_t *table_baton = baton;
  const l2p_header_t *header = (const l2p_header_t *)data;
  const l2p_page_table_entry_t *page_table
    = svn_temp_deserializer__ptr(header,
                                 (const void *const *)&header->page_table);
  const apr_size_t *page_table_index
    = svn_temp_deserializer__ptr(header,
                           (const void *const *)&header->page_table_index);

  /* copy the revision's page table into BATON */
  apr_size_t rel_revision = table_baton->revision - header->first_revision;
  if (rel_revision < header->revision_count)
    {
      const l2p_page_table_entry_t *entry
        = page_table + page_table_index[rel_revision];
      const l2p_page_table_entry_t *last_entry
        = page_table + page_table_index[rel_revision + 1];

      for (; entry < last_entry; ++entry)
        APR_ARRAY_PUSH(table_baton->pages, l2p_page_table_entry_t)
          = *entry;
    }

  /* set output as a courtesy to the caller */
  *out = table_baton->pages;

  return SVN_NO_ERROR;
}

/* Read the l2p index page table for REVISION in FS from cache and return
 * it in PAGES.  The later must be provided by the caller (and can be
 * re-used); existing entries will be removed before writing the result.
 * If the data cannot be found in the cache, the result will be empty
 * (it never can be empty for a valid REVISION if the data is cached).
 * Use the info from REV_FILE to determine pack / rev file properties.
 * Use SCRATCH_POOL for temporary allocations.
 */
static svn_error_t *
get_l2p_page_table(apr_array_header_t *pages,
                   svn_fs_t *fs,
                   svn_fs_fs__revision_file_t *rev_file,
                   svn_revnum_t revision,
                   apr_pool_t *scratch_pool)
{
  fs_fs_data_t *ffd = fs->fsap_data;
  svn_boolean_t is_cached = FALSE;
  l2p_page_table_baton_t baton;

  pair_cache_key_t key;
  key.revision = rev_file->start_revision;
  key.second = rev_file->is_packed;

  apr_array_clear(pages);
  baton.revision = revision;
  baton.pages = pages;
  SVN_ERR(svn_cache__get_partial((void**)&pages, &is_cached,
                                 ffd->l2p_header_cache, &key,
                                 l2p_page_table_access_func, &baton,
                                 scratch_pool));

  return SVN_NO_ERROR;
}

/* From the log-to-phys index file starting at START_REVISION in FS, read
 * the mapping page identified by TABLE_ENTRY and return it in *PAGE.
 * Use REV_FILE to access on-disk files.
 * Use RESULT_POOL for allocations.
 */
static svn_error_t *
get_l2p_page(l2p_page_t **page,
             svn_fs_fs__revision_file_t *rev_file,
             svn_fs_t *fs,
             svn_revnum_t start_revision,
             l2p_page_table_entry_t *table_entry,
             apr_pool_t *result_pool)
{
  apr_uint32_t i;
  l2p_page_t *result = apr_pcalloc(result_pool, sizeof(*result));
  apr_uint64_t last_value = 0;

  /* open index file and select page */
  SVN_ERR(auto_open_l2p_index(rev_file, fs, start_revision));
  packed_stream_seek(rev_file->l2p_stream, table_entry->offset);

  /* initialize the page content */
  result->entry_count = table_entry->entry_count;
  result->offsets = apr_pcalloc(result_pool, result->entry_count
                                           * sizeof(*result->offsets));

  /* read all page entries (offsets in rev file and container sub-items) */
  for (i = 0; i < result->entry_count; ++i)
    {
      apr_uint64_t value = 0;
      SVN_ERR(packed_stream_get(&value, rev_file->l2p_stream));
      last_value += decode_int(value);
      result->offsets[i] = last_value - 1;
    }

  /* After reading all page entries, the read cursor must have moved by
   * TABLE_ENTRY->SIZE bytes. */
  if (   packed_stream_offset(rev_file->l2p_stream)
      != table_entry->offset + table_entry->size)
    return svn_error_create(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
                _("L2P actual page size does not match page table value."));

  *page = result;

  return SVN_NO_ERROR;
}

/* 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 };

  /* Parameter check. */
  if (min_offset < 0)
    min_offset = 0;

  if (max_offset <= 0)
    {
      /* Nothing to do */
      *end = TRUE;
      return SVN_NO_ERROR;
    }

  /* get the page table for REVISION from cache */
  *end = FALSE;
  SVN_ERR(get_l2p_page_table(pages, fs, rev_file, revision, scratch_pool));
  if (pages->nelts == 0 || rev_file->l2p_stream == NULL)
    {
      /* not found -> we can't continue without hitting the disk again */
      *end = TRUE;
      return SVN_NO_ERROR;
    }

  /* prefetch pages individually until all are done or we found one in
   * the cache */
  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;

      /* skip pages outside the specified index file range */
      if (   entry->offset < (apr_uint64_t)min_offset
          || entry->offset + entry->size > (apr_uint64_t)max_offset)
        {
          *end = TRUE;
          continue;
        }

      /* page already in cache? */
      key.page = i;
      SVN_ERR(svn_cache__has_key(&is_cached, ffd->l2p_page_cache,
                                 &key, iterpool));
      if (!is_cached)
        {
          /* no in cache -> read from stream (data already buffered in APR)
           * and cache the result */
          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;
}

/* Request data structure for l2p_entry_access_func.
 */
typedef struct l2p_entry_baton_t
{
  /* in data */
  /* revision. Used for error messages only */
  svn_revnum_t revision;

  /* item index to look up. Used for error messages only */
  apr_uint64_t item_index;

  /* offset within the cached page */
  apr_uint32_t page_offset;

  /* out data */
  /* absolute item or container offset in rev / pack file */
  apr_uint64_t offset;
} l2p_entry_baton_t;

/* Return the rev / pack file offset of the item at BATON->PAGE_OFFSET in
 * OFFSETS of PAGE and write it to *OFFSET.
 */
static svn_error_t *
l2p_page_get_entry(l2p_entry_baton_t *baton,
                   const l2p_page_t *page,
                   const apr_uint64_t *offsets,
                   apr_pool_t *scratch_pool)
{
  /* overflow check */
  if (page->entry_count <= baton->page_offset)
    return svn_error_createf(SVN_ERR_FS_INDEX_OVERFLOW , NULL,
                             _("Item index %s"
                               " too large in revision %ld"),
                             apr_psprintf(scratch_pool, "%" APR_UINT64_T_FMT,
                                          baton->item_index),
                             baton->revision);

  /* return the result */
  baton->offset = offsets[baton->page_offset];

  return SVN_NO_ERROR;
}

/* Implement svn_cache__partial_getter_func_t: copy the data requested in
 * l2p_entry_baton_t *BATON from l2p_page_t *DATA into BATON->OFFSET.
 * *OUT remains unchanged.
 */
static svn_error_t *
l2p_entry_access_func(void **out,
                      const void *data,
                      apr_size_t data_len,
                      void *baton,
                      apr_pool_t *result_pool)
{
  /* resolve all in-cache pointers */
  const l2p_page_t *page = data;
  const apr_uint64_t *offsets
    = svn_temp_deserializer__ptr(page, (const void *const *)&page->offsets);

  /* return the requested data */
  return l2p_page_get_entry(baton, page, offsets, result_pool);
}

/* Using the log-to-phys indexes in FS, find the absolute offset in the
 * rev file for (REVISION, ITEM_INDEX) and return it in *OFFSET.
 * Use SCRATCH_POOL for temporary allocations.
 */
static svn_error_t *
l2p_index_lookup(apr_off_t *offset,
                 svn_fs_t *fs,
                 svn_fs_fs__revision_file_t *rev_file,
                 svn_revnum_t revision,
                 apr_uint64_t item_index,
                 apr_pool_t *scratch_pool)
{
  fs_fs_data_t *ffd = fs->fsap_data;
  l2p_page_info_baton_t info_baton;
  l2p_entry_baton_t page_baton;
  l2p_page_t *page = NULL;
  svn_fs_fs__page_cache_key_t key = { 0 };
  svn_boolean_t is_cached = FALSE;
  void *dummy = NULL;

  /* read index master data structure and extract the info required to
   * access the l2p index page for (REVISION,ITEM_INDEX)*/
  info_baton.revision = revision;
  info_baton.item_index = item_index;
  SVN_ERR(get_l2p_page_info(&info_baton, rev_file, fs, scratch_pool));

  /* try to find the page in the cache and get the OFFSET from it */
  page_baton.revision = revision;
  page_baton.item_index = item_index;
  page_baton.page_offset = info_baton.page_offset;

  assert(revision <= APR_UINT32_MAX);
  key.revision = (apr_uint32_t)revision;
  key.is_packed = svn_fs_fs__is_packed_rev(fs, revision);
  key.page = info_baton.page_no;

  SVN_ERR(svn_cache__get_partial(&dummy, &is_cached,
                                 ffd->l2p_page_cache, &key,
                                 l2p_entry_access_func, &page_baton,
                                 scratch_pool));

  if (!is_cached)
    {
      /* we need to read the info from disk (might already be in the
       * APR file buffer, though) */
      apr_array_header_t *pages;
      svn_revnum_t prefetch_revision;
      svn_revnum_t last_revision
        = info_baton.first_revision
          + (key.is_packed ? ffd->max_files_per_dir : 1);
      svn_boolean_t end;
      apr_off_t max_offset
        = APR_ALIGN(info_baton.entry.offset + info_baton.entry.size,
                    ffd->block_size);
      apr_off_t min_offset = max_offset - ffd->block_size;

      /* read the relevant page */
      SVN_ERR(get_l2p_page(&page, rev_file, fs, info_baton.first_revision,
                           &info_baton.entry, scratch_pool));

      /* cache the page and extract the result we need */
      SVN_ERR(svn_cache__set(ffd->l2p_page_cache, &key, page, scratch_pool));
      SVN_ERR(l2p_page_get_entry(&page_baton, page, page->offsets,
                                 scratch_pool));

      if (ffd->use_block_read)
        {
          apr_pool_t *iterpool = svn_pool_create(scratch_pool);

          /* prefetch pages from following and preceding revisions */
          pages = apr_array_make(scratch_pool, 16,
                                 sizeof(l2p_page_table_entry_t));
          end = FALSE;
          for (prefetch_revision = revision;
              prefetch_revision < last_revision && !end;
              ++prefetch_revision)
            {
              int excluded_page_no = prefetch_revision == revision
                                  ? info_baton.page_no
                                  : -1;
              svn_pool_clear(iterpool);

              SVN_ERR(prefetch_l2p_pages(&end, fs, rev_file,
                                        info_baton.first_revision,
                                        prefetch_revision, pages,
                                        excluded_page_no, min_offset,
                                        max_offset, iterpool));
            }

          end = FALSE;
          for (prefetch_revision = revision-1;
              prefetch_revision >= info_baton.first_revision && !end;
              --prefetch_revision)
            {
              svn_pool_clear(iterpool);

              SVN_ERR(prefetch_l2p_pages(&end, fs, rev_file,
                                        info_baton.first_revision,
                                        prefetch_revision, pages, -1,
                                        min_offset, max_offset, iterpool));
            }

          svn_pool_destroy(iterpool);
        }
    }

  *offset = page_baton.offset;

  return SVN_NO_ERROR;
}

/* Using the log-to-phys proto index in transaction TXN_ID in FS, find the
 * absolute offset in the proto rev file for the given ITEM_INDEX and return
 * it in *OFFSET.  Use SCRATCH_POOL for temporary allocations.
 */
static svn_error_t *
l2p_proto_index_lookup(apr_off_t *offset,
                       svn_fs_t *fs,
                       const svn_fs_fs__id_part_t *txn_id,
                       apr_uint64_t item_index,
                       apr_pool_t *scratch_pool)
{
  svn_boolean_t eof = FALSE;
  apr_file_t *file = NULL;
  SVN_ERR(svn_io_file_open(&file,
                           svn_fs_fs__path_l2p_proto_index(fs, txn_id,
                                                           scratch_pool),
                           APR_READ | APR_BUFFERED, APR_OS_DEFAULT,
                           scratch_pool));

  /* process all entries until we fail due to EOF */
  *offset = -1;
  while (!eof)
    {
      l2p_proto_entry_t entry;

      /* (attempt to) read the next entry from the source */
      SVN_ERR(read_l2p_entry_from_proto_index(file, &entry, &eof,
                                              scratch_pool));

      /* handle new revision */
      if (!eof && entry.item_index == item_index)
        {
          *offset = (apr_off_t)entry.offset - 1;
          break;
        }
    }

  SVN_ERR(svn_io_file_close(file, scratch_pool));

  return SVN_NO_ERROR;
}

/* Read the log-to-phys header info of the index covering REVISION from FS
 * and return it in *HEADER.  REV_FILE provides the pack / rev status.
 * Allocate *HEADER in RESULT_POOL, use SCRATCH_POOL for temporary
 * allocations.
 */
static svn_error_t *
get_l2p_header(l2p_header_t **header,
               svn_fs_fs__revision_file_t *rev_file,
               svn_fs_t *fs,
               svn_revnum_t revision,
               apr_pool_t *result_pool,
               apr_pool_t *scratch_pool)
{
  fs_fs_data_t *ffd = fs->fsap_data;
  svn_boolean_t is_cached = FALSE;

  /* first, try cache lookop */
  pair_cache_key_t key;
  key.revision = rev_file->start_revision;
  key.second = rev_file->is_packed;
  SVN_ERR(svn_cache__get((void**)header, &is_cached, ffd->l2p_header_cache,
                         &key, result_pool));
  if (is_cached)
    return SVN_NO_ERROR;

  /* read from disk and cache the result */
  SVN_ERR(get_l2p_header_body(header, rev_file, fs, revision, result_pool,
                              scratch_pool));

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_fs__l2p_get_max_ids(apr_array_header_t **max_ids,
                           svn_fs_t *fs,
                           svn_revnum_t start_rev,
                           apr_size_t count,
                           apr_pool_t *result_pool,
                           apr_pool_t *scratch_pool)
{
  l2p_header_t *header = NULL;
  svn_revnum_t revision;
  svn_revnum_t last_rev = (svn_revnum_t)(start_rev + count);
  svn_fs_fs__revision_file_t *rev_file;
  apr_pool_t *header_pool = svn_pool_create(scratch_pool);

  /* read index master data structure for the index covering START_REV */
  SVN_ERR(svn_fs_fs__open_pack_or_rev_file(&rev_file, fs, start_rev,
                                           header_pool, header_pool));
  SVN_ERR(get_l2p_header(&header, rev_file, fs, start_rev, header_pool,
                         header_pool));
  SVN_ERR(svn_fs_fs__close_revision_file(rev_file));

  /* Determine the length of the item index list for each rev.
   * Read new index headers as required. */
  *max_ids = apr_array_make(result_pool, (int)count, sizeof(apr_uint64_t));
  for (revision = start_rev; revision < last_rev; ++revision)
    {
      apr_uint64_t full_page_count;
      apr_uint64_t item_count;
      apr_size_t first_page_index, last_page_index;

      if (revision - header->first_revision >= header->revision_count)
        {
          /* need to read the next index. Clear up memory used for the
           * previous one.  Note that intermittent pack runs do not change
           * the number of items in a revision, i.e. there is no consistency
           * issue here. */
          svn_pool_clear(header_pool);
          SVN_ERR(svn_fs_fs__open_pack_or_rev_file(&rev_file, fs, revision,
                                                  header_pool, header_pool));
          SVN_ERR(get_l2p_header(&header, rev_file, fs, revision,
                                 header_pool, header_pool));
          SVN_ERR(svn_fs_fs__close_revision_file(rev_file));
        }

      /* in a revision with N index pages, the first N-1 index pages are
       * "full", i.e. contain HEADER->PAGE_SIZE entries */
      first_page_index
         = header->page_table_index[revision - header->first_revision];
      last_page_index
         = header->page_table_index[revision - header->first_revision + 1];
      full_page_count = last_page_index - first_page_index - 1;
      item_count = full_page_count * header->page_size
                 + header->page_table[last_page_index - 1].entry_count;

      APR_ARRAY_PUSH(*max_ids, apr_uint64_t) = item_count;
    }

  svn_pool_destroy(header_pool);
  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_fs__item_offset(apr_off_t *absolute_position,
                       svn_fs_t *fs,
                       svn_fs_fs__revision_file_t *rev_file,
                       svn_revnum_t revision,
                       const svn_fs_fs__id_part_t *txn_id,
                       apr_uint64_t item_index,
                       apr_pool_t *scratch_pool)
{
  svn_error_t *err = SVN_NO_ERROR;
  if (txn_id)
    {
      if (svn_fs_fs__use_log_addressing(fs))
        {
          /* the txn is going to produce a rev with logical addressing.
             So, we need to get our info from the (proto) index file. */
          SVN_ERR(l2p_proto_index_lookup(absolute_position, fs, txn_id,
                                         item_index, scratch_pool));
        }
      else
        {
          /* for data in txns, item_index *is* the offset */
          *absolute_position = item_index;
        }
    }
  else if (svn_fs_fs__use_log_addressing(fs))
    {
      /* ordinary index lookup */
      SVN_ERR(l2p_index_lookup(absolute_position, fs, rev_file, revision,
                               item_index, scratch_pool));
    }
  else if (rev_file->is_packed)
    {
      /* pack file with physical addressing */
      apr_off_t rev_offset;
      SVN_ERR(svn_fs_fs__get_packed_offset(&rev_offset, fs, revision,
                                           scratch_pool));
      *absolute_position = rev_offset + item_index;
    }
  else
    {
      /* for non-packed revs with physical addressing,
         item_index *is* the offset */
      *absolute_position = item_index;
    }

  return svn_error_trace(err);
}

/*
 * phys-to-log index
 */
svn_error_t *
svn_fs_fs__p2l_proto_index_open(apr_file_t **proto_index,
                                const char *file_name,
                                apr_pool_t *result_pool)
{
  SVN_ERR(svn_io_file_open(proto_index, file_name, APR_READ | APR_WRITE
                           | APR_CREATE | APR_APPEND | APR_BUFFERED,
                           APR_OS_DEFAULT, result_pool));

  return SVN_NO_ERROR;
}


svn_error_t *
svn_fs_fs__p2l_proto_index_add_entry(apr_file_t *proto_index,
                                     const svn_fs_fs__p2l_entry_t *entry,
                                     apr_pool_t *scratch_pool)
{
  apr_uint64_t revision;

  /* Make sure all signed elements of ENTRY have non-negative values.
   *
   * For file offsets and sizes, this is a given as we use them to describe
   * absolute positions and sizes.  For revisions, SVN_INVALID_REVNUM is
   * valid, hence we have to shift it by 1.
   */
  SVN_ERR_ASSERT(entry->offset >= 0);
  SVN_ERR_ASSERT(entry->size >= 0);
  SVN_ERR_ASSERT(   entry->item.revision >= 0
                 || entry->item.revision == SVN_INVALID_REVNUM);

  revision = entry->item.revision == SVN_INVALID_REVNUM
           ? 0
           : ((apr_uint64_t)entry->item.revision + 1);

  /* Now, all values will nicely convert to uint64. */
  /* Make sure to keep P2L_PROTO_INDEX_ENTRY_SIZE consistent with this: */

  SVN_ERR(write_uint64_to_proto_index(proto_index, entry->offset,
                                      scratch_pool));
  SVN_ERR(write_uint64_to_proto_index(proto_index, entry->size,
                                      scratch_pool));
  SVN_ERR(write_uint64_to_proto_index(proto_index, entry->type,
                                      scratch_pool));
  SVN_ERR(write_uint64_to_proto_index(proto_index, entry->fnv1_checksum,
                                      scratch_pool));
  SVN_ERR(write_uint64_to_proto_index(proto_index, revision,
                                      scratch_pool));
  SVN_ERR(write_uint64_to_proto_index(proto_index, entry->item.number,
                                      scratch_pool));

  return SVN_NO_ERROR;
}

/* Read *ENTRY from log-to-phys PROTO_INDEX file and indicate end-of-file
 * in *EOF, or error out in that case if EOF is NULL.  *ENTRY is in an
 * undefined state if an end-of-file occurred.
 * Use SCRATCH_POOL for temporary allocations.
 */
static svn_error_t *
read_p2l_entry_from_proto_index(apr_file_t *proto_index,
                                svn_fs_fs__p2l_entry_t *entry,
                                svn_boolean_t *eof,
                                apr_pool_t *scratch_pool)
{
  apr_uint64_t revision;

  SVN_ERR(read_off_t_from_proto_index(proto_index, &entry->offset,
                                      eof, scratch_pool));
  SVN_ERR(read_off_t_from_proto_index(proto_index, &entry->size,
                                      eof, scratch_pool));
  SVN_ERR(read_uint32_from_proto_index(proto_index, &entry->type,
                                       eof, scratch_pool));
  SVN_ERR(read_uint32_from_proto_index(proto_index, &entry->fnv1_checksum,
                                       eof, scratch_pool));
  SVN_ERR(read_uint64_from_proto_index(proto_index, &revision,
                                       eof, scratch_pool));
  SVN_ERR(read_uint64_from_proto_index(proto_index, &entry->item.number,
                                       eof, scratch_pool));

  /* Do the inverse REVSION number conversion (see
   * svn_fs_fs__p2l_proto_index_add_entry), if we actually read a complete
   * record.
   */
  if (!eof || !*eof)
    {
      /* Be careful with the arithmetics here (overflows and wrap-around): */
      if (revision > 0 && revision - 1 > LONG_MAX)
        return svn_error_createf(SVN_ERR_FS_INDEX_OVERFLOW, NULL,
                                _("Revision 0x%s too large, max = 0x%s"),
                                apr_psprintf(scratch_pool,
                                             "%" APR_UINT64_T_HEX_FMT,
                                             revision),
                                apr_psprintf(scratch_pool,
                                             "%" APR_UINT64_T_HEX_FMT,
                                             (apr_uint64_t)LONG_MAX));

      /* Shortening conversion from unsigned to signed int is well-defined
       * and not lossy in C because the value can be represented in the
       * target type.  Also, cast to 'long' instead of 'svn_revnum_t' here
       * to provoke a compiler warning if those types should differ and we
       * would need to change the overflow checking logic.
       */
      entry->item.revision = revision == 0
                           ? SVN_INVALID_REVNUM
                           : (long)(revision - 1);
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_fs__p2l_proto_index_next_offset(apr_off_t *next_offset,
                                       apr_file_t *proto_index,
                                       apr_pool_t *scratch_pool)
{
  apr_off_t offset = 0;

  /* Empty index file? */
  SVN_ERR(svn_io_file_seek(proto_index, APR_END, &offset, scratch_pool));
  if (offset == 0)
    {
      *next_offset = 0;
    }
  else
    {
      /* At least one entry.  Read last entry. */
      svn_fs_fs__p2l_entry_t entry;
      offset -= P2L_PROTO_INDEX_ENTRY_SIZE;

      SVN_ERR(svn_io_file_seek(proto_index, APR_SET, &offset, scratch_pool));
      SVN_ERR(read_p2l_entry_from_proto_index(proto_index, &entry,
                                              NULL, scratch_pool));

      /* Return next offset. */
      *next_offset = entry.offset + entry.size;
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_fs__p2l_index_append(svn_checksum_t **checksum,
                            svn_fs_t *fs,
                            apr_file_t *index_file,
                            const char *proto_file_name,
                            svn_revnum_t revision,
                            apr_pool_t *result_pool,
                            apr_pool_t *scratch_pool)
{
  fs_fs_data_t *ffd = fs->fsap_data;
  apr_uint64_t page_size = ffd->p2l_page_size;
  apr_file_t *proto_index = NULL;
  svn_stream_t *stream;
  int i;
  svn_boolean_t eof = FALSE;
  unsigned char encoded[ENCODED_INT_LENGTH];
  svn_revnum_t last_revision = revision;
  apr_uint64_t last_compound = 0;

  apr_uint64_t last_entry_end = 0;
  apr_uint64_t last_page_end = 0;
  apr_uint64_t last_buffer_size = 0;  /* byte offset in the spill buffer at
                                         the begin of the current revision */
  apr_uint64_t file_size = 0;

  /* temporary data structures that collect the data which will be moved
     to the target file in a second step */
  apr_pool_t *local_pool = svn_pool_create(scratch_pool);
  apr_array_header_t *table_sizes
     = apr_array_make(local_pool, 16, sizeof(apr_uint64_t));

  /* 64k blocks, spill after 16MB */
  svn_spillbuf_t *buffer
     = svn_spillbuf__create(0x10000, 0x1000000, local_pool);

  /* for loop temps ... */
  apr_pool_t *iterpool = svn_pool_create(scratch_pool);

  /* start at the beginning of the source file */
  SVN_ERR(svn_io_file_open(&proto_index, proto_file_name,
                           APR_READ | APR_CREATE | APR_BUFFERED,
                           APR_OS_DEFAULT, scratch_pool));

  /* process all entries until we fail due to EOF */
  while (!eof)
    {
      svn_fs_fs__p2l_entry_t entry;
      apr_uint64_t entry_end;
      svn_boolean_t new_page = svn_spillbuf__get_size(buffer) == 0;
      apr_uint64_t compound;
      apr_int64_t rev_diff, compound_diff;

      svn_pool_clear(iterpool);

      /* (attempt to) read the next entry from the source */
      SVN_ERR(read_p2l_entry_from_proto_index(proto_index, &entry,
                                              &eof, iterpool));

      /* "unused" (and usually non-existent) section to cover the offsets
         at the end the of the last page. */
      if (eof)
        {
          file_size = last_entry_end;

          entry.offset = last_entry_end;
          entry.size = APR_ALIGN(entry.offset, page_size) - entry.offset;
          entry.type = SVN_FS_FS__ITEM_TYPE_UNUSED;
          entry.fnv1_checksum = 0;
          entry.item.revision = last_revision;
          entry.item.number = 0;
        }
      else
        {
          /* fix-up items created when the txn's target rev was unknown */
          if (entry.item.revision == SVN_INVALID_REVNUM)
            entry.item.revision = revision;
        }

      /* end pages if entry is extending beyond their boundaries */
      entry_end = entry.offset + entry.size;
      while (entry_end - last_page_end > page_size)
        {
          apr_uint64_t buffer_size = svn_spillbuf__get_size(buffer);
          APR_ARRAY_PUSH(table_sizes, apr_uint64_t)
             = buffer_size - last_buffer_size;

          last_buffer_size = buffer_size;
          last_page_end += page_size;
          new_page = TRUE;
        }

      /* this entry starts a new table -> store its offset
         (all following entries in the same table will store sizes only) */
      if (new_page)
        {
          SVN_ERR(svn_spillbuf__write(buffer, (const char *)encoded,
                                      encode_uint(encoded, entry.offset),
                                      iterpool));
          last_revision = revision;
          last_compound = 0;
        }

      /* write simple item entry */
      SVN_ERR(svn_spillbuf__write(buffer, (const char *)encoded,
                                  encode_uint(encoded, entry.size),
                                  iterpool));

      rev_diff = entry.item.revision - last_revision;
      last_revision = entry.item.revision;

      compound = entry.item.number * 8 + entry.type;
      compound_diff = compound - last_compound;
      last_compound = compound;

      SVN_ERR(svn_spillbuf__write(buffer, (const char *)encoded,
                                  encode_int(encoded, compound_diff),
                                  iterpool));
      SVN_ERR(svn_spillbuf__write(buffer, (const char *)encoded,
                                  encode_int(encoded, rev_diff),
                                  iterpool));
      SVN_ERR(svn_spillbuf__write(buffer, (const char *)encoded,
                                  encode_uint(encoded, entry.fnv1_checksum),
                                  iterpool));

      last_entry_end = entry_end;
    }

  /* close the source file */
  SVN_ERR(svn_io_file_close(proto_index, local_pool));

  /* store length of last table */
  APR_ARRAY_PUSH(table_sizes, apr_uint64_t)
      = svn_spillbuf__get_size(buffer) - last_buffer_size;

  /* Open target stream. */
  stream = svn_stream_checksummed2(svn_stream_from_aprfile2(index_file, TRUE,
                                                            local_pool),
                                   NULL, checksum, svn_checksum_md5, FALSE,
                                   result_pool);

  /* write the start revision, file size and page size */
  SVN_ERR(svn_stream_puts(stream, P2L_STREAM_PREFIX));
  SVN_ERR(stream_write_encoded(stream, revision));
  SVN_ERR(stream_write_encoded(stream, file_size));
  SVN_ERR(stream_write_encoded(stream, page_size));

  /* write the page table (actually, the sizes of each page description) */
  SVN_ERR(stream_write_encoded(stream, table_sizes->nelts));
  for (i = 0; i < table_sizes->nelts; ++i)
    {
      apr_uint64_t value = APR_ARRAY_IDX(table_sizes, i, apr_uint64_t);
      SVN_ERR(stream_write_encoded(stream, value));
    }

  /* append page contents and implicitly close STREAM */
  SVN_ERR(svn_stream_copy3(svn_stream__from_spillbuf(buffer, local_pool),
                           stream, NULL, NULL, local_pool));

  svn_pool_destroy(iterpool);
  svn_pool_destroy(local_pool);

  return SVN_NO_ERROR;
}

/* If REV_FILE->P2L_STREAM is NULL, create a new stream for the phys-to-log
 * index for REVISION in FS using the rev / pack file provided by REV_FILE.
 */
static svn_error_t *
auto_open_p2l_index(svn_fs_fs__revision_file_t *rev_file,
                    svn_fs_t *fs,
                    svn_revnum_t revision)
{
  if (rev_file->p2l_stream == NULL)
    {
      fs_fs_data_t *ffd = fs->fsap_data;

      SVN_ERR(svn_fs_fs__auto_read_footer(rev_file));
      SVN_ERR(packed_stream_open(&rev_file->p2l_stream,
                                 rev_file->file,
                                 rev_file->p2l_offset,
                                 rev_file->footer_offset,
                                 P2L_STREAM_PREFIX,
                                 (apr_size_t)ffd->block_size,
                                 rev_file->pool,
                                 rev_file->pool));
    }

  return SVN_NO_ERROR;
}


/* Read the header data structure of the phys-to-log index for REVISION in
 * FS and return it in *HEADER, allocated in RESULT_POOL. Use REV_FILE to
 * access on-disk data.  Use SCRATCH_POOL for temporary allocations.
 */
static svn_error_t *
get_p2l_header(p2l_header_t **header,
               svn_fs_fs__revision_file_t *rev_file,
               svn_fs_t *fs,
               svn_revnum_t revision,
               apr_pool_t *result_pool,
               apr_pool_t *scratch_pool)
{
  fs_fs_data_t *ffd = fs->fsap_data;
  apr_uint64_t value;
  apr_size_t i;
  apr_off_t offset;
  p2l_header_t *result;
  svn_boolean_t is_cached = FALSE;

  /* look for the header data in our cache */
  pair_cache_key_t key;
  key.revision = rev_file->start_revision;
  key.second = rev_file->is_packed;

  SVN_ERR(svn_cache__get((void**)header, &is_cached, ffd->p2l_header_cache,
                         &key, result_pool));
  if (is_cached)
    return SVN_NO_ERROR;

  /* not found -> must read it from disk.
   * Open index file or position read pointer to the begin of the file */
  if (rev_file->p2l_stream == NULL)
    SVN_ERR(auto_open_p2l_index(rev_file, fs, rev_file->start_revision));
  else
    packed_stream_seek(rev_file->p2l_stream, 0);

  /* allocate result data structure */
  result = apr_pcalloc(result_pool, sizeof(*result));

  /* Read table sizes, check them for plausibility and allocate page array. */
  SVN_ERR(packed_stream_get(&value, rev_file->p2l_stream));
  result->first_revision = (svn_revnum_t)value;
  if (result->first_revision != rev_file->start_revision)
    return svn_error_create(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
                  _("Index rev / pack file revision numbers do not match"));

  SVN_ERR(packed_stream_get(&value, rev_file->p2l_stream));
  result->file_size = value;
  if (result->file_size != (apr_uint64_t)rev_file->l2p_offset)
    return svn_error_create(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
                   _("Index offset and rev / pack file size do not match"));

  SVN_ERR(packed_stream_get(&value, rev_file->p2l_stream));
  result->page_size = value;
  if (!result->page_size || (result->page_size & (result->page_size - 1)))
    return svn_error_create(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
                            _("P2L index page size is not a power of two"));

  SVN_ERR(packed_stream_get(&value, rev_file->p2l_stream));
  result->page_count = (apr_size_t)value;
  if (result->page_count != (result->file_size - 1) / result->page_size + 1)
    return svn_error_create(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
                   _("P2L page count does not match rev / pack file size"));

  result->offsets
    = apr_pcalloc(result_pool, (result->page_count + 1) * sizeof(*result->offsets));

  /* read page sizes and derive page description offsets from them */
  result->offsets[0] = 0;
  for (i = 0; i < result->page_count; ++i)
    {
      SVN_ERR(packed_stream_get(&value, rev_file->p2l_stream));
      result->offsets[i+1] = result->offsets[i] + (apr_off_t)value;
    }

  /* correct the offset values */
  offset = packed_stream_offset(rev_file->p2l_stream);
  for (i = 0; i <= result->page_count; ++i)
    result->offsets[i] += offset;

  /* cache the header data */
  SVN_ERR(svn_cache__set(ffd->p2l_header_cache, &key, result, scratch_pool));

  /* return the result */
  *header = result;

  return SVN_NO_ERROR;
}

/* Data structure that describes which p2l page info shall be extracted
 * from the cache and contains the fields that receive the result.
 */
typedef struct p2l_page_info_baton_t
{
  /* input variables */
  /* revision identifying the index file */
  svn_revnum_t revision;

  /* offset within the page in rev / pack file */
  apr_off_t offset;

  /* output variables */
  /* page containing OFFSET */
  apr_size_t page_no;

  /* first revision in this p2l index */
  svn_revnum_t first_revision;

  /* offset within the p2l index file describing this page */
  apr_off_t start_offset;

  /* offset within the p2l index file describing the following page */
  apr_off_t next_offset;

  /* PAGE_NO * PAGE_SIZE (if <= OFFSET) */
  apr_off_t page_start;

  /* total number of pages indexed */
  apr_size_t page_count;

  /* size of each page in pack / rev file */
  apr_uint64_t page_size;
} p2l_page_info_baton_t;

/* From HEADER and the list of all OFFSETS, fill BATON with the page info
 * requested by BATON->OFFSET.
 */
static void
p2l_page_info_copy(p2l_page_info_baton_t *baton,
                   const p2l_header_t *header,
                   const apr_off_t *offsets)
{
  /* if the requested offset is out of bounds, return info for
   * a zero-sized empty page right behind the last page.
   */
  if (baton->offset / header->page_size < header->page_count)
    {
      /* This cast is safe because the value is < header->page_count. */
      baton->page_no = (apr_size_t)(baton->offset / header->page_size);
      baton->start_offset = offsets[baton->page_no];
      baton->next_offset = offsets[baton->page_no + 1];
      baton->page_size = header->page_size;
    }
  else
    {
      /* Beyond the last page. */
      baton->page_no = header->page_count;
      baton->start_offset = offsets[baton->page_no];
      baton->next_offset = offsets[baton->page_no];
      baton->page_size = 0;
    }

  baton->first_revision = header->first_revision;
  baton->page_start = (apr_off_t)(header->page_size * baton->page_no);
  baton->page_count = header->page_count;
}

/* Implement svn_cache__partial_getter_func_t: extract the p2l page info
 * requested by BATON and return it in BATON.
 */
static svn_error_t *
p2l_page_info_func(void **out,
                   const void *data,
                   apr_size_t data_len,
                   void *baton,
                   apr_pool_t *result_pool)
{
  /* all the pointers to cached data we need */
  const p2l_header_t *header = data;
  const apr_off_t *offsets
    = svn_temp_deserializer__ptr(header,
                                 (const void *const *)&header->offsets);

  /* copy data from cache to BATON */
  p2l_page_info_copy(baton, header, offsets);
  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.  Use REV_FILE
 * to access on-disk data.  Use SCRATCH_POOL for temporary allocations.
 */
static svn_error_t *
get_p2l_page_info(p2l_page_info_baton_t *baton,
                  svn_fs_fs__revision_file_t *rev_file,
                  svn_fs_t *fs,
                  apr_pool_t *scratch_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 = rev_file->start_revision;
  key.second = rev_file->is_packed;

  SVN_ERR(svn_cache__get_partial(&dummy, &is_cached, ffd->p2l_header_cache,
                                 &key, p2l_page_info_func, baton,
                                 scratch_pool));
  if (is_cached)
    return SVN_NO_ERROR;

  SVN_ERR(get_p2l_header(&header, rev_file, fs, baton->revision,
                         scratch_pool, scratch_pool));

  /* copy the requested info into *BATON */
  p2l_page_info_copy(baton, header, header->offsets);

  return SVN_NO_ERROR;
}

/* Read a mapping entry from the phys-to-log index STREAM and append it to
 * RESULT.  *ITEM_INDEX contains the phys offset for the entry and will
 * be moved forward by the size of entry.
 */
static svn_error_t *
read_entry(svn_fs_fs__packed_number_stream_t *stream,
           apr_off_t *item_offset,
           svn_revnum_t *last_revision,
           apr_uint64_t *last_compound,
           apr_array_header_t *result)
{
  apr_uint64_t value;

  svn_fs_fs__p2l_entry_t entry;

  entry.offset = *item_offset;
  SVN_ERR(packed_stream_get(&value, stream));
  entry.size = (apr_off_t)value;

  SVN_ERR(packed_stream_get(&value, stream));
  *last_compound += decode_int(value);

  entry.type = *last_compound & 7;
  entry.item.number = *last_compound / 8;

  /* Verify item type. */
  if (entry.type > SVN_FS_FS__ITEM_TYPE_CHANGES)
    return svn_error_create(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
                            _("Invalid item type in P2L index"));
  if (   entry.type == SVN_FS_FS__ITEM_TYPE_CHANGES
      && entry.item.number != SVN_FS_FS__ITEM_INDEX_CHANGES)
    return svn_error_create(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
                            _("Changed path list must have item number 1"));

  SVN_ERR(packed_stream_get(&value, stream));
  *last_revision += (svn_revnum_t)decode_int(value);
  entry.item.revision = *last_revision;

  SVN_ERR(packed_stream_get(&value, stream));
  entry.fnv1_checksum = (apr_uint32_t)value;

  /* Truncating the checksum to 32 bits may have hidden random data in the
   * unused extra bits of the on-disk representation (7/8 bit representation
   * uses 5 bytes on disk for the 32 bit value, leaving 3 bits unused). */
  if (value > APR_UINT32_MAX)
    return svn_error_create(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
                            _("Invalid FNV1 checksum in P2L index"));

  /* Some of the index data for empty rev / pack file sections will not be
   * used during normal operation.  Thus, we have strict rules for the
   * contents of those unused fields. */
  if (entry.type == SVN_FS_FS__ITEM_TYPE_UNUSED)
    if (   entry.item.number != SVN_FS_FS__ITEM_INDEX_UNUSED
        || entry.fnv1_checksum != 0)
      return svn_error_create(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
                 _("Empty regions must have item number 0 and checksum 0"));

  /* Corrupted SIZE values might cause arithmetic overflow.
   * The same can happen if you copy a repository from a system with 63 bit
   * file lengths to one with 31 bit file lengths. */
  if ((apr_uint64_t)entry.offset + (apr_uint64_t)entry.size > off_t_max)
    return svn_error_create(SVN_ERR_FS_INDEX_OVERFLOW , NULL,
                            _("P2L index entry size overflow."));

  APR_ARRAY_PUSH(result, svn_fs_fs__p2l_entry_t) = entry;
  *item_offset += entry.size;

  return SVN_NO_ERROR;
}

/* Read the phys-to-log mappings for the cluster beginning at rev file
 * offset PAGE_START from the index for START_REVISION in FS.  The data
 * can be found in the index page beginning at START_OFFSET with the next
 * page beginning at NEXT_OFFSET.  PAGE_SIZE is the L2P index page size.
 * Return the relevant index entries in *ENTRIES.  Use REV_FILE to access
 * on-disk data.  Allocate *ENTRIES in RESULT_POOL.
 */
static svn_error_t *
get_p2l_page(apr_array_header_t **entries,
             svn_fs_fs__revision_file_t *rev_file,
             svn_fs_t *fs,
             svn_revnum_t start_revision,
             apr_off_t start_offset,
             apr_off_t next_offset,
             apr_off_t page_start,
             apr_uint64_t page_size,
             apr_pool_t *result_pool)
{
  apr_uint64_t value;
  apr_array_header_t *result
    = apr_array_make(result_pool, 16, sizeof(svn_fs_fs__p2l_entry_t));
  apr_off_t item_offset;
  apr_off_t offset;
  svn_revnum_t last_revision;
  apr_uint64_t last_compound;

  /* open index and navigate to page start */
  SVN_ERR(auto_open_p2l_index(rev_file, fs, start_revision));
  packed_stream_seek(rev_file->p2l_stream, start_offset);

  /* read rev file offset of the first page entry (all page entries will
   * only store their sizes). */
  SVN_ERR(packed_stream_get(&value, rev_file->p2l_stream));
  item_offset = (apr_off_t)value;

  /* read all entries of this page */
  last_revision = start_revision;
  last_compound = 0;

  /* Special case: empty pages. */
  if (start_offset == next_offset)
    {
      /* Empty page. This only happens if the first entry of the next page
       * also covers this page (and possibly more) completely. */
      SVN_ERR(read_entry(rev_file->p2l_stream, &item_offset,
                         &last_revision, &last_compound, result));
    }
  else
    {
      /* Read non-empty page. */
      do
        {
          SVN_ERR(read_entry(rev_file->p2l_stream, &item_offset,
                             &last_revision, &last_compound, result));
          offset = packed_stream_offset(rev_file->p2l_stream);
        }
      while (offset < next_offset);

      /* We should now be exactly at the next offset, i.e. the numbers in
       * the stream cannot overlap into the next page description. */
      if (offset != next_offset)
        return svn_error_create(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
             _("P2L page description overlaps with next page description"));

      /* if we haven't covered the cluster end yet, we must read the first
       * entry of the next page */
      if (item_offset < page_start + page_size)
        {
          SVN_ERR(packed_stream_get(&value, rev_file->p2l_stream));
          item_offset = (apr_off_t)value;
          last_revision = start_revision;
          last_compound = 0;
          SVN_ERR(read_entry(rev_file->p2l_stream, &item_offset,
                             &last_revision, &last_compound, result));
        }
    }

  *entries = result;

  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.  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 already in the
 * cache, decrease *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 };

  /* fetch the page info */
  *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)
    {
      /* page outside limits -> stop prefetching */
      *end = TRUE;
      return SVN_NO_ERROR;
    }

  /* do we have that page in our caches already? */
  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));

  /* yes, already cached */
  if (already_cached)
    {
      /* stop prefetching if most pages are already cached. */
      if (!--*leaking_bucket)
        *end = TRUE;

      return SVN_NO_ERROR;
    }

  ++*leaking_bucket;

  /* read from disk */
  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));

  /* and put it into our cache */
  SVN_ERR(svn_cache__set(ffd->p2l_page_cache, &key, page, scratch_pool));

  return SVN_NO_ERROR;
}

/* 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 REV_FILE.  Use SCRATCH_POOL for temporary
 * 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,
             svn_fs_fs__revision_file_t *rev_file,
             svn_fs_t *fs,
             svn_revnum_t revision,
             apr_off_t offset,
             apr_pool_t *scratch_pool)
{
  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, rev_file, fs, scratch_pool));

  /* if the offset refers to a non-existent page, bail out */
  if (page_info.page_count <= page_info.page_no)
    return svn_error_createf(SVN_ERR_FS_INDEX_OVERFLOW , NULL,
                              _("Offset %s too large in revision %ld"),
                              apr_off_t_toa(scratch_pool, offset), revision);

  /* 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 };
      assert(page_info.first_revision <= APR_UINT32_MAX);
      key.revision = (apr_uint32_t)page_info.first_revision;
      key.is_packed = rev_file->is_packed;
      key.page = page_info.page_no;

      *key_p = key;
    }

  return SVN_NO_ERROR;
}

/* qsort-compatible compare function that compares the OFFSET of the
 * svn_fs_fs__p2l_entry_t in *LHS with the apr_off_t in *RHS. */
static int
compare_start_p2l_entry(const void *lhs,
                        const void *rhs)
{
  const svn_fs_fs__p2l_entry_t *entry = lhs;
  apr_off_t start = *(const apr_off_t*)rhs;
  apr_off_t diff = entry->offset - start;

  /* restrict result to int */
  return diff < 0 ? -1 : (diff == 0 ? 0 : 1);
}

/* From the PAGE_ENTRIES array of svn_fs_fs__p2l_entry_t, ordered
 * by their OFFSET member, copy all elements overlapping the range
 * [BLOCK_START, BLOCK_END) to ENTRIES. */
static void
append_p2l_entries(apr_array_header_t *entries,
                   apr_array_header_t *page_entries,
                   apr_off_t block_start,
                   apr_off_t block_end)
{
  const svn_fs_fs__p2l_entry_t *entry;
  int idx = svn_sort__bsearch_lower_bound(page_entries, &block_start,
                                          compare_start_p2l_entry);

  /* start at the first entry that overlaps with BLOCK_START */
  if (idx > 0)
    {
      entry = &APR_ARRAY_IDX(page_entries, idx - 1, svn_fs_fs__p2l_entry_t);
      if (entry->offset + entry->size > block_start)
        --idx;
    }

  /* copy all entries covering the requested range */
  for ( ; idx < page_entries->nelts; ++idx)
    {
      entry = &APR_ARRAY_IDX(page_entries, idx, svn_fs_fs__p2l_entry_t);
      if (entry->offset >= block_end)
        break;

      APR_ARRAY_PUSH(entries, svn_fs_fs__p2l_entry_t) = *entry;
    }
}

/* Auxiliary struct passed to p2l_entries_func selecting the relevant
 * data range. */
typedef struct p2l_entries_baton_t
{
  apr_off_t start;
  apr_off_t end;
} p2l_entries_baton_t;

/* Implement svn_cache__partial_getter_func_t: extract p2l entries from
 * the page in DATA which overlap the p2l_entries_baton_t in BATON.
 * The target array is already provided in *OUT.
 */
static svn_error_t *
p2l_entries_func(void **out,
                 const void *data,
                 apr_size_t data_len,
                 void *baton,
                 apr_pool_t *result_pool)
{
  apr_array_header_t *entries = *(apr_array_header_t **)out;
  const apr_array_header_t *raw_page = data;
  p2l_entries_baton_t *block = baton;

  /* Make PAGE a readable APR array. */
  apr_array_header_t page = *raw_page;
  page.elts = (void *)svn_temp_deserializer__ptr(raw_page,
                                    (const void * const *)&raw_page->elts);

  /* append relevant information to result */
  append_p2l_entries(entries, &page, block->start, block->end);

  return SVN_NO_ERROR;
}


/* Body of svn_fs_fs__p2l_index_lookup.  However, do a single index page
 * lookup and append the result to the ENTRIES array provided by the caller.
 * Use successive calls to cover larger ranges.
 */
static svn_error_t *
p2l_index_lookup(apr_array_header_t *entries,
                 svn_fs_fs__revision_file_t *rev_file,
                 svn_fs_t *fs,
                 svn_revnum_t revision,
                 apr_off_t block_start,
                 apr_off_t block_end,
                 apr_pool_t *scratch_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;
  apr_array_header_t *local_result = entries;

  /* baton selecting the relevant entries from the one page we access */
  p2l_entries_baton_t block;
  block.start = block_start;
  block.end = block_end;

  /* if we requested an empty range, the result would be empty */
  SVN_ERR_ASSERT(block_start < block_end);

  /* look for the fist page of the range in our cache */
  SVN_ERR(get_p2l_keys(&page_info, &key, rev_file, fs, revision, block_start,
                       scratch_pool));
  SVN_ERR(svn_cache__get_partial((void**)&local_result, &is_cached,
                                 ffd->p2l_page_cache, &key, p2l_entries_func,
                                 &block, scratch_pool));

  if (!is_cached)
    {
      svn_boolean_t end;
      apr_pool_t *iterpool = svn_pool_create(scratch_pool);
      apr_off_t original_page_start = page_info.page_start;
      int leaking_bucket = 4;
      p2l_page_info_baton_t prefetch_info = page_info;
      apr_array_header_t *page_entries;

      apr_off_t max_offset
        = APR_ALIGN(page_info.next_offset, ffd->block_size);
      apr_off_t min_offset
        = APR_ALIGN(page_info.start_offset, ffd->block_size) - ffd->block_size;

      /* Since we read index data in larger chunks, we probably got more
       * page data than we requested.  Parse & cache that until either we
       * encounter pages already cached or reach the end of the buffer.
       */

      /* pre-fetch preceding pages */
      if (ffd->use_block_read)
        {
          end = FALSE;
          prefetch_info.offset = original_page_start;
          while (prefetch_info.offset >= prefetch_info.page_size && !end)
            {
              svn_pool_clear(iterpool);

              prefetch_info.offset -= prefetch_info.page_size;
              SVN_ERR(prefetch_p2l_page(&end, &leaking_bucket, fs, rev_file,
                                        &prefetch_info, min_offset,
                                        iterpool));
            }
        }

      /* fetch page from disk and put it into the cache */
      SVN_ERR(get_p2l_page(&page_entries, rev_file, fs,
                           page_info.first_revision,
                           page_info.start_offset,
                           page_info.next_offset,
                           page_info.page_start,
                           page_info.page_size, iterpool));

      /* The last cache entry must not end beyond the range covered by
       * this index.  The same applies for any subset of entries. */
      if (page_entries->nelts)
        {
          const svn_fs_fs__p2l_entry_t *entry
            = &APR_ARRAY_IDX(page_entries, page_entries->nelts - 1,
                             svn_fs_fs__p2l_entry_t);
          if (  entry->offset + entry->size
              > page_info.page_size * page_info.page_count)
            return svn_error_createf(SVN_ERR_FS_INDEX_OVERFLOW , NULL,
                                     _("Last P2L index entry extends beyond "
                                       "the last page in revision %ld."),
                                     revision);
        }

      SVN_ERR(svn_cache__set(ffd->p2l_page_cache, &key, page_entries,
                             iterpool));

      /* append relevant information to result */
      append_p2l_entries(entries, page_entries, block_start, block_end);

      /* pre-fetch following pages */
      if (ffd->use_block_read)
        {
          end = FALSE;
          leaking_bucket = 4;
          prefetch_info = page_info;
          prefetch_info.offset = original_page_start;
          while (   prefetch_info.next_offset < max_offset
                && prefetch_info.page_no + 1 < prefetch_info.page_count
                && !end)
            {
              svn_pool_clear(iterpool);

              prefetch_info.offset += prefetch_info.page_size;
              SVN_ERR(prefetch_p2l_page(&end, &leaking_bucket, fs, rev_file,
                                        &prefetch_info, min_offset,
                                        iterpool));
            }
        }

      svn_pool_destroy(iterpool);
    }

  /* We access a valid page (otherwise, we had seen an error in the
   * get_p2l_keys request).  Hence, at least one entry must be found. */
  SVN_ERR_ASSERT(entries->nelts > 0);

  /* Add an "unused" entry if it extends beyond the end of the data file.
   * Since the index page size might be smaller than the current data
   * read block size, the trailing "unused" entry in this index may not
   * fully cover the end of the last block. */
  if (page_info.page_no + 1 >= page_info.page_count)
    {
      svn_fs_fs__p2l_entry_t *entry
        = &APR_ARRAY_IDX(entries, entries->nelts-1, svn_fs_fs__p2l_entry_t);

      apr_off_t entry_end = entry->offset + entry->size;
      if (entry_end < block_end)
        {
          if (entry->type == SVN_FS_FS__ITEM_TYPE_UNUSED)
            {
              /* extend the terminal filler */
              entry->size = block_end - entry->offset;
            }
          else
            {
              /* No terminal filler. Add one. */
              entry = apr_array_push(entries);
              entry->offset = entry_end;
              entry->size = block_end - entry_end;
              entry->type = SVN_FS_FS__ITEM_TYPE_UNUSED;
              entry->fnv1_checksum = 0;
              entry->item.revision = SVN_INVALID_REVNUM;
              entry->item.number = SVN_FS_FS__ITEM_INDEX_UNUSED;
            }
        }
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_fs__p2l_index_lookup(apr_array_header_t **entries,
                            svn_fs_t *fs,
                            svn_fs_fs__revision_file_t *rev_file,
                            svn_revnum_t revision,
                            apr_off_t block_start,
                            apr_off_t block_size,
                            apr_pool_t *result_pool,
                            apr_pool_t *scratch_pool)
{
  apr_off_t block_end = block_start + block_size;

  /* the receiving container */
  int last_count = 0;
  apr_array_header_t *result = apr_array_make(result_pool, 16,
                                              sizeof(svn_fs_fs__p2l_entry_t));

  /* Fetch entries page-by-page.  Since the p2l index is supposed to cover
   * every single byte in the rev / pack file - even unused sections -
   * every iteration must result in some progress. */
  while (block_start < block_end)
    {
      svn_fs_fs__p2l_entry_t *entry;
      SVN_ERR(p2l_index_lookup(result, rev_file, fs, revision, block_start,
                               block_end, scratch_pool));
      SVN_ERR_ASSERT(result->nelts > 0);

      /* continue directly behind last item */
      entry = &APR_ARRAY_IDX(result, result->nelts-1, svn_fs_fs__p2l_entry_t);
      block_start = entry->offset + entry->size;

      /* Some paranoia check.  Successive iterations should never return
       * duplicates but if it did, we might get into trouble later on. */
      if (last_count > 0 && last_count < result->nelts)
        {
           entry =  &APR_ARRAY_IDX(result, last_count - 1,
                                   svn_fs_fs__p2l_entry_t);
           SVN_ERR_ASSERT(APR_ARRAY_IDX(result, last_count,
                                        svn_fs_fs__p2l_entry_t).offset
                          >= entry->offset + entry->size);
        }

      last_count = result->nelts;
    }

  *entries = result;
  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,
 * allocated in RESULT_POOL, starting at OFFSET or NULL if that's not an
 * the start offset of any item. Use SCRATCH_POOL for temporary allocations.
 */
static svn_fs_fs__p2l_entry_t *
get_p2l_entry_from_cached_page(const void *data,
                               apr_uint64_t offset,
                               apr_pool_t *result_pool,
                               apr_pool_t *scratch_pool)
{
  /* resolve all pointer values of in-cache data */
  const apr_array_header_t *page = data;
  apr_array_header_t *entries = apr_pmemdup(scratch_pool, page,
                                            sizeof(*page));
  svn_fs_fs__p2l_entry_t *entry;

  entries->elts = (char *)svn_temp_deserializer__ptr(page,
                                     (const void *const *)&page->elts);

  /* search of the offset we want */
  entry = svn_sort__array_lookup(entries, &offset, NULL,
      (int (*)(const void *, const void *))compare_p2l_entry_offsets);

  /* return it, if it is a perfect match */
  return entry ? apr_pmemdup(result_pool, entry, sizeof(*entry)) : 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,
                                     result_pool);

  *out = entry && entry->offset == *(apr_off_t *)baton
       ? apr_pmemdup(result_pool, entry, sizeof(*entry))
       : NULL;

  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_fs_fs__revision_file_t *rev_file,
                            svn_revnum_t revision,
                            apr_off_t offset,
                            apr_pool_t *result_pool,
                            apr_pool_t *scratch_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, rev_file, fs, revision, offset,
                       scratch_pool));
  SVN_ERR(svn_cache__get_partial((void**)entry_p, &is_cached,
                                 ffd->p2l_page_cache, &key,
                                 p2l_entry_lookup_func, &offset,
                                 result_pool));
  if (!is_cached)
    {
      /* do a standard index lookup.  This is will automatically prefetch
       * data to speed up future lookups. */
      apr_array_header_t *entries = apr_array_make(result_pool, 1,
                                                   sizeof(**entry_p));
      SVN_ERR(p2l_index_lookup(entries, rev_file, fs, revision, offset,
                               offset + 1, scratch_pool));

      /* Find the entry that we want. */
      *entry_p = svn_sort__array_lookup(entries, &offset, NULL,
          (int (*)(const void *, const void *))compare_p2l_entry_offsets);
    }

  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->file_size;
  *out = apr_pmemdup(result_pool, &max_offset, sizeof(max_offset));

  return SVN_NO_ERROR;
}

/* Core functionality of to svn_fs_fs__p2l_get_max_offset with identical
 * signature. */
static svn_error_t *
p2l_get_max_offset(apr_off_t *offset,
                   svn_fs_t *fs,
                   svn_fs_fs__revision_file_t *rev_file,
                   svn_revnum_t revision,
                   apr_pool_t *scratch_pool)
{
  fs_fs_data_t *ffd = fs->fsap_data;
  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 = rev_file->start_revision;
  key.second = rev_file->is_packed;

  SVN_ERR(svn_cache__get_partial((void **)&offset_p, &is_cached,
                                 ffd->p2l_header_cache, &key,
                                 p2l_get_max_offset_func, NULL,
                                 scratch_pool));
  if (is_cached)
    {
      *offset = *offset_p;
      return SVN_NO_ERROR;
    }

  SVN_ERR(get_p2l_header(&header, rev_file, fs, revision, scratch_pool,
                         scratch_pool));
  *offset = header->file_size;

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_fs__p2l_get_max_offset(apr_off_t *offset,
                              svn_fs_t *fs,
                              svn_fs_fs__revision_file_t *rev_file,
                              svn_revnum_t revision,
                              apr_pool_t *scratch_pool)
{
  return svn_error_trace(p2l_get_max_offset(offset, fs, rev_file, revision,
                                            scratch_pool));
}

/* Calculate the FNV1 checksum over the offset range in REV_FILE, covered by
 * ENTRY.  Store the result in ENTRY->FNV1_CHECKSUM.  Use SCRATCH_POOL for
 * temporary allocations. */
static svn_error_t *
calc_fnv1(svn_fs_fs__p2l_entry_t *entry,
          svn_fs_fs__revision_file_t *rev_file,
          apr_pool_t *scratch_pool)
{
  unsigned char buffer[4096];
  svn_checksum_t *checksum;
  svn_checksum_ctx_t *context
    = svn_checksum_ctx_create(svn_checksum_fnv1a_32x4, scratch_pool);
  apr_off_t size = entry->size;

  /* Special rules apply to unused sections / items.  The data must be a
   * sequence of NUL bytes (not checked here) and the checksum is fixed to 0.
   */
  if (entry->type == SVN_FS_FS__ITEM_TYPE_UNUSED)
    {
      entry->fnv1_checksum = 0;
      return SVN_NO_ERROR;
    }

  /* Read the block and feed it to the checksum calculator. */
  SVN_ERR(svn_io_file_seek(rev_file->file, APR_SET, &entry->offset,
                           scratch_pool));
  while (size > 0)
    {
      apr_size_t to_read = size > sizeof(buffer)
                         ? sizeof(buffer)
                         : (apr_size_t)size;
      SVN_ERR(svn_io_file_read_full2(rev_file->file, buffer, to_read, NULL,
                                     NULL, scratch_pool));
      SVN_ERR(svn_checksum_update(context, buffer, to_read));
      size -= to_read;
    }

  /* Store final checksum in ENTRY. */
  SVN_ERR(svn_checksum_final(&checksum, context, scratch_pool));
  entry->fnv1_checksum = ntohl(*(const apr_uint32_t *)checksum->digest);

  return SVN_NO_ERROR;
}

/*
 * Index (re-)creation utilities.
 */

svn_error_t *
svn_fs_fs__p2l_index_from_p2l_entries(const char **protoname,
                                      svn_fs_t *fs,
                                      svn_fs_fs__revision_file_t *rev_file,
                                      apr_array_header_t *entries,
                                      apr_pool_t *result_pool,
                                      apr_pool_t *scratch_pool)
{
  apr_file_t *proto_index;

  /* Use a subpool for immediate temp file cleanup at the end of this
   * function. */
  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
  int i;

  /* Create a proto-index file. */
  SVN_ERR(svn_io_open_unique_file3(NULL, protoname, NULL,
                                   svn_io_file_del_on_pool_cleanup,
                                   result_pool, scratch_pool));
  SVN_ERR(svn_fs_fs__p2l_proto_index_open(&proto_index, *protoname,
                                          scratch_pool));

  /* Write ENTRIES to proto-index file and calculate checksums as we go. */
  for (i = 0; i < entries->nelts; ++i)
    {
      svn_fs_fs__p2l_entry_t *entry
        = APR_ARRAY_IDX(entries, i, svn_fs_fs__p2l_entry_t *);
      svn_pool_clear(iterpool);

      SVN_ERR(calc_fnv1(entry, rev_file, iterpool));
      SVN_ERR(svn_fs_fs__p2l_proto_index_add_entry(proto_index, entry,
                                                   iterpool));
    }

  /* Convert proto-index into final index and move it into position.
   * Note that REV_FILE contains the start revision of the shard file if it
   * has been packed while REVISION may be somewhere in the middle.  For
   * non-packed shards, they will have identical values. */
  SVN_ERR(svn_io_file_close(proto_index, iterpool));

  /* Temp file cleanup. */
  svn_pool_destroy(iterpool);

  return SVN_NO_ERROR;
}

/* A svn_sort__array compatible comparator function, sorting the
 * svn_fs_fs__p2l_entry_t** given in LHS, RHS by revision. */
static int
compare_p2l_entry_revision(const void *lhs,
                           const void *rhs)
{
  const svn_fs_fs__p2l_entry_t *lhs_entry
    =*(const svn_fs_fs__p2l_entry_t *const *)lhs;
  const svn_fs_fs__p2l_entry_t *rhs_entry
    =*(const svn_fs_fs__p2l_entry_t *const *)rhs;

  if (lhs_entry->item.revision < rhs_entry->item.revision)
    return -1;

  return lhs_entry->item.revision == rhs_entry->item.revision ? 0 : 1;
}

svn_error_t *
svn_fs_fs__l2p_index_from_p2l_entries(const char **protoname,
                                      svn_fs_t *fs,
                                      apr_array_header_t *entries,
                                      apr_pool_t *result_pool,
                                      apr_pool_t *scratch_pool)
{
  apr_file_t *proto_index;

  /* Use a subpool for immediate temp file cleanup at the end of this
   * function. */
  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
  int i;
  svn_revnum_t last_revision = SVN_INVALID_REVNUM;

  /* L2P index must be written in revision order.
   * Sort ENTRIES accordingly. */
  svn_sort__array(entries, compare_p2l_entry_revision);

  /* Create the temporary proto-rev file. */
  SVN_ERR(svn_io_open_unique_file3(NULL, protoname, NULL,
                                   svn_io_file_del_on_pool_cleanup,
                                   result_pool, scratch_pool));
  SVN_ERR(svn_fs_fs__l2p_proto_index_open(&proto_index, *protoname,
                                          scratch_pool));

  /*  Write all entries. */
  for (i = 0; i < entries->nelts; ++i)
    {
      const svn_fs_fs__p2l_entry_t *entry
        = APR_ARRAY_IDX(entries, i, const svn_fs_fs__p2l_entry_t *);
      svn_pool_clear(iterpool);

      if (entry->type == SVN_FS_FS__ITEM_TYPE_UNUSED)
        continue;

      if (last_revision != entry->item.revision)
        {
          SVN_ERR(svn_fs_fs__l2p_proto_index_add_revision(proto_index,
                                                          scratch_pool));
          last_revision = entry->item.revision;
        }

      SVN_ERR(svn_fs_fs__l2p_proto_index_add_entry(proto_index,
                                                   entry->offset,
                                                   entry->item.number,
                                                   iterpool));
    }

  /* Convert proto-index into final index and move it into position. */
  SVN_ERR(svn_io_file_close(proto_index, iterpool));

  /* Temp file cleanup. */
  svn_pool_destroy(iterpool);

  return SVN_NO_ERROR;
}


/*
 * Standard (de-)serialization functions
 */

svn_error_t *
svn_fs_fs__serialize_l2p_header(void **data,
                                apr_size_t *data_len,
                                void *in,
                                apr_pool_t *pool)
{
  l2p_header_t *header = in;
  svn_temp_serializer__context_t *context;
  svn_stringbuf_t *serialized;
  apr_size_t page_count = header->page_table_index[header->revision_count];
  apr_size_t page_table_size = page_count * sizeof(*header->page_table);
  apr_size_t index_size
    = (header->revision_count + 1) * sizeof(*header->page_table_index);
  apr_size_t data_size = sizeof(*header) + index_size + page_table_size;

  /* serialize header and all its elements */
  context = svn_temp_serializer__init(header,
                                      sizeof(*header),
                                      data_size + 32,
                                      pool);

  /* page table index array */
  svn_temp_serializer__add_leaf(context,
                                (const void * const *)&header->page_table_index,
                                index_size);

  /* page table array */
  svn_temp_serializer__add_leaf(context,
                                (const void * const *)&header->page_table,
                                page_table_size);

  /* return the serialized result */
  serialized = svn_temp_serializer__get(context);

  *data = serialized->data;
  *data_len = serialized->len;

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_fs__deserialize_l2p_header(void **out,
                                  void *data,
                                  apr_size_t data_len,
                                  apr_pool_t *pool)
{
  l2p_header_t *header = (l2p_header_t *)data;

  /* resolve the pointers in the struct */
  svn_temp_deserializer__resolve(header, (void**)&header->page_table_index);
  svn_temp_deserializer__resolve(header, (void**)&header->page_table);

  /* done */
  *out = header;

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_fs__serialize_l2p_page(void **data,
                              apr_size_t *data_len,
                              void *in,
                              apr_pool_t *pool)
{
  l2p_page_t *page = in;
  svn_temp_serializer__context_t *context;
  svn_stringbuf_t *serialized;
  apr_size_t of_table_size = page->entry_count * sizeof(*page->offsets);

  /* serialize struct and all its elements */
  context = svn_temp_serializer__init(page,
                                      sizeof(*page),
                                      of_table_size + sizeof(*page) + 32,
                                      pool);

  /* offsets and sub_items arrays */
  svn_temp_serializer__add_leaf(context,
                                (const void * const *)&page->offsets,
                                of_table_size);

  /* return the serialized result */
  serialized = svn_temp_serializer__get(context);

  *data = serialized->data;
  *data_len = serialized->len;

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_fs__deserialize_l2p_page(void **out,
                                void *data,
                                apr_size_t data_len,
                                apr_pool_t *pool)
{
  l2p_page_t *page = data;

  /* resolve the pointers in the struct */
  svn_temp_deserializer__resolve(page, (void**)&page->offsets);

  /* done */
  *out = page;

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_fs__serialize_p2l_header(void **data,
                                apr_size_t *data_len,
                                void *in,
                                apr_pool_t *pool)
{
  p2l_header_t *header = in;
  svn_temp_serializer__context_t *context;
  svn_stringbuf_t *serialized;
  apr_size_t table_size = (header->page_count + 1) * sizeof(*header->offsets);

  /* serialize header and all its elements */
  context = svn_temp_serializer__init(header,
                                      sizeof(*header),
                                      table_size + sizeof(*header) + 32,
                                      pool);

  /* offsets array */
  svn_temp_serializer__add_leaf(context,
                                (const void * const *)&header->offsets,
                                table_size);

  /* return the serialized result */
  serialized = svn_temp_serializer__get(context);

  *data = serialized->data;
  *data_len = serialized->len;

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_fs__deserialize_p2l_header(void **out,
                                  void *data,
                                  apr_size_t data_len,
                                  apr_pool_t *pool)
{
  p2l_header_t *header = data;

  /* resolve the only pointer in the struct */
  svn_temp_deserializer__resolve(header, (void**)&header->offsets);

  /* done */
  *out = header;

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_fs__serialize_p2l_page(void **data,
                              apr_size_t *data_len,
                              void *in,
                              apr_pool_t *pool)
{
  apr_array_header_t *page = in;
  svn_temp_serializer__context_t *context;
  svn_stringbuf_t *serialized;
  apr_size_t table_size = page->elt_size * page->nelts;

  /* serialize array header and all its elements */
  context = svn_temp_serializer__init(page,
                                      sizeof(*page),
                                      table_size + sizeof(*page) + 32,
                                      pool);

  /* items in the array */
  svn_temp_serializer__add_leaf(context,
                                (const void * const *)&page->elts,
                                table_size);

  /* return the serialized result */
  serialized = svn_temp_serializer__get(context);

  *data = serialized->data;
  *data_len = serialized->len;

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_fs__deserialize_p2l_page(void **out,
                                void *data,
                                apr_size_t data_len,
                                apr_pool_t *pool)
{
  apr_array_header_t *page = (apr_array_header_t *)data;

  /* resolve the only pointer in the struct */
  svn_temp_deserializer__resolve(page, (void**)&page->elts);

  /* patch up members */
  page->pool = pool;
  page->nalloc = page->nelts;

  /* done */
  *out = page;

  return SVN_NO_ERROR;
}
