/* transaction.c --- transaction-related functions of FSFS
 *
 * ====================================================================
 *    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 "transaction.h"

#include <assert.h>
#include <apr_sha1.h>

#include "svn_error_codes.h"
#include "svn_hash.h"
#include "svn_props.h"
#include "svn_sorts.h"
#include "svn_time.h"
#include "svn_dirent_uri.h"

#include "fs_fs.h"
#include "index.h"
#include "tree.h"
#include "util.h"
#include "id.h"
#include "low_level.h"
#include "temp_serializer.h"
#include "cached_data.h"
#include "lock.h"
#include "rep-cache.h"

#include "private/svn_fs_util.h"
#include "private/svn_fspath.h"
#include "private/svn_sorts_private.h"
#include "private/svn_subr_private.h"
#include "private/svn_string_private.h"
#include "../libsvn_fs/fs-loader.h"

#include "svn_private_config.h"

/* Return the name of the sha1->rep mapping file in transaction TXN_ID
 * within FS for the given SHA1 checksum.  Use POOL for allocations.
 */
static APR_INLINE const char *
path_txn_sha1(svn_fs_t *fs,
              const svn_fs_fs__id_part_t *txn_id,
              const unsigned char *sha1,
              apr_pool_t *pool)
{
  svn_checksum_t checksum;
  checksum.digest = sha1;
  checksum.kind = svn_checksum_sha1;

  return svn_dirent_join(svn_fs_fs__path_txn_dir(fs, txn_id, pool),
                         svn_checksum_to_cstring(&checksum, pool),
                         pool);
}

static APR_INLINE const char *
path_txn_changes(svn_fs_t *fs,
                 const svn_fs_fs__id_part_t *txn_id,
                 apr_pool_t *pool)
{
  return svn_dirent_join(svn_fs_fs__path_txn_dir(fs, txn_id, pool),
                         PATH_CHANGES, pool);
}

static APR_INLINE const char *
path_txn_props(svn_fs_t *fs,
               const svn_fs_fs__id_part_t *txn_id,
               apr_pool_t *pool)
{
  return svn_dirent_join(svn_fs_fs__path_txn_dir(fs, txn_id, pool),
                         PATH_TXN_PROPS, pool);
}

static APR_INLINE const char *
path_txn_next_ids(svn_fs_t *fs,
                  const svn_fs_fs__id_part_t *txn_id,
                  apr_pool_t *pool)
{
  return svn_dirent_join(svn_fs_fs__path_txn_dir(fs, txn_id, pool),
                         PATH_NEXT_IDS, pool);
}


/* The vtable associated with an open transaction object. */
static txn_vtable_t txn_vtable = {
  svn_fs_fs__commit_txn,
  svn_fs_fs__abort_txn,
  svn_fs_fs__txn_prop,
  svn_fs_fs__txn_proplist,
  svn_fs_fs__change_txn_prop,
  svn_fs_fs__txn_root,
  svn_fs_fs__change_txn_props
};

/* FSFS-specific data being attached to svn_fs_txn_t.
 */
typedef struct fs_txn_data_t
{
  /* Strongly typed representation of the TXN's ID member. */
  svn_fs_fs__id_part_t txn_id;
} fs_txn_data_t;

const svn_fs_fs__id_part_t *
svn_fs_fs__txn_get_id(svn_fs_txn_t *txn)
{
  fs_txn_data_t *ftd = txn->fsap_data;
  return &ftd->txn_id;
}

/* Functions for working with shared transaction data. */

/* Return the transaction object for transaction TXN_ID from the
   transaction list of filesystem FS (which must already be locked via the
   txn_list_lock mutex).  If the transaction does not exist in the list,
   then create a new transaction object and return it (if CREATE_NEW is
   true) or return NULL (otherwise). */
static fs_fs_shared_txn_data_t *
get_shared_txn(svn_fs_t *fs,
               const svn_fs_fs__id_part_t *txn_id,
               svn_boolean_t create_new)
{
  fs_fs_data_t *ffd = fs->fsap_data;
  fs_fs_shared_data_t *ffsd = ffd->shared;
  fs_fs_shared_txn_data_t *txn;

  for (txn = ffsd->txns; txn; txn = txn->next)
    if (svn_fs_fs__id_part_eq(&txn->txn_id, txn_id))
      break;

  if (txn || !create_new)
    return txn;

  /* Use the transaction object from the (single-object) freelist,
     if one is available, or otherwise create a new object. */
  if (ffsd->free_txn)
    {
      txn = ffsd->free_txn;
      ffsd->free_txn = NULL;
    }
  else
    {
      apr_pool_t *subpool = svn_pool_create(ffsd->common_pool);
      txn = apr_palloc(subpool, sizeof(*txn));
      txn->pool = subpool;
    }

  txn->txn_id = *txn_id;
  txn->being_written = FALSE;

  /* Link this transaction into the head of the list.  We will typically
     be dealing with only one active transaction at a time, so it makes
     sense for searches through the transaction list to look at the
     newest transactions first.  */
  txn->next = ffsd->txns;
  ffsd->txns = txn;

  return txn;
}

/* Free the transaction object for transaction TXN_ID, and remove it
   from the transaction list of filesystem FS (which must already be
   locked via the txn_list_lock mutex).  Do nothing if the transaction
   does not exist. */
static void
free_shared_txn(svn_fs_t *fs, const svn_fs_fs__id_part_t *txn_id)
{
  fs_fs_data_t *ffd = fs->fsap_data;
  fs_fs_shared_data_t *ffsd = ffd->shared;
  fs_fs_shared_txn_data_t *txn, *prev = NULL;

  for (txn = ffsd->txns; txn; prev = txn, txn = txn->next)
    if (svn_fs_fs__id_part_eq(&txn->txn_id, txn_id))
      break;

  if (!txn)
    return;

  if (prev)
    prev->next = txn->next;
  else
    ffsd->txns = txn->next;

  /* As we typically will be dealing with one transaction after another,
     we will maintain a single-object free list so that we can hopefully
     keep reusing the same transaction object. */
  if (!ffsd->free_txn)
    ffsd->free_txn = txn;
  else
    svn_pool_destroy(txn->pool);
}


/* Obtain a lock on the transaction list of filesystem FS, call BODY
   with FS, BATON, and POOL, and then unlock the transaction list.
   Return what BODY returned. */
static svn_error_t *
with_txnlist_lock(svn_fs_t *fs,
                  svn_error_t *(*body)(svn_fs_t *fs,
                                       const void *baton,
                                       apr_pool_t *pool),
                  const void *baton,
                  apr_pool_t *pool)
{
  fs_fs_data_t *ffd = fs->fsap_data;
  fs_fs_shared_data_t *ffsd = ffd->shared;

  SVN_MUTEX__WITH_LOCK(ffsd->txn_list_lock,
                       body(fs, baton, pool));

  return SVN_NO_ERROR;
}


/* A structure used by unlock_proto_rev() and unlock_proto_rev_body(),
   which see. */
struct unlock_proto_rev_baton
{
  svn_fs_fs__id_part_t txn_id;
  void *lockcookie;
};

/* Callback used in the implementation of unlock_proto_rev(). */
static svn_error_t *
unlock_proto_rev_body(svn_fs_t *fs, const void *baton, apr_pool_t *pool)
{
  const struct unlock_proto_rev_baton *b = baton;
  apr_file_t *lockfile = b->lockcookie;
  fs_fs_shared_txn_data_t *txn = get_shared_txn(fs, &b->txn_id, FALSE);
  apr_status_t apr_err;

  if (!txn)
    return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
                             _("Can't unlock unknown transaction '%s'"),
                             svn_fs_fs__id_txn_unparse(&b->txn_id, pool));
  if (!txn->being_written)
    return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
                             _("Can't unlock nonlocked transaction '%s'"),
                             svn_fs_fs__id_txn_unparse(&b->txn_id, pool));

  apr_err = apr_file_unlock(lockfile);
  if (apr_err)
    return svn_error_wrap_apr
      (apr_err,
       _("Can't unlock prototype revision lockfile for transaction '%s'"),
       svn_fs_fs__id_txn_unparse(&b->txn_id, pool));
  apr_err = apr_file_close(lockfile);
  if (apr_err)
    return svn_error_wrap_apr
      (apr_err,
       _("Can't close prototype revision lockfile for transaction '%s'"),
       svn_fs_fs__id_txn_unparse(&b->txn_id, pool));

  txn->being_written = FALSE;

  return SVN_NO_ERROR;
}

/* Unlock the prototype revision file for transaction TXN_ID in filesystem
   FS using cookie LOCKCOOKIE.  The original prototype revision file must
   have been closed _before_ calling this function.

   Perform temporary allocations in POOL. */
static svn_error_t *
unlock_proto_rev(svn_fs_t *fs,
                 const svn_fs_fs__id_part_t *txn_id,
                 void *lockcookie,
                 apr_pool_t *pool)
{
  struct unlock_proto_rev_baton b;

  b.txn_id = *txn_id;
  b.lockcookie = lockcookie;
  return with_txnlist_lock(fs, unlock_proto_rev_body, &b, pool);
}

/* A structure used by get_writable_proto_rev() and
   get_writable_proto_rev_body(), which see. */
struct get_writable_proto_rev_baton
{
  void **lockcookie;
  svn_fs_fs__id_part_t txn_id;
};

/* Callback used in the implementation of get_writable_proto_rev(). */
static svn_error_t *
get_writable_proto_rev_body(svn_fs_t *fs, const void *baton, apr_pool_t *pool)
{
  const struct get_writable_proto_rev_baton *b = baton;
  void **lockcookie = b->lockcookie;
  fs_fs_shared_txn_data_t *txn = get_shared_txn(fs, &b->txn_id, TRUE);

  /* First, ensure that no thread in this process (including this one)
     is currently writing to this transaction's proto-rev file. */
  if (txn->being_written)
    return svn_error_createf(SVN_ERR_FS_REP_BEING_WRITTEN, NULL,
                             _("Cannot write to the prototype revision file "
                               "of transaction '%s' because a previous "
                               "representation is currently being written by "
                               "this process"),
                             svn_fs_fs__id_txn_unparse(&b->txn_id, pool));


  /* We know that no thread in this process is writing to the proto-rev
     file, and by extension, that no thread in this process is holding a
     lock on the prototype revision lock file.  It is therefore safe
     for us to attempt to lock this file, to see if any other process
     is holding a lock. */

  {
    apr_file_t *lockfile;
    apr_status_t apr_err;
    const char *lockfile_path
      = svn_fs_fs__path_txn_proto_rev_lock(fs, &b->txn_id, pool);

    /* Open the proto-rev lockfile, creating it if necessary, as it may
       not exist if the transaction dates from before the lockfiles were
       introduced.

       ### We'd also like to use something like svn_io_file_lock2(), but
           that forces us to create a subpool just to be able to unlock
           the file, which seems a waste. */
    SVN_ERR(svn_io_file_open(&lockfile, lockfile_path,
                             APR_WRITE | APR_CREATE, APR_OS_DEFAULT, pool));

    apr_err = apr_file_lock(lockfile,
                            APR_FLOCK_EXCLUSIVE | APR_FLOCK_NONBLOCK);
    if (apr_err)
      {
        svn_error_clear(svn_io_file_close(lockfile, pool));

        if (APR_STATUS_IS_EAGAIN(apr_err))
          return svn_error_createf(SVN_ERR_FS_REP_BEING_WRITTEN, NULL,
                                   _("Cannot write to the prototype revision "
                                     "file of transaction '%s' because a "
                                     "previous representation is currently "
                                     "being written by another process"),
                                   svn_fs_fs__id_txn_unparse(&b->txn_id,
                                                             pool));

        return svn_error_wrap_apr(apr_err,
                                  _("Can't get exclusive lock on file '%s'"),
                                  svn_dirent_local_style(lockfile_path, pool));
      }

    *lockcookie = lockfile;
  }

  /* We've successfully locked the transaction; mark it as such. */
  txn->being_written = TRUE;

  return SVN_NO_ERROR;
}

/* Make sure the length ACTUAL_LENGTH of the proto-revision file PROTO_REV
   of transaction TXN_ID in filesystem FS matches the proto-index file.
   Trim any crash / failure related extra data from the proto-rev file.

   If the prototype revision file is too short, we can't do much but bail out.

   Perform all allocations in POOL. */
static svn_error_t *
auto_truncate_proto_rev(svn_fs_t *fs,
                        apr_file_t *proto_rev,
                        apr_off_t actual_length,
                        const svn_fs_fs__id_part_t *txn_id,
                        apr_pool_t *pool)
{
  /* Only relevant for newer FSFS formats. */
  if (svn_fs_fs__use_log_addressing(fs))
    {
      /* Determine file range covered by the proto-index so far.  Note that
         we always append to both file, i.e. the last index entry also
         corresponds to the last addition in the rev file. */
      const char *path = svn_fs_fs__path_p2l_proto_index(fs, txn_id, pool);
      apr_file_t *file;
      apr_off_t indexed_length;

      SVN_ERR(svn_fs_fs__p2l_proto_index_open(&file, path, pool));
      SVN_ERR(svn_fs_fs__p2l_proto_index_next_offset(&indexed_length, file,
                                                     pool));
      SVN_ERR(svn_io_file_close(file, pool));

      /* Handle mismatches. */
      if (indexed_length < actual_length)
        SVN_ERR(svn_io_file_trunc(proto_rev, indexed_length, pool));
      else if (indexed_length > actual_length)
        return svn_error_createf(SVN_ERR_FS_INDEX_INCONSISTENT,
                                 NULL,
                                 _("p2l proto index offset %s beyond proto"
                                   "rev file size %s for TXN %s"),
                                   apr_off_t_toa(pool, indexed_length),
                                   apr_off_t_toa(pool, actual_length),
                                   svn_fs_fs__id_txn_unparse(txn_id, pool));
    }

  return SVN_NO_ERROR;
}

/* Get a handle to the prototype revision file for transaction TXN_ID in
   filesystem FS, and lock it for writing.  Return FILE, a file handle
   positioned at the end of the file, and LOCKCOOKIE, a cookie that
   should be passed to unlock_proto_rev() to unlock the file once FILE
   has been closed.

   If the prototype revision file is already locked, return error
   SVN_ERR_FS_REP_BEING_WRITTEN.

   Perform all allocations in POOL. */
static svn_error_t *
get_writable_proto_rev(apr_file_t **file,
                       void **lockcookie,
                       svn_fs_t *fs,
                       const svn_fs_fs__id_part_t *txn_id,
                       apr_pool_t *pool)
{
  struct get_writable_proto_rev_baton b;
  svn_error_t *err;
  apr_off_t end_offset = 0;

  b.lockcookie = lockcookie;
  b.txn_id = *txn_id;

  SVN_ERR(with_txnlist_lock(fs, get_writable_proto_rev_body, &b, pool));

  /* Now open the prototype revision file and seek to the end. */
  err = svn_io_file_open(file,
                         svn_fs_fs__path_txn_proto_rev(fs, txn_id, pool),
                         APR_READ | APR_WRITE | APR_BUFFERED, APR_OS_DEFAULT,
                         pool);

  /* You might expect that we could dispense with the following seek
     and achieve the same thing by opening the file using APR_APPEND.
     Unfortunately, APR's buffered file implementation unconditionally
     places its initial file pointer at the start of the file (even for
     files opened with APR_APPEND), so we need this seek to reconcile
     the APR file pointer to the OS file pointer (since we need to be
     able to read the current file position later). */
  if (!err)
    err = svn_io_file_seek(*file, APR_END, &end_offset, pool);

  /* We don't want unused sections (such as leftovers from failed delta
     stream) in our file.  If we use log addressing, we would need an
     index entry for the unused section and that section would need to
     be all NUL by convention.  So, detect and fix those cases by truncating
     the protorev file. */
  if (!err)
    err = auto_truncate_proto_rev(fs, *file, end_offset, txn_id, pool);

  if (err)
    {
      err = svn_error_compose_create(
              err,
              unlock_proto_rev(fs, txn_id, *lockcookie, pool));

      *lockcookie = NULL;
    }

  return svn_error_trace(err);
}

/* Callback used in the implementation of purge_shared_txn(). */
static svn_error_t *
purge_shared_txn_body(svn_fs_t *fs, const void *baton, apr_pool_t *pool)
{
  const svn_fs_fs__id_part_t *txn_id = baton;

  free_shared_txn(fs, txn_id);
  svn_fs_fs__reset_txn_caches(fs);

  return SVN_NO_ERROR;
}

/* Purge the shared data for transaction TXN_ID in filesystem FS.
   Perform all allocations in POOL. */
static svn_error_t *
purge_shared_txn(svn_fs_t *fs,
                 const svn_fs_fs__id_part_t *txn_id,
                 apr_pool_t *pool)
{
  return with_txnlist_lock(fs, purge_shared_txn_body, txn_id, pool);
}


svn_error_t *
svn_fs_fs__put_node_revision(svn_fs_t *fs,
                             const svn_fs_id_t *id,
                             node_revision_t *noderev,
                             svn_boolean_t fresh_txn_root,
                             apr_pool_t *pool)
{
  fs_fs_data_t *ffd = fs->fsap_data;
  apr_file_t *noderev_file;

  noderev->is_fresh_txn_root = fresh_txn_root;

  if (! svn_fs_fs__id_is_txn(id))
    return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
                             _("Attempted to write to non-transaction '%s'"),
                             svn_fs_fs__id_unparse(id, pool)->data);

  SVN_ERR(svn_io_file_open(&noderev_file,
                           svn_fs_fs__path_txn_node_rev(fs, id, pool),
                           APR_WRITE | APR_CREATE | APR_TRUNCATE
                           | APR_BUFFERED, APR_OS_DEFAULT, pool));

  SVN_ERR(svn_fs_fs__write_noderev(svn_stream_from_aprfile2(noderev_file, TRUE,
                                                            pool),
                                   noderev, ffd->format,
                                   svn_fs_fs__fs_supports_mergeinfo(fs),
                                   pool));

  SVN_ERR(svn_io_file_close(noderev_file, pool));

  return SVN_NO_ERROR;
}

/* For the in-transaction NODEREV within FS, write the sha1->rep mapping
 * file in the respective transaction, if rep sharing has been enabled etc.
 * Use SCATCH_POOL for temporary allocations.
 */
static svn_error_t *
store_sha1_rep_mapping(svn_fs_t *fs,
                       node_revision_t *noderev,
                       apr_pool_t *scratch_pool)
{
  fs_fs_data_t *ffd = fs->fsap_data;

  /* if rep sharing has been enabled and the noderev has a data rep and
   * its SHA-1 is known, store the rep struct under its SHA1. */
  if (   ffd->rep_sharing_allowed
      && noderev->data_rep
      && noderev->data_rep->has_sha1)
    {
      apr_file_t *rep_file;
      const char *file_name = path_txn_sha1(fs,
                                            &noderev->data_rep->txn_id,
                                            noderev->data_rep->sha1_digest,
                                            scratch_pool);
      svn_stringbuf_t *rep_string
        = svn_fs_fs__unparse_representation(noderev->data_rep,
                                            ffd->format,
                                            (noderev->kind == svn_node_dir),
                                            scratch_pool, scratch_pool);
      SVN_ERR(svn_io_file_open(&rep_file, file_name,
                               APR_WRITE | APR_CREATE | APR_TRUNCATE
                               | APR_BUFFERED, APR_OS_DEFAULT, scratch_pool));

      SVN_ERR(svn_io_file_write_full(rep_file, rep_string->data,
                                     rep_string->len, NULL, scratch_pool));

      SVN_ERR(svn_io_file_close(rep_file, scratch_pool));
    }

  return SVN_NO_ERROR;
}

static svn_error_t *
unparse_dir_entry(svn_fs_dirent_t *dirent,
                  svn_stream_t *stream,
                  apr_pool_t *pool)
{
  apr_size_t to_write;
  svn_string_t *id_str = svn_fs_fs__id_unparse(dirent->id, pool);
  apr_size_t name_len = strlen(dirent->name);

  /* Note that sizeof == len + 1, i.e. accounts for the space between
   * type and ID. */
  apr_size_t type_len = (dirent->kind == svn_node_file)
                      ? sizeof(SVN_FS_FS__KIND_FILE)
                      : sizeof(SVN_FS_FS__KIND_DIR);
  apr_size_t value_len = type_len + id_str->len;

  /* A buffer with sufficient space for
   * - both string lines
   * - 4 newlines
   * - 2 lines K/V lines containing a number each
   */
  char *buffer = apr_palloc(pool,   name_len + value_len
                                  + 4
                                  + 2 * (2 + SVN_INT64_BUFFER_SIZE));

  /* Now construct the value. */
  char *p = buffer;

  /* The "K length(name)\n" line. */
  p[0] = 'K';
  p[1] = ' ';
  p += 2;
  p += svn__i64toa(p, name_len);
  *(p++) = '\n';

  /* The line with the key, i.e. dir entry name. */
  memcpy(p, dirent->name, name_len);
  p += name_len;
  *(p++) = '\n';

  /* The "V length(type+id)\n" line. */
  p[0] = 'V';
  p[1] = ' ';
  p += 2;
  p += svn__i64toa(p, value_len);
  *(p++) = '\n';

  /* The line with the type and ID. */
  memcpy(p,
         (dirent->kind == svn_node_file) ? SVN_FS_FS__KIND_FILE
                                         : SVN_FS_FS__KIND_DIR,
         type_len - 1);
  p += type_len - 1;
  *(p++) = ' ';
  memcpy(p, id_str->data, id_str->len);
  p+=id_str->len;
  *(p++) = '\n';

  /* Add the entry to the output stream. */
  to_write = p - buffer;
  SVN_ERR(svn_stream_write(stream, buffer, &to_write));
  return SVN_NO_ERROR;
}

/* Write the directory given as array of dirent structs in ENTRIES to STREAM.
   Perform temporary allocations in POOL. */
static svn_error_t *
unparse_dir_entries(apr_array_header_t *entries,
                    svn_stream_t *stream,
                    apr_pool_t *pool)
{
  apr_pool_t *iterpool = svn_pool_create(pool);
  int i;
  for (i = 0; i < entries->nelts; ++i)
    {
      svn_fs_dirent_t *dirent;

      svn_pool_clear(iterpool);
      dirent = APR_ARRAY_IDX(entries, i, svn_fs_dirent_t *);
      SVN_ERR(unparse_dir_entry(dirent, stream, iterpool));
    }

  SVN_ERR(svn_stream_printf(stream, pool, "%s\n", SVN_HASH_TERMINATOR));

  svn_pool_destroy(iterpool);
  return SVN_NO_ERROR;
}

/* Return a deep copy of SOURCE and allocate it in RESULT_POOL.
 */
static svn_fs_path_change2_t *
path_change_dup(const svn_fs_path_change2_t *source,
                apr_pool_t *result_pool)
{
  svn_fs_path_change2_t *result = apr_pmemdup(result_pool, source,
                                              sizeof(*source));
  result->node_rev_id = svn_fs_fs__id_copy(source->node_rev_id, result_pool);
  if (source->copyfrom_path)
    result->copyfrom_path = apr_pstrdup(result_pool, source->copyfrom_path);

  return result;
}

/* Merge the internal-use-only CHANGE into a hash of public-FS
   svn_fs_path_change2_t CHANGED_PATHS, collapsing multiple changes into a
   single summarical (is that real word?) change per path.  DELETIONS is
   also a path->svn_fs_path_change2_t hash and contains all the deletions
   that got turned into a replacement. */
static svn_error_t *
fold_change(apr_hash_t *changed_paths,
            apr_hash_t *deletions,
            const change_t *change)
{
  apr_pool_t *pool = apr_hash_pool_get(changed_paths);
  svn_fs_path_change2_t *old_change, *new_change;
  const svn_string_t *path = &change->path;
  const svn_fs_path_change2_t *info = &change->info;

  if ((old_change = apr_hash_get(changed_paths, path->data, path->len)))
    {
      /* This path already exists in the hash, so we have to merge
         this change into the already existing one. */

      /* Sanity check:  only allow NULL node revision ID in the
         `reset' case. */
      if ((! info->node_rev_id)
           && (info->change_kind != svn_fs_path_change_reset))
        return svn_error_create
          (SVN_ERR_FS_CORRUPT, NULL,
           _("Missing required node revision ID"));

      /* Sanity check: we should be talking about the same node
         revision ID as our last change except where the last change
         was a deletion. */
      if (info->node_rev_id
          && (! svn_fs_fs__id_eq(old_change->node_rev_id, info->node_rev_id))
          && (old_change->change_kind != svn_fs_path_change_delete))
        return svn_error_create
          (SVN_ERR_FS_CORRUPT, NULL,
           _("Invalid change ordering: new node revision ID "
             "without delete"));

      /* Sanity check: an add, replacement, or reset must be the first
         thing to follow a deletion. */
      if ((old_change->change_kind == svn_fs_path_change_delete)
          && (! ((info->change_kind == svn_fs_path_change_replace)
                 || (info->change_kind == svn_fs_path_change_reset)
                 || (info->change_kind == svn_fs_path_change_add))))
        return svn_error_create
          (SVN_ERR_FS_CORRUPT, NULL,
           _("Invalid change ordering: non-add change on deleted path"));

      /* Sanity check: an add can't follow anything except
         a delete or reset.  */
      if ((info->change_kind == svn_fs_path_change_add)
          && (old_change->change_kind != svn_fs_path_change_delete)
          && (old_change->change_kind != svn_fs_path_change_reset))
        return svn_error_create
          (SVN_ERR_FS_CORRUPT, NULL,
           _("Invalid change ordering: add change on preexisting path"));

      /* Now, merge that change in. */
      switch (info->change_kind)
        {
        case svn_fs_path_change_reset:
          /* A reset here will simply remove the path change from the
             hash. */
          apr_hash_set(changed_paths, path->data, path->len, NULL);
          break;

        case svn_fs_path_change_delete:
          if (old_change->change_kind == svn_fs_path_change_add)
            {
              /* If the path was introduced in this transaction via an
                 add, and we are deleting it, just remove the path
                 altogether.  (The caller will delete any child paths.) */
              apr_hash_set(changed_paths, path->data, path->len, NULL);
            }
          else if (old_change->change_kind == svn_fs_path_change_replace)
            {
              /* A deleting a 'replace' restore the original deletion. */
              new_change = apr_hash_get(deletions, path->data, path->len);
              SVN_ERR_ASSERT(new_change);
              apr_hash_set(changed_paths, path->data, path->len, new_change);
            }
          else
            {
              /* A deletion overrules a previous change (modify). */
              new_change = path_change_dup(info, pool);
              apr_hash_set(changed_paths, path->data, path->len, new_change);
            }
          break;

        case svn_fs_path_change_add:
        case svn_fs_path_change_replace:
          /* An add at this point must be following a previous delete,
             so treat it just like a replace.  Remember the original
             deletion such that we are able to delete this path again
             (the replacement may have changed node kind and id). */
          new_change = path_change_dup(info, pool);
          new_change->change_kind = svn_fs_path_change_replace;

          apr_hash_set(changed_paths, path->data, path->len, new_change);

          /* Remember the original change.
           * Make sure to allocate the hash key in a durable pool. */
          apr_hash_set(deletions,
                       apr_pstrmemdup(apr_hash_pool_get(deletions),
                                      path->data, path->len),
                       path->len, old_change);
          break;

        case svn_fs_path_change_modify:
        default:
          /* If the new change modifies some attribute of the node, set
             the corresponding flag, whether it already was set or not.
             Note: We do not reset a flag to FALSE if a change is undone. */
          if (info->text_mod)
            old_change->text_mod = TRUE;
          if (info->prop_mod)
            old_change->prop_mod = TRUE;
          if (info->mergeinfo_mod == svn_tristate_true)
            old_change->mergeinfo_mod = svn_tristate_true;
          break;
        }
    }
  else
    {
      /* Add this path.  The API makes no guarantees that this (new) key
         will not be retained.  Thus, we copy the key into the target pool
         to ensure a proper lifetime.  */
      apr_hash_set(changed_paths,
                   apr_pstrmemdup(pool, path->data, path->len), path->len,
                   path_change_dup(info, pool));
    }

  return SVN_NO_ERROR;
}

/* Baton type to be used with process_changes(). */
typedef struct process_changes_baton_t
{
  /* Folded list of path changes. */
  apr_hash_t *changed_paths;

  /* Path changes that are deletions and have been turned into
     replacements.  If those replacements get deleted again, this
     container contains the record that we have to revert to. */
  apr_hash_t *deletions;
} process_changes_baton_t;

/* An implementation of svn_fs_fs__change_receiver_t.
   Examine all the changed path entries in CHANGES and store them in
   *CHANGED_PATHS.  Folding is done to remove redundant or unnecessary
   data. Do all allocations in POOL. */
static svn_error_t *
process_changes(void *baton_p,
                change_t *change,
                apr_pool_t *scratch_pool)
{
  process_changes_baton_t *baton = baton_p;

  SVN_ERR(fold_change(baton->changed_paths, baton->deletions, change));

  /* Now, if our change was a deletion or replacement, we have to
     blow away any changes thus far on paths that are (or, were)
     children of this path.
     ### i won't bother with another iteration pool here -- at
     most we talking about a few extra dups of paths into what
     is already a temporary subpool.
  */

  if ((change->info.change_kind == svn_fs_path_change_delete)
       || (change->info.change_kind == svn_fs_path_change_replace))
    {
      apr_hash_index_t *hi;

      /* a potential child path must contain at least 2 more chars
         (the path separator plus at least one char for the name).
         Also, we should not assume that all paths have been normalized
         i.e. some might have trailing path separators.
      */
      apr_ssize_t path_len = change->path.len;
      apr_ssize_t min_child_len = path_len == 0
                                ? 1
                                : change->path.data[path_len-1] == '/'
                                    ? path_len + 1
                                    : path_len + 2;

      /* CAUTION: This is the inner loop of an O(n^2) algorithm.
         The number of changes to process may be >> 1000.
         Therefore, keep the inner loop as tight as possible.
      */
      for (hi = apr_hash_first(scratch_pool, baton->changed_paths);
           hi;
           hi = apr_hash_next(hi))
        {
          /* KEY is the path. */
          const void *path;
          apr_ssize_t klen;
          svn_fs_path_change2_t *old_change;
          apr_hash_this(hi, &path, &klen, (void**)&old_change);

          /* If we come across a child of our path, remove it.
             Call svn_fspath__skip_ancestor only if there is a chance that
             this is actually a sub-path.
           */
          if (klen >= min_child_len)
            {
              const char *child;

              child = svn_fspath__skip_ancestor(change->path.data, path);
              if (child && child[0] != '\0')
                {
                  apr_hash_set(baton->changed_paths, path, klen, NULL);
                }
            }
        }
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_fs__txn_changes_fetch(apr_hash_t **changed_paths_p,
                             svn_fs_t *fs,
                             const svn_fs_fs__id_part_t *txn_id,
                             apr_pool_t *pool)
{
  apr_file_t *file;
  apr_hash_t *changed_paths = apr_hash_make(pool);
  apr_pool_t *scratch_pool = svn_pool_create(pool);
  process_changes_baton_t baton;

  baton.changed_paths = changed_paths;
  baton.deletions = apr_hash_make(scratch_pool);

  SVN_ERR(svn_io_file_open(&file,
                           path_txn_changes(fs, txn_id, scratch_pool),
                           APR_READ | APR_BUFFERED, APR_OS_DEFAULT,
                           scratch_pool));

  SVN_ERR(svn_fs_fs__read_changes_incrementally(
                                  svn_stream_from_aprfile2(file, TRUE,
                                                           scratch_pool),
                                  process_changes, &baton,
                                  scratch_pool));
  svn_pool_destroy(scratch_pool);

  *changed_paths_p = changed_paths;

  return SVN_NO_ERROR;
}


svn_error_t *
svn_fs_fs__paths_changed(apr_hash_t **changed_paths_p,
                         svn_fs_t *fs,
                         svn_revnum_t rev,
                         apr_pool_t *pool)
{
  apr_hash_t *changed_paths = svn_hash__make(pool);
  svn_fs_fs__changes_context_t *context;

  apr_pool_t *iterpool = svn_pool_create(pool);

  /* Fetch all data block-by-block. */
  SVN_ERR(svn_fs_fs__create_changes_context(&context, fs, rev, pool));
  while (!context->eol)
    {
      apr_array_header_t *changes;
      int i;

      svn_pool_clear(iterpool);

      /* Be sure to allocate the changes in the result POOL, even though
         we don't need the array itself afterwards.  Copying the entries
         from a temp pool to the result POOL would be expensive and saves
         use less then 10% memory. */
      SVN_ERR(svn_fs_fs__get_changes(&changes, context, pool, iterpool));

      for (i = 0; i < changes->nelts; ++i)
        {
          change_t *change = APR_ARRAY_IDX(changes, i, change_t *);
          apr_hash_set(changed_paths, change->path.data, change->path.len,
                       &change->info);
        }
    }

  svn_pool_destroy(iterpool);

  *changed_paths_p = changed_paths;

  return SVN_NO_ERROR;
}

/* Copy a revision node-rev SRC into the current transaction TXN_ID in
   the filesystem FS.  This is only used to create the root of a transaction.
   Allocations are from POOL.  */
static svn_error_t *
create_new_txn_noderev_from_rev(svn_fs_t *fs,
                                const svn_fs_fs__id_part_t *txn_id,
                                svn_fs_id_t *src,
                                apr_pool_t *pool)
{
  node_revision_t *noderev;
  const svn_fs_fs__id_part_t *node_id, *copy_id;

  SVN_ERR(svn_fs_fs__get_node_revision(&noderev, fs, src, pool, pool));

  if (svn_fs_fs__id_is_txn(noderev->id))
    return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
                            _("Copying from transactions not allowed"));

  noderev->predecessor_id = noderev->id;
  noderev->predecessor_count++;
  noderev->copyfrom_path = NULL;
  noderev->copyfrom_rev = SVN_INVALID_REVNUM;

  /* For the transaction root, the copyroot never changes. */

  node_id = svn_fs_fs__id_node_id(noderev->id);
  copy_id = svn_fs_fs__id_copy_id(noderev->id);
  noderev->id = svn_fs_fs__id_txn_create(node_id, copy_id, txn_id, pool);

  return svn_fs_fs__put_node_revision(fs, noderev->id, noderev, TRUE, pool);
}

/* A structure used by get_and_increment_txn_key_body(). */
struct get_and_increment_txn_key_baton {
  svn_fs_t *fs;
  apr_uint64_t txn_number;
  apr_pool_t *pool;
};

/* Callback used in the implementation of create_txn_dir().  This gets
   the current base 36 value in PATH_TXN_CURRENT and increments it.
   It returns the original value by the baton. */
static svn_error_t *
get_and_increment_txn_key_body(void *baton, apr_pool_t *pool)
{
  struct get_and_increment_txn_key_baton *cb = baton;
  fs_fs_data_t *ffd = cb->fs->fsap_data;
  const char *txn_current_filename
    = svn_fs_fs__path_txn_current(cb->fs, pool);
  char new_id_str[SVN_INT64_BUFFER_SIZE + 1]; /* add space for a newline */
  apr_size_t line_length;

  svn_stringbuf_t *buf;
  SVN_ERR(svn_fs_fs__read_content(&buf, txn_current_filename, cb->pool));

  /* assign the current txn counter value to our result */
  cb->txn_number = svn__base36toui64(NULL, buf->data);

  /* remove trailing newlines */
  line_length = svn__ui64tobase36(new_id_str, cb->txn_number+1);
  new_id_str[line_length] = '\n';

  /* Increment the key and add a trailing \n to the string so the
     txn-current file has a newline in it. */
  SVN_ERR(svn_io_write_atomic2(txn_current_filename, new_id_str,
                               line_length + 1,
                               txn_current_filename /* copy_perms path */,
                               ffd->flush_to_disk, pool));

  return SVN_NO_ERROR;
}

/* Create a unique directory for a transaction in FS based on revision REV.
   Return the ID for this transaction in *ID_P and *TXN_ID.  Use a sequence
   value in the transaction ID to prevent reuse of transaction IDs. */
static svn_error_t *
create_txn_dir(const char **id_p,
               svn_fs_fs__id_part_t *txn_id,
               svn_fs_t *fs,
               svn_revnum_t rev,
               apr_pool_t *pool)
{
  struct get_and_increment_txn_key_baton cb;
  const char *txn_dir;

  /* Get the current transaction sequence value, which is a base-36
     number, from the txn-current file, and write an
     incremented value back out to the file.  Place the revision
     number the transaction is based off into the transaction id. */
  cb.pool = pool;
  cb.fs = fs;
  SVN_ERR(svn_fs_fs__with_txn_current_lock(fs,
                                           get_and_increment_txn_key_body,
                                           &cb,
                                           pool));
  txn_id->revision = rev;
  txn_id->number = cb.txn_number;

  *id_p = svn_fs_fs__id_txn_unparse(txn_id, pool);
  txn_dir = svn_fs_fs__path_txn_dir(fs, txn_id, pool);

  return svn_io_dir_make(txn_dir, APR_OS_DEFAULT, pool);
}

/* Create a unique directory for a transaction in FS based on revision
   REV.  Return the ID for this transaction in *ID_P and *TXN_ID.  This
   implementation is used in svn 1.4 and earlier repositories and is
   kept in 1.5 and greater to support the --pre-1.4-compatible and
   --pre-1.5-compatible repository creation options.  Reused
   transaction IDs are possible with this implementation. */
static svn_error_t *
create_txn_dir_pre_1_5(const char **id_p,
                       svn_fs_fs__id_part_t *txn_id,
                       svn_fs_t *fs,
                       svn_revnum_t rev,
                       apr_pool_t *pool)
{
  unsigned int i;
  apr_pool_t *subpool;
  const char *unique_path, *prefix;

  /* Try to create directories named "<txndir>/<rev>-<uniqueifier>.txn". */
  prefix = svn_dirent_join(svn_fs_fs__path_txns_dir(fs, pool),
                           apr_psprintf(pool, "%ld", rev), pool);

  subpool = svn_pool_create(pool);
  for (i = 1; i <= 99999; i++)
    {
      svn_error_t *err;

      svn_pool_clear(subpool);
      unique_path = apr_psprintf(subpool, "%s-%u" PATH_EXT_TXN, prefix, i);
      err = svn_io_dir_make(unique_path, APR_OS_DEFAULT, subpool);
      if (! err)
        {
          /* We succeeded.  Return the basename minus the ".txn" extension. */
          const char *name = svn_dirent_basename(unique_path, subpool);
          *id_p = apr_pstrndup(pool, name,
                               strlen(name) - strlen(PATH_EXT_TXN));
          SVN_ERR(svn_fs_fs__id_txn_parse(txn_id, *id_p));
          svn_pool_destroy(subpool);
          return SVN_NO_ERROR;
        }
      if (! APR_STATUS_IS_EEXIST(err->apr_err))
        return svn_error_trace(err);
      svn_error_clear(err);
    }

  return svn_error_createf(SVN_ERR_IO_UNIQUE_NAMES_EXHAUSTED,
                           NULL,
                           _("Unable to create transaction directory "
                             "in '%s' for revision %ld"),
                           svn_dirent_local_style(fs->path, pool),
                           rev);
}

svn_error_t *
svn_fs_fs__create_txn(svn_fs_txn_t **txn_p,
                      svn_fs_t *fs,
                      svn_revnum_t rev,
                      apr_pool_t *pool)
{
  fs_fs_data_t *ffd = fs->fsap_data;
  svn_fs_txn_t *txn;
  fs_txn_data_t *ftd;
  svn_fs_id_t *root_id;

  txn = apr_pcalloc(pool, sizeof(*txn));
  ftd = apr_pcalloc(pool, sizeof(*ftd));

  /* Get the txn_id. */
  if (ffd->format >= SVN_FS_FS__MIN_TXN_CURRENT_FORMAT)
    SVN_ERR(create_txn_dir(&txn->id, &ftd->txn_id, fs, rev, pool));
  else
    SVN_ERR(create_txn_dir_pre_1_5(&txn->id, &ftd->txn_id, fs, rev, pool));

  txn->fs = fs;
  txn->base_rev = rev;

  txn->vtable = &txn_vtable;
  txn->fsap_data = ftd;
  *txn_p = txn;

  /* Create a new root node for this transaction. */
  SVN_ERR(svn_fs_fs__rev_get_root(&root_id, fs, rev, pool, pool));
  SVN_ERR(create_new_txn_noderev_from_rev(fs, &ftd->txn_id, root_id, pool));

  /* Create an empty rev file. */
  SVN_ERR(svn_io_file_create_empty(
                    svn_fs_fs__path_txn_proto_rev(fs, &ftd->txn_id, pool),
                    pool));

  /* Create an empty rev-lock file. */
  SVN_ERR(svn_io_file_create_empty(
               svn_fs_fs__path_txn_proto_rev_lock(fs, &ftd->txn_id, pool),
               pool));

  /* Create an empty changes file. */
  SVN_ERR(svn_io_file_create_empty(path_txn_changes(fs, &ftd->txn_id, pool),
                                   pool));

  /* Create the next-ids file. */
  return svn_io_file_create(path_txn_next_ids(fs, &ftd->txn_id, pool),
                            "0 0\n", pool);
}

/* Store the property list for transaction TXN_ID in PROPLIST.
   Perform temporary allocations in POOL. */
static svn_error_t *
get_txn_proplist(apr_hash_t *proplist,
                 svn_fs_t *fs,
                 const svn_fs_fs__id_part_t *txn_id,
                 apr_pool_t *pool)
{
  svn_stream_t *stream;
  svn_error_t *err;

  /* Check for issue #3696. (When we find and fix the cause, we can change
   * this to an assertion.) */
  if (!txn_id || !svn_fs_fs__id_txn_used(txn_id))
    return svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
                            _("Internal error: a null transaction id was "
                              "passed to get_txn_proplist()"));

  /* Open the transaction properties file. */
  SVN_ERR(svn_stream_open_readonly(&stream, path_txn_props(fs, txn_id, pool),
                                   pool, pool));

  /* Read in the property list. */
  err = svn_hash_read2(proplist, stream, SVN_HASH_TERMINATOR, pool);
  if (err)
    {
      err = svn_error_compose_create(err, svn_stream_close(stream));
      return svn_error_quick_wrapf(err,
               _("malformed property list in transaction '%s'"),
               path_txn_props(fs, txn_id, pool));
    }

  return svn_stream_close(stream);
}

/* Save the property list PROPS as the revprops for transaction TXN_ID
   in FS.  Perform temporary allocations in POOL. */
static svn_error_t *
set_txn_proplist(svn_fs_t *fs,
                 const svn_fs_fs__id_part_t *txn_id,
                 apr_hash_t *props,
                 apr_pool_t *pool)
{
  svn_stream_t *tmp_stream;
  const char *tmp_path;
  const char *final_path = path_txn_props(fs, txn_id, pool);

  /* Write the new contents into a temporary file. */
  SVN_ERR(svn_stream_open_unique(&tmp_stream, &tmp_path,
                                 svn_dirent_dirname(final_path, pool),
                                 svn_io_file_del_none,
                                 pool, pool));

  /* Replace the old file with the new one. */
  SVN_ERR(svn_hash_write2(props, tmp_stream, SVN_HASH_TERMINATOR, pool));
  SVN_ERR(svn_stream_close(tmp_stream));

  SVN_ERR(svn_io_file_rename2(tmp_path, final_path, FALSE, pool));

  return SVN_NO_ERROR;
}


svn_error_t *
svn_fs_fs__change_txn_prop(svn_fs_txn_t *txn,
                           const char *name,
                           const svn_string_t *value,
                           apr_pool_t *pool)
{
  apr_array_header_t *props = apr_array_make(pool, 1, sizeof(svn_prop_t));
  svn_prop_t prop;

  prop.name = name;
  prop.value = value;
  APR_ARRAY_PUSH(props, svn_prop_t) = prop;

  return svn_fs_fs__change_txn_props(txn, props, pool);
}

svn_error_t *
svn_fs_fs__change_txn_props(svn_fs_txn_t *txn,
                            const apr_array_header_t *props,
                            apr_pool_t *pool)
{
  fs_txn_data_t *ftd = txn->fsap_data;
  apr_hash_t *txn_prop = apr_hash_make(pool);
  int i;
  svn_error_t *err;

  err = get_txn_proplist(txn_prop, txn->fs, &ftd->txn_id, pool);
  /* Here - and here only - we need to deal with the possibility that the
     transaction property file doesn't yet exist.  The rest of the
     implementation assumes that the file exists, but we're called to set the
     initial transaction properties as the transaction is being created. */
  if (err && (APR_STATUS_IS_ENOENT(err->apr_err)))
    svn_error_clear(err);
  else if (err)
    return svn_error_trace(err);

  for (i = 0; i < props->nelts; i++)
    {
      svn_prop_t *prop = &APR_ARRAY_IDX(props, i, svn_prop_t);

      if (svn_hash_gets(txn_prop, SVN_FS__PROP_TXN_CLIENT_DATE)
          && !strcmp(prop->name, SVN_PROP_REVISION_DATE))
        svn_hash_sets(txn_prop, SVN_FS__PROP_TXN_CLIENT_DATE,
                      svn_string_create("1", pool));

      svn_hash_sets(txn_prop, prop->name, prop->value);
    }

  /* Create a new version of the file and write out the new props. */
  /* Open the transaction properties file. */
  SVN_ERR(set_txn_proplist(txn->fs, &ftd->txn_id, txn_prop, pool));

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_fs__get_txn(transaction_t **txn_p,
                   svn_fs_t *fs,
                   const svn_fs_fs__id_part_t *txn_id,
                   apr_pool_t *pool)
{
  transaction_t *txn;
  node_revision_t *noderev;
  svn_fs_id_t *root_id;

  txn = apr_pcalloc(pool, sizeof(*txn));
  root_id = svn_fs_fs__id_txn_create_root(txn_id, pool);

  SVN_ERR(svn_fs_fs__get_node_revision(&noderev, fs, root_id, pool, pool));

  txn->root_id = svn_fs_fs__id_copy(noderev->id, pool);
  txn->base_id = svn_fs_fs__id_copy(noderev->predecessor_id, pool);
  txn->copies = NULL;

  *txn_p = txn;

  return SVN_NO_ERROR;
}

/* Write out the currently available next node_id NODE_ID and copy_id
   COPY_ID for transaction TXN_ID in filesystem FS.  The next node-id is
   used both for creating new unique nodes for the given transaction, as
   well as uniquifying representations.  Perform temporary allocations in
   POOL. */
static svn_error_t *
write_next_ids(svn_fs_t *fs,
               const svn_fs_fs__id_part_t *txn_id,
               apr_uint64_t node_id,
               apr_uint64_t copy_id,
               apr_pool_t *pool)
{
  apr_file_t *file;
  char buffer[2 * SVN_INT64_BUFFER_SIZE + 2];
  char *p = buffer;

  p += svn__ui64tobase36(p, node_id);
  *(p++) = ' ';
  p += svn__ui64tobase36(p, copy_id);
  *(p++) = '\n';
  *(p++) = '\0';

  SVN_ERR(svn_io_file_open(&file,
                           path_txn_next_ids(fs, txn_id, pool),
                           APR_WRITE | APR_TRUNCATE,
                           APR_OS_DEFAULT, pool));
  SVN_ERR(svn_io_file_write_full(file, buffer, p - buffer, NULL, pool));
  return svn_io_file_close(file, pool);
}

/* Find out what the next unique node-id and copy-id are for
   transaction TXN_ID in filesystem FS.  Store the results in *NODE_ID
   and *COPY_ID.  The next node-id is used both for creating new unique
   nodes for the given transaction, as well as uniquifying representations.
   Perform all allocations in POOL. */
static svn_error_t *
read_next_ids(apr_uint64_t *node_id,
              apr_uint64_t *copy_id,
              svn_fs_t *fs,
              const svn_fs_fs__id_part_t *txn_id,
              apr_pool_t *pool)
{
  svn_stringbuf_t *buf;
  const char *str;
  SVN_ERR(svn_fs_fs__read_content(&buf,
                                  path_txn_next_ids(fs, txn_id, pool),
                                  pool));

  /* Parse this into two separate strings. */

  str = buf->data;
  *node_id = svn__base36toui64(&str, str);
  if (*str != ' ')
    return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
                            _("next-id file corrupt"));

  ++str;
  *copy_id = svn__base36toui64(&str, str);
  if (*str != '\n')
    return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
                            _("next-id file corrupt"));

  return SVN_NO_ERROR;
}

/* Get a new and unique to this transaction node-id for transaction
   TXN_ID in filesystem FS.  Store the new node-id in *NODE_ID_P.
   Node-ids are guaranteed to be unique to this transction, but may
   not necessarily be sequential.  Perform all allocations in POOL. */
static svn_error_t *
get_new_txn_node_id(svn_fs_fs__id_part_t *node_id_p,
                    svn_fs_t *fs,
                    const svn_fs_fs__id_part_t *txn_id,
                    apr_pool_t *pool)
{
  apr_uint64_t node_id, copy_id;

  /* First read in the current next-ids file. */
  SVN_ERR(read_next_ids(&node_id, &copy_id, fs, txn_id, pool));

  node_id_p->revision = SVN_INVALID_REVNUM;
  node_id_p->number = node_id;

  SVN_ERR(write_next_ids(fs, txn_id, ++node_id, copy_id, pool));

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_fs__reserve_copy_id(svn_fs_fs__id_part_t *copy_id_p,
                           svn_fs_t *fs,
                           const svn_fs_fs__id_part_t *txn_id,
                           apr_pool_t *pool)
{
  apr_uint64_t node_id, copy_id;

  /* First read in the current next-ids file. */
  SVN_ERR(read_next_ids(&node_id, &copy_id, fs, txn_id, pool));

  /* this is an in-txn ID now */
  copy_id_p->revision = SVN_INVALID_REVNUM;
  copy_id_p->number = copy_id;

  /* Update the ID counter file */
  SVN_ERR(write_next_ids(fs, txn_id, node_id, ++copy_id, pool));

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_fs__create_node(const svn_fs_id_t **id_p,
                       svn_fs_t *fs,
                       node_revision_t *noderev,
                       const svn_fs_fs__id_part_t *copy_id,
                       const svn_fs_fs__id_part_t *txn_id,
                       apr_pool_t *pool)
{
  svn_fs_fs__id_part_t node_id;
  const svn_fs_id_t *id;

  /* Get a new node-id for this node. */
  SVN_ERR(get_new_txn_node_id(&node_id, fs, txn_id, pool));

  id = svn_fs_fs__id_txn_create(&node_id, copy_id, txn_id, pool);

  noderev->id = id;

  SVN_ERR(svn_fs_fs__put_node_revision(fs, noderev->id, noderev, FALSE, pool));

  *id_p = id;

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_fs__purge_txn(svn_fs_t *fs,
                     const char *txn_id_str,
                     apr_pool_t *pool)
{
  fs_fs_data_t *ffd = fs->fsap_data;
  svn_fs_fs__id_part_t txn_id;
  SVN_ERR(svn_fs_fs__id_txn_parse(&txn_id, txn_id_str));

  /* Remove the shared transaction object associated with this transaction. */
  SVN_ERR(purge_shared_txn(fs, &txn_id, pool));
  /* Remove the directory associated with this transaction. */
  SVN_ERR(svn_io_remove_dir2(svn_fs_fs__path_txn_dir(fs, &txn_id, pool),
                             FALSE, NULL, NULL, pool));
  if (ffd->format >= SVN_FS_FS__MIN_PROTOREVS_DIR_FORMAT)
    {
      /* Delete protorev and its lock, which aren't in the txn
         directory.  It's OK if they don't exist (for example, if this
         is post-commit and the proto-rev has been moved into
         place). */
      SVN_ERR(svn_io_remove_file2(
                  svn_fs_fs__path_txn_proto_rev(fs, &txn_id, pool),
                  TRUE, pool));
      SVN_ERR(svn_io_remove_file2(
                  svn_fs_fs__path_txn_proto_rev_lock(fs, &txn_id, pool),
                  TRUE, pool));
    }
  return SVN_NO_ERROR;
}


svn_error_t *
svn_fs_fs__abort_txn(svn_fs_txn_t *txn,
                     apr_pool_t *pool)
{
  SVN_ERR(svn_fs__check_fs(txn->fs, TRUE));

  /* Now, purge the transaction. */
  SVN_ERR_W(svn_fs_fs__purge_txn(txn->fs, txn->id, pool),
            apr_psprintf(pool, _("Transaction '%s' cleanup failed"),
                         txn->id));

  return SVN_NO_ERROR;
}

/* Assign the UNIQUIFIER member of REP based on the current state of TXN_ID
 * in FS.  Allocate the uniquifier in POOL.
 */
static svn_error_t *
set_uniquifier(svn_fs_t *fs,
               representation_t *rep,
               apr_pool_t *pool)
{
  svn_fs_fs__id_part_t temp;
  fs_fs_data_t *ffd = fs->fsap_data;

  if (ffd->format >= SVN_FS_FS__MIN_REP_SHARING_FORMAT)
    {
      SVN_ERR(get_new_txn_node_id(&temp, fs, &rep->txn_id, pool));
      rep->uniquifier.noderev_txn_id = rep->txn_id;
      rep->uniquifier.number = temp.number;
    }

  return SVN_NO_ERROR;
}

/* Return TRUE if the TXN_ID member of REP is in use.
 */
static svn_boolean_t
is_txn_rep(const representation_t *rep)
{
  return svn_fs_fs__id_txn_used(&rep->txn_id);
}

/* Mark the TXN_ID member of REP as "unused".
 */
static void
reset_txn_in_rep(representation_t *rep)
{
  svn_fs_fs__id_txn_reset(&rep->txn_id);
}

svn_error_t *
svn_fs_fs__set_entry(svn_fs_t *fs,
                     const svn_fs_fs__id_part_t *txn_id,
                     node_revision_t *parent_noderev,
                     const char *name,
                     const svn_fs_id_t *id,
                     svn_node_kind_t kind,
                     apr_pool_t *pool)
{
  representation_t *rep = parent_noderev->data_rep;
  const char *filename
    = svn_fs_fs__path_txn_node_children(fs, parent_noderev->id, pool);
  apr_file_t *file;
  svn_stream_t *out;
  svn_filesize_t filesize;
  fs_fs_data_t *ffd = fs->fsap_data;
  apr_pool_t *subpool = svn_pool_create(pool);

  if (!rep || !is_txn_rep(rep))
    {
      apr_array_header_t *entries;

      /* Before we can modify the directory, we need to dump its old
         contents into a mutable representation file. */
      SVN_ERR(svn_fs_fs__rep_contents_dir(&entries, fs, parent_noderev,
                                          subpool, subpool));
      SVN_ERR(svn_io_file_open(&file, filename,
                               APR_WRITE | APR_CREATE | APR_BUFFERED,
                               APR_OS_DEFAULT, pool));
      out = svn_stream_from_aprfile2(file, TRUE, pool);
      SVN_ERR(unparse_dir_entries(entries, out, subpool));

      /* Mark the node-rev's data rep as mutable. */
      rep = apr_pcalloc(pool, sizeof(*rep));
      rep->revision = SVN_INVALID_REVNUM;
      rep->txn_id = *txn_id;
      SVN_ERR(set_uniquifier(fs, rep, pool));
      parent_noderev->data_rep = rep;
      SVN_ERR(svn_fs_fs__put_node_revision(fs, parent_noderev->id,
                                           parent_noderev, FALSE, pool));

      /* Immediately populate the txn dir cache to avoid re-reading
       * the file we just wrote. */
      if (ffd->txn_dir_cache)
        {
          const char *key
            = svn_fs_fs__id_unparse(parent_noderev->id, subpool)->data;
          svn_fs_fs__dir_data_t dir_data;

          /* Flush APR buffers. */
          SVN_ERR(svn_io_file_flush(file, subpool));

          /* Obtain final file size to update txn_dir_cache. */
          SVN_ERR(svn_io_file_size_get(&filesize, file, subpool));

          /* Store in the cache. */
          dir_data.entries = entries;
          dir_data.txn_filesize = filesize;
          SVN_ERR(svn_cache__set(ffd->txn_dir_cache, key, &dir_data,
                                 subpool));
        }

      svn_pool_clear(subpool);
    }
  else
    {
      /* The directory rep is already mutable, so just open it for append. */
      SVN_ERR(svn_io_file_open(&file, filename, APR_WRITE | APR_APPEND,
                               APR_OS_DEFAULT, subpool));
      out = svn_stream_from_aprfile2(file, TRUE, subpool);

      /* If the cache contents is stale, drop it.
       *
       * Note that the directory file is append-only, i.e. if the size
       * did not change, the contents didn't either. */
      if (ffd->txn_dir_cache)
        {
          const char *key
            = svn_fs_fs__id_unparse(parent_noderev->id, subpool)->data;
          svn_boolean_t found;
          svn_filesize_t cached_filesize;

          /* Get the file size that corresponds to the cached contents
           * (if any). */
          SVN_ERR(svn_cache__get_partial((void **)&cached_filesize, &found,
                                         ffd->txn_dir_cache, key,
                                         svn_fs_fs__extract_dir_filesize,
                                         NULL, subpool));

          /* File size info still matches?
           * If not, we need to drop the cache entry. */
          if (found)
            {
              SVN_ERR(svn_io_file_size_get(&filesize, file, subpool));

              if (cached_filesize != filesize)
                SVN_ERR(svn_cache__set(ffd->txn_dir_cache, key, NULL,
                                       subpool));
            }
        }
    }

  /* Append an incremental hash entry for the entry change. */
  if (id)
    {
      svn_fs_dirent_t entry;
      entry.name = name;
      entry.id = id;
      entry.kind = kind;

      SVN_ERR(unparse_dir_entry(&entry, out, subpool));
    }
  else
    {
      SVN_ERR(svn_stream_printf(out, subpool, "D %" APR_SIZE_T_FMT "\n%s\n",
                                strlen(name), name));
    }

  /* Flush APR buffers. */
  SVN_ERR(svn_io_file_flush(file, subpool));

  /* Obtain final file size to update txn_dir_cache. */
  SVN_ERR(svn_io_file_size_get(&filesize, file, subpool));

  /* Close file. */
  SVN_ERR(svn_io_file_close(file, subpool));
  svn_pool_clear(subpool);

  /* if we have a directory cache for this transaction, update it */
  if (ffd->txn_dir_cache)
    {
      /* build parameters: name, new entry, new file size  */
      const char *key =
          svn_fs_fs__id_unparse(parent_noderev->id, subpool)->data;
      replace_baton_t baton;

      baton.name = name;
      baton.new_entry = NULL;
      baton.txn_filesize = filesize;

      if (id)
        {
          baton.new_entry = apr_pcalloc(subpool, sizeof(*baton.new_entry));
          baton.new_entry->name = name;
          baton.new_entry->kind = kind;
          baton.new_entry->id = id;
        }

      /* actually update the cached directory (if cached) */
      SVN_ERR(svn_cache__set_partial(ffd->txn_dir_cache, key,
                                     svn_fs_fs__replace_dir_entry, &baton,
                                     subpool));
    }

  svn_pool_destroy(subpool);
  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_fs__add_change(svn_fs_t *fs,
                      const svn_fs_fs__id_part_t *txn_id,
                      const char *path,
                      const svn_fs_id_t *id,
                      svn_fs_path_change_kind_t change_kind,
                      svn_boolean_t text_mod,
                      svn_boolean_t prop_mod,
                      svn_boolean_t mergeinfo_mod,
                      svn_node_kind_t node_kind,
                      svn_revnum_t copyfrom_rev,
                      const char *copyfrom_path,
                      apr_pool_t *pool)
{
  apr_file_t *file;
  svn_fs_path_change2_t *change;
  apr_hash_t *changes = apr_hash_make(pool);

  /* Not using APR_BUFFERED to append change in one atomic write operation. */
  SVN_ERR(svn_io_file_open(&file, path_txn_changes(fs, txn_id, pool),
                           APR_APPEND | APR_WRITE | APR_CREATE,
                           APR_OS_DEFAULT, pool));

  change = svn_fs__path_change_create_internal(id, change_kind, pool);
  change->text_mod = text_mod;
  change->prop_mod = prop_mod;
  change->mergeinfo_mod = mergeinfo_mod
                        ? svn_tristate_true
                        : svn_tristate_false;
  change->node_kind = node_kind;
  change->copyfrom_known = TRUE;
  change->copyfrom_rev = copyfrom_rev;
  if (copyfrom_path)
    change->copyfrom_path = apr_pstrdup(pool, copyfrom_path);

  svn_hash_sets(changes, path, change);
  SVN_ERR(svn_fs_fs__write_changes(svn_stream_from_aprfile2(file, TRUE, pool),
                                   fs, changes, FALSE, pool));

  return svn_io_file_close(file, pool);
}

/* Store the (ITEM_INDEX, OFFSET) pair in the txn's log-to-phys proto
 * index file.
 * Use POOL for allocations.
 * This function assumes that transaction TXN_ID in FS uses logical
 * addressing.
 */
static svn_error_t *
store_l2p_index_entry(svn_fs_t *fs,
                      const svn_fs_fs__id_part_t *txn_id,
                      apr_off_t offset,
                      apr_uint64_t item_index,
                      apr_pool_t *pool)
{
  const char *path;
  apr_file_t *file;

  SVN_ERR_ASSERT(svn_fs_fs__use_log_addressing(fs));

  path = svn_fs_fs__path_l2p_proto_index(fs, txn_id, pool);
  SVN_ERR(svn_fs_fs__l2p_proto_index_open(&file, path, pool));
  SVN_ERR(svn_fs_fs__l2p_proto_index_add_entry(file, offset,
                                               item_index, pool));
  SVN_ERR(svn_io_file_close(file, pool));

  return SVN_NO_ERROR;
}

/* Store ENTRY in the phys-to-log proto index file of transaction TXN_ID.
 * Use POOL for allocations.
 * This function assumes that transaction TXN_ID in FS uses logical
 * addressing.
 */
static svn_error_t *
store_p2l_index_entry(svn_fs_t *fs,
                      const svn_fs_fs__id_part_t *txn_id,
                      const svn_fs_fs__p2l_entry_t *entry,
                      apr_pool_t *pool)
{
  const char *path;
  apr_file_t *file;

  SVN_ERR_ASSERT(svn_fs_fs__use_log_addressing(fs));

  path = svn_fs_fs__path_p2l_proto_index(fs, txn_id, pool);
  SVN_ERR(svn_fs_fs__p2l_proto_index_open(&file, path, pool));
  SVN_ERR(svn_fs_fs__p2l_proto_index_add_entry(file, entry, pool));
  SVN_ERR(svn_io_file_close(file, pool));

  return SVN_NO_ERROR;
}

/* Allocate an item index for the given MY_OFFSET in the transaction TXN_ID
 * of file system FS and return it in *ITEM_INDEX.  For old formats, it
 * will simply return the offset as item index; in new formats, it will
 * increment the txn's item index counter file and store the mapping in
 * the proto index file.  Use POOL for allocations.
 */
static svn_error_t *
allocate_item_index(apr_uint64_t *item_index,
                    svn_fs_t *fs,
                    const svn_fs_fs__id_part_t *txn_id,
                    apr_off_t my_offset,
                    apr_pool_t *pool)
{
  if (svn_fs_fs__use_log_addressing(fs))
    {
      apr_file_t *file;
      char buffer[SVN_INT64_BUFFER_SIZE] = { 0 };
      svn_boolean_t eof = FALSE;
      apr_size_t to_write;
      apr_size_t bytes_read;
      apr_off_t offset = 0;

      /* read number, increment it and write it back to disk */
      SVN_ERR(svn_io_file_open(&file,
                         svn_fs_fs__path_txn_item_index(fs, txn_id, pool),
                         APR_READ | APR_WRITE | APR_CREATE,
                         APR_OS_DEFAULT, pool));
      SVN_ERR(svn_io_file_read_full2(file, buffer, sizeof(buffer)-1,
                                     &bytes_read, &eof, pool));

      /* Item index file should be shorter than SVN_INT64_BUFFER_SIZE,
         otherwise we truncate data. */
      if (!eof)
          return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
                                  _("Unexpected itemidx file length"));
      else if (bytes_read)
        SVN_ERR(svn_cstring_atoui64(item_index, buffer));
      else
        *item_index = SVN_FS_FS__ITEM_INDEX_FIRST_USER;

      to_write = svn__ui64toa(buffer, *item_index + 1);
      SVN_ERR(svn_io_file_seek(file, APR_SET, &offset, pool));
      SVN_ERR(svn_io_file_write_full(file, buffer, to_write, NULL, pool));
      SVN_ERR(svn_io_file_close(file, pool));

      /* write log-to-phys index */
      SVN_ERR(store_l2p_index_entry(fs, txn_id, my_offset, *item_index, pool));
    }
  else
    {
      *item_index = (apr_uint64_t)my_offset;
    }

  return SVN_NO_ERROR;
}

/* Baton used by fnv1a_write_handler to calculate the FNV checksum
 * before passing the data on to the INNER_STREAM.
 */
typedef struct fnv1a_stream_baton_t
{
  svn_stream_t *inner_stream;
  svn_checksum_ctx_t *context;
} fnv1a_stream_baton_t;

/* Implement svn_write_fn_t.
 * Update checksum and pass data on to inner stream.
 */
static svn_error_t *
fnv1a_write_handler(void *baton,
                    const char *data,
                    apr_size_t *len)
{
  fnv1a_stream_baton_t *b = baton;

  SVN_ERR(svn_checksum_update(b->context, data, *len));
  SVN_ERR(svn_stream_write(b->inner_stream, data, len));

  return SVN_NO_ERROR;
}

/* Return a stream that calculates a FNV checksum in *CONTEXT
 * over all data written to the stream and passes that data on
 * to INNER_STREAM.  Allocate objects in POOL.
 */
static svn_stream_t *
fnv1a_wrap_stream(svn_checksum_ctx_t **context,
                  svn_stream_t *inner_stream,
                  apr_pool_t *pool)
{
  svn_stream_t *outer_stream;

  fnv1a_stream_baton_t *baton = apr_pcalloc(pool, sizeof(*baton));
  baton->inner_stream = inner_stream;
  baton->context = svn_checksum_ctx_create(svn_checksum_fnv1a_32x4, pool);
  *context = baton->context;

  outer_stream = svn_stream_create(baton, pool);
  svn_stream_set_write(outer_stream, fnv1a_write_handler);

  return outer_stream;
}

/* Set *DIGEST to the FNV checksum calculated in CONTEXT.
 * Use SCRATCH_POOL for temporary allocations.
 */
static svn_error_t *
fnv1a_checksum_finalize(apr_uint32_t *digest,
                        svn_checksum_ctx_t *context,
                        apr_pool_t *scratch_pool)
{
  svn_checksum_t *checksum;

  SVN_ERR(svn_checksum_final(&checksum, context, scratch_pool));
  SVN_ERR_ASSERT(checksum->kind == svn_checksum_fnv1a_32x4);
  *digest = ntohl(*(const apr_uint32_t *)(checksum->digest));

  return SVN_NO_ERROR;
}

/* This baton is used by the representation writing streams.  It keeps
   track of the checksum information as well as the total size of the
   representation so far. */
struct rep_write_baton
{
  /* The FS we are writing to. */
  svn_fs_t *fs;

  /* Actual file to which we are writing. */
  svn_stream_t *rep_stream;

  /* A stream from the delta combiner.  Data written here gets
     deltified, then eventually written to rep_stream. */
  svn_stream_t *delta_stream;

  /* Where is this representation header stored. */
  apr_off_t rep_offset;

  /* Start of the actual data. */
  apr_off_t delta_start;

  /* How many bytes have been written to this rep already. */
  svn_filesize_t rep_size;

  /* The node revision for which we're writing out info. */
  node_revision_t *noderev;

  /* Actual output file. */
  apr_file_t *file;
  /* Lock 'cookie' used to unlock the output file once we've finished
     writing to it. */
  void *lockcookie;

  svn_checksum_ctx_t *md5_checksum_ctx;
  svn_checksum_ctx_t *sha1_checksum_ctx;

  /* calculate a modified FNV-1a checksum of the on-disk representation */
  svn_checksum_ctx_t *fnv1a_checksum_ctx;

  /* Local / scratch pool, available for temporary allocations. */
  apr_pool_t *scratch_pool;

  /* Outer / result pool. */
  apr_pool_t *result_pool;
};

/* Handler for the write method of the representation writable stream.
   BATON is a rep_write_baton, DATA is the data to write, and *LEN is
   the length of this data. */
static svn_error_t *
rep_write_contents(void *baton,
                   const char *data,
                   apr_size_t *len)
{
  struct rep_write_baton *b = baton;

  SVN_ERR(svn_checksum_update(b->md5_checksum_ctx, data, *len));
  SVN_ERR(svn_checksum_update(b->sha1_checksum_ctx, data, *len));
  b->rep_size += *len;

  /* If we are writing a delta, use that stream. */
  if (b->delta_stream)
    return svn_stream_write(b->delta_stream, data, len);
  else
    return svn_stream_write(b->rep_stream, data, len);
}

/* Set *SPANNED to the number of shards touched when walking WALK steps on
 * NODEREV's predecessor chain in FS.  Use POOL for temporary allocations.
 */
static svn_error_t *
shards_spanned(int *spanned,
               svn_fs_t *fs,
               node_revision_t *noderev,
               int walk,
               apr_pool_t *pool)
{
  fs_fs_data_t *ffd = fs->fsap_data;
  int shard_size = ffd->max_files_per_dir ? ffd->max_files_per_dir : 1;
  apr_pool_t *iterpool;

  int count = walk ? 1 : 0; /* The start of a walk already touches a shard. */
  svn_revnum_t shard, last_shard = ffd->youngest_rev_cache / shard_size;
  iterpool = svn_pool_create(pool);
  while (walk-- && noderev->predecessor_count)
    {
      svn_pool_clear(iterpool);
      SVN_ERR(svn_fs_fs__get_node_revision(&noderev, fs,
                                           noderev->predecessor_id, pool,
                                           iterpool));
      shard = svn_fs_fs__id_rev(noderev->id) / shard_size;
      if (shard != last_shard)
        {
          ++count;
          last_shard = shard;
        }
    }
  svn_pool_destroy(iterpool);

  *spanned = count;
  return SVN_NO_ERROR;
}

/* Given a node-revision NODEREV in filesystem FS, return the
   representation in *REP to use as the base for a text representation
   delta if PROPS is FALSE.  If PROPS has been set, a suitable props
   base representation will be returned.  Perform temporary allocations
   in *POOL. */
static svn_error_t *
choose_delta_base(representation_t **rep,
                  svn_fs_t *fs,
                  node_revision_t *noderev,
                  svn_boolean_t props,
                  apr_pool_t *pool)
{
  /* The zero-based index (counting from the "oldest" end), along NODEREVs line
   * predecessors, of the node-rev we will use as delta base. */
  int count;
  /* The length of the linear part of a delta chain.  (Delta chains use
   * skip-delta bits for the high-order bits and are linear in the low-order
   * bits.) */
  int walk;
  node_revision_t *base;
  fs_fs_data_t *ffd = fs->fsap_data;
  apr_pool_t *iterpool;

  /* If we have no predecessors, or that one is empty, then use the empty
   * stream as a base. */
  if (! noderev->predecessor_count)
    {
      *rep = NULL;
      return SVN_NO_ERROR;
    }

  /* Flip the rightmost '1' bit of the predecessor count to determine
     which file rev (counting from 0) we want to use.  (To see why
     count & (count - 1) unsets the rightmost set bit, think about how
     you decrement a binary number.) */
  count = noderev->predecessor_count;
  count = count & (count - 1);

  /* Finding the delta base over a very long distance can become extremely
     expensive for very deep histories, possibly causing client timeouts etc.
     OTOH, this is a rare operation and its gains are minimal. Lets simply
     start deltification anew close every other 1000 changes or so.  */
  walk = noderev->predecessor_count - count;
  if (walk > (int)ffd->max_deltification_walk)
    {
      *rep = NULL;
      return SVN_NO_ERROR;
    }

  /* We use skip delta for limiting the number of delta operations
     along very long node histories.  Close to HEAD however, we create
     a linear history to minimize delta size.  */
  if (walk < (int)ffd->max_linear_deltification)
    {
      int shards;
      SVN_ERR(shards_spanned(&shards, fs, noderev, walk, pool));

      /* We also don't want the linear deltification to span more shards
         than if deltas we used in a simple skip-delta scheme. */
      if ((1 << (--shards)) <= walk)
        count = noderev->predecessor_count - 1;
    }

  /* Walk back a number of predecessors equal to the difference
     between count and the original predecessor count.  (For example,
     if noderev has ten predecessors and we want the eighth file rev,
     walk back two predecessors.) */
  base = noderev;
  iterpool = svn_pool_create(pool);
  while ((count++) < noderev->predecessor_count)
    {
      svn_pool_clear(iterpool);
      SVN_ERR(svn_fs_fs__get_node_revision(&base, fs,
                                           base->predecessor_id, pool,
                                           iterpool));
    }
  svn_pool_destroy(iterpool);

  /* return a suitable base representation */
  *rep = props ? base->prop_rep : base->data_rep;

  /* if we encountered a shared rep, its parent chain may be different
   * from the node-rev parent chain. */
  if (*rep)
    {
      int chain_length = 0;
      int shard_count = 0;

      /* Very short rep bases are simply not worth it as we are unlikely
       * to re-coup the deltification space overhead of 20+ bytes. */
      svn_filesize_t rep_size = (*rep)->expanded_size;
      if (rep_size < 64)
        {
          *rep = NULL;
          return SVN_NO_ERROR;
        }

      /* Check whether the length of the deltification chain is acceptable.
       * Otherwise, shared reps may form a non-skipping delta chain in
       * extreme cases. */
      SVN_ERR(svn_fs_fs__rep_chain_length(&chain_length, &shard_count,
                                          *rep, fs, pool));

      /* Some reasonable limit, depending on how acceptable longer linear
       * chains are in this repo.  Also, allow for some minimal chain. */
      if (chain_length >= 2 * (int)ffd->max_linear_deltification + 2)
        *rep = NULL;
      else
        /* To make it worth opening additional shards / pack files, we
         * require that the reps have a certain minimal size.  To deltify
         * against a rep in different shard, the lower limit is 512 bytes
         * and doubles with every extra shard to visit along the delta
         * chain. */
        if (   shard_count > 1
            && ((svn_filesize_t)128 << shard_count) >= rep_size)
          *rep = NULL;
    }

  return SVN_NO_ERROR;
}

/* Something went wrong and the pool for the rep write is being
   cleared before we've finished writing the rep.  So we need
   to remove the rep from the protorevfile and we need to unlock
   the protorevfile. */
static apr_status_t
rep_write_cleanup(void *data)
{
  struct rep_write_baton *b = data;
  svn_error_t *err;

  /* Truncate and close the protorevfile. */
  err = svn_io_file_trunc(b->file, b->rep_offset, b->scratch_pool);
  err = svn_error_compose_create(err, svn_io_file_close(b->file,
                                                        b->scratch_pool));

  /* Remove our lock regardless of any preceding errors so that the
     being_written flag is always removed and stays consistent with the
     file lock which will be removed no matter what since the pool is
     going away. */
  err = svn_error_compose_create(err,
                                 unlock_proto_rev(b->fs,
                                     svn_fs_fs__id_txn_id(b->noderev->id),
                                     b->lockcookie, b->scratch_pool));
  if (err)
    {
      apr_status_t rc = err->apr_err;
      svn_error_clear(err);
      return rc;
    }

  return APR_SUCCESS;
}

static void
txdelta_to_svndiff(svn_txdelta_window_handler_t *handler,
                   void **handler_baton,
                   svn_stream_t *output,
                   svn_fs_t *fs,
                   apr_pool_t *pool)
{
  fs_fs_data_t *ffd = fs->fsap_data;
  int svndiff_version;

  if (ffd->delta_compression_type == compression_type_lz4)
    {
      SVN_ERR_ASSERT_NO_RETURN(ffd->format >= SVN_FS_FS__MIN_SVNDIFF2_FORMAT);
      svndiff_version = 2;
    }
  else if (ffd->delta_compression_type == compression_type_zlib)
    {
      SVN_ERR_ASSERT_NO_RETURN(ffd->format >= SVN_FS_FS__MIN_SVNDIFF1_FORMAT);
      svndiff_version = 1;
    }
  else
    {
      svndiff_version = 0;
    }

  svn_txdelta_to_svndiff3(handler, handler_baton, output, svndiff_version,
                          ffd->delta_compression_level, pool);
}

/* Get a rep_write_baton and store it in *WB_P for the representation
   indicated by NODEREV in filesystem FS.  Perform allocations in
   POOL.  Only appropriate for file contents, not for props or
   directory contents. */
static svn_error_t *
rep_write_get_baton(struct rep_write_baton **wb_p,
                    svn_fs_t *fs,
                    node_revision_t *noderev,
                    apr_pool_t *pool)
{
  struct rep_write_baton *b;
  apr_file_t *file;
  representation_t *base_rep;
  svn_stream_t *source;
  svn_txdelta_window_handler_t wh;
  void *whb;
  svn_fs_fs__rep_header_t header = { 0 };

  b = apr_pcalloc(pool, sizeof(*b));

  b->sha1_checksum_ctx = svn_checksum_ctx_create(svn_checksum_sha1, pool);
  b->md5_checksum_ctx = svn_checksum_ctx_create(svn_checksum_md5, pool);

  b->fs = fs;
  b->result_pool = pool;
  b->scratch_pool = svn_pool_create(pool);
  b->rep_size = 0;
  b->noderev = noderev;

  /* Open the prototype rev file and seek to its end. */
  SVN_ERR(get_writable_proto_rev(&file, &b->lockcookie,
                                 fs, svn_fs_fs__id_txn_id(noderev->id),
                                 b->scratch_pool));

  b->file = file;
  b->rep_stream = svn_stream_from_aprfile2(file, TRUE, b->scratch_pool);
  if (svn_fs_fs__use_log_addressing(fs))
    b->rep_stream = fnv1a_wrap_stream(&b->fnv1a_checksum_ctx, b->rep_stream,
                                      b->scratch_pool);

  SVN_ERR(svn_io_file_get_offset(&b->rep_offset, file, b->scratch_pool));

  /* Get the base for this delta. */
  SVN_ERR(choose_delta_base(&base_rep, fs, noderev, FALSE, b->scratch_pool));
  SVN_ERR(svn_fs_fs__get_contents(&source, fs, base_rep, TRUE,
                                  b->scratch_pool));

  /* Write out the rep header. */
  if (base_rep)
    {
      header.base_revision = base_rep->revision;
      header.base_item_index = base_rep->item_index;
      header.base_length = base_rep->size;
      header.type = svn_fs_fs__rep_delta;
    }
  else
    {
      header.type = svn_fs_fs__rep_self_delta;
    }
  SVN_ERR(svn_fs_fs__write_rep_header(&header, b->rep_stream,
                                      b->scratch_pool));

  /* Now determine the offset of the actual svndiff data. */
  SVN_ERR(svn_io_file_get_offset(&b->delta_start, file,
                                 b->scratch_pool));

  /* Cleanup in case something goes wrong. */
  apr_pool_cleanup_register(b->scratch_pool, b, rep_write_cleanup,
                            apr_pool_cleanup_null);

  /* Prepare to write the svndiff data. */
  txdelta_to_svndiff(&wh, &whb, b->rep_stream, fs, pool);

  b->delta_stream = svn_txdelta_target_push(wh, whb, source,
                                            b->scratch_pool);

  *wb_p = b;

  return SVN_NO_ERROR;
}

/* For REP->SHA1_CHECKSUM, try to find an already existing representation
   in FS and return it in *OLD_REP.  If no such representation exists or
   if rep sharing has been disabled for FS, NULL will be returned.  Since
   there may be new duplicate representations within the same uncommitted
   revision, those can be passed in REPS_HASH (maps a sha1 digest onto
   representation_t*), otherwise pass in NULL for REPS_HASH.

   The content of both representations will be compared, taking REP's content
   from FILE at OFFSET.  Only if they actually match, will *OLD_REP not be
   NULL.

   Use RESULT_POOL for *OLD_REP  allocations and SCRATCH_POOL for temporaries.
   The lifetime of *OLD_REP is limited by both, RESULT_POOL and REP lifetime.
 */
static svn_error_t *
get_shared_rep(representation_t **old_rep,
               svn_fs_t *fs,
               representation_t *rep,
               apr_file_t *file,
               apr_off_t offset,
               apr_hash_t *reps_hash,
               apr_pool_t *result_pool,
               apr_pool_t *scratch_pool)
{
  svn_error_t *err;
  fs_fs_data_t *ffd = fs->fsap_data;

  svn_checksum_t checksum;
  checksum.digest = rep->sha1_digest;
  checksum.kind = svn_checksum_sha1;

  /* Return NULL, if rep sharing has been disabled. */
  *old_rep = NULL;
  if (!ffd->rep_sharing_allowed)
    return SVN_NO_ERROR;

  /* Can't look up if we don't know the key (happens for directories). */
  if (!rep->has_sha1)
    return SVN_NO_ERROR;

  /* Check and see if we already have a representation somewhere that's
     identical to the one we just wrote out.  Start with the hash lookup
     because it is cheapest. */
  if (reps_hash)
    *old_rep = apr_hash_get(reps_hash,
                            rep->sha1_digest,
                            APR_SHA1_DIGESTSIZE);

  /* If we haven't found anything yet, try harder and consult our DB. */
  if (*old_rep == NULL)
    {
      err = svn_fs_fs__get_rep_reference(old_rep, fs, &checksum, result_pool);
      /* ### Other error codes that we shouldn't mask out? */
      if (err == SVN_NO_ERROR)
        {
          if (*old_rep)
            SVN_ERR(svn_fs_fs__check_rep(*old_rep, fs, NULL, scratch_pool));
        }
      else if (err->apr_err == SVN_ERR_FS_CORRUPT
               || SVN_ERROR_IN_CATEGORY(err->apr_err,
                                        SVN_ERR_MALFUNC_CATEGORY_START))
        {
          /* Fatal error; don't mask it.

             In particular, this block is triggered when the rep-cache refers
             to revisions in the future.  We signal that as a corruption situation
             since, once those revisions are less than youngest (because of more
             commits), the rep-cache would be invalid.
           */
          SVN_ERR(err);
        }
      else
        {
          /* Something's wrong with the rep-sharing index.  We can continue
             without rep-sharing, but warn.
           */
          (fs->warning)(fs->warning_baton, err);
          svn_error_clear(err);
          *old_rep = NULL;
        }
    }

  /* look for intra-revision matches (usually data reps but not limited
     to them in case props happen to look like some data rep)
   */
  if (*old_rep == NULL && is_txn_rep(rep))
    {
      svn_node_kind_t kind;
      const char *file_name
        = path_txn_sha1(fs, &rep->txn_id, rep->sha1_digest, scratch_pool);

      /* in our txn, is there a rep file named with the wanted SHA1?
         If so, read it and use that rep.
       */
      SVN_ERR(svn_io_check_path(file_name, &kind, scratch_pool));
      if (kind == svn_node_file)
        {
          svn_stringbuf_t *rep_string;
          SVN_ERR(svn_stringbuf_from_file2(&rep_string, file_name,
                                           scratch_pool));
          SVN_ERR(svn_fs_fs__parse_representation(old_rep, rep_string,
                                                  result_pool, scratch_pool));
        }
    }

  if (!*old_rep)
    return SVN_NO_ERROR;

  /* A simple guard against general rep-cache induced corruption. */
  if ((*old_rep)->expanded_size != rep->expanded_size)
    {
      /* Make the problem show up in the server log.

         Because not sharing reps is always a safe option,
         terminating the request would be inappropriate.
       */
      err = svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
                              "Rep size %s mismatches rep-cache.db value %s "
                              "for SHA1 %s.\n"
                              "You should delete the rep-cache.db and "
                              "verify the repository. The cached rep will "
                              "not be shared.",
                              apr_psprintf(scratch_pool,
                                           "%" SVN_FILESIZE_T_FMT,
                                           rep->expanded_size),
                              apr_psprintf(scratch_pool,
                                           "%" SVN_FILESIZE_T_FMT,
                                           (*old_rep)->expanded_size),
                              svn_checksum_to_cstring_display(&checksum,
                                                              scratch_pool));

      (fs->warning)(fs->warning_baton, err);
      svn_error_clear(err);

      /* Ignore the shared rep. */
      *old_rep = NULL;
    }
  else
    {
      /* Add information that is missing in the cached data.
         Use the old rep for this content. */
      memcpy((*old_rep)->md5_digest, rep->md5_digest, sizeof(rep->md5_digest));
      (*old_rep)->uniquifier = rep->uniquifier;
    }

  /* If we (very likely) found a matching representation, compare the actual
   * contents such that we can be sure that no rep-cache.db corruption or
   * hash collision produced a false positive. */
  if (*old_rep)
    {
      apr_off_t old_position;
      svn_stream_t *contents;
      svn_stream_t *old_contents;
      svn_boolean_t same;

      /* The existing representation may itself be part of the current
       * transaction.  In that case, it may be in different stages of
       * the commit finalization process.
       *
       * OLD_REP_NORM is the same as that OLD_REP but it is assigned
       * explicitly to REP's transaction if OLD_REP does not point
       * to an already committed revision.  This then prevents the
       * revision lookup and the txn data will be accessed.
       */
      representation_t old_rep_norm = **old_rep;
      if (   !SVN_IS_VALID_REVNUM(old_rep_norm.revision)
          || old_rep_norm.revision > ffd->youngest_rev_cache)
        old_rep_norm.txn_id = rep->txn_id;

      /* Make sure we can later restore FILE's current position. */
      SVN_ERR(svn_io_file_get_offset(&old_position, file, scratch_pool));

      /* Compare the two representations.
       * Note that the stream comparison might also produce MD5 checksum
       * errors or other failures in case of SHA1 collisions. */
      SVN_ERR(svn_fs_fs__get_contents_from_file(&contents, fs, rep, file,
                                                offset, scratch_pool));
      SVN_ERR(svn_fs_fs__get_contents(&old_contents, fs, &old_rep_norm,
                                      FALSE, scratch_pool));
      err = svn_stream_contents_same2(&same, contents, old_contents,
                                      scratch_pool);

      /* A mismatch should be extremely rare.
       * If it does happen, reject the commit. */
      if (!same || err)
        {
          /* SHA1 collision or worse. */
          svn_stringbuf_t *old_rep_str
            = svn_fs_fs__unparse_representation(*old_rep,
                                                ffd->format, FALSE,
                                                scratch_pool,
                                                scratch_pool);
          svn_stringbuf_t *rep_str
            = svn_fs_fs__unparse_representation(rep,
                                                ffd->format, FALSE,
                                                scratch_pool,
                                                scratch_pool);
          const char *checksum__str
            = svn_checksum_to_cstring_display(&checksum, scratch_pool);

          return svn_error_createf(SVN_ERR_FS_AMBIGUOUS_CHECKSUM_REP,
                                   err, "SHA1 of reps '%s' and '%s' "
                                   "matches (%s) but contents differ",
                                   old_rep_str->data, rep_str->data,
                                   checksum__str);
        }

      /* Restore FILE's read / write position. */
      SVN_ERR(svn_io_file_seek(file, APR_SET, &old_position, scratch_pool));
    }

  return SVN_NO_ERROR;
}

/* Copy the hash sum calculation results from MD5_CTX, SHA1_CTX into REP.
 * SHA1 results are only be set if SHA1_CTX is not NULL.
 * Use POOL for allocations.
 */
static svn_error_t *
digests_final(representation_t *rep,
              const svn_checksum_ctx_t *md5_ctx,
              const svn_checksum_ctx_t *sha1_ctx,
              apr_pool_t *pool)
{
  svn_checksum_t *checksum;

  SVN_ERR(svn_checksum_final(&checksum, md5_ctx, pool));
  memcpy(rep->md5_digest, checksum->digest, svn_checksum_size(checksum));
  rep->has_sha1 = sha1_ctx != NULL;
  if (rep->has_sha1)
    {
      SVN_ERR(svn_checksum_final(&checksum, sha1_ctx, pool));
      memcpy(rep->sha1_digest, checksum->digest, svn_checksum_size(checksum));
    }

  return SVN_NO_ERROR;
}

/* Close handler for the representation write stream.  BATON is a
   rep_write_baton.  Writes out a new node-rev that correctly
   references the representation we just finished writing. */
static svn_error_t *
rep_write_contents_close(void *baton)
{
  struct rep_write_baton *b = baton;
  representation_t *rep;
  representation_t *old_rep;
  apr_off_t offset;

  rep = apr_pcalloc(b->result_pool, sizeof(*rep));

  /* Close our delta stream so the last bits of svndiff are written
     out. */
  if (b->delta_stream)
    SVN_ERR(svn_stream_close(b->delta_stream));

  /* Determine the length of the svndiff data. */
  SVN_ERR(svn_io_file_get_offset(&offset, b->file, b->scratch_pool));
  rep->size = offset - b->delta_start;

  /* Fill in the rest of the representation field. */
  rep->expanded_size = b->rep_size;
  rep->txn_id = *svn_fs_fs__id_txn_id(b->noderev->id);
  SVN_ERR(set_uniquifier(b->fs, rep, b->scratch_pool));
  rep->revision = SVN_INVALID_REVNUM;

  /* Finalize the checksum. */
  SVN_ERR(digests_final(rep, b->md5_checksum_ctx, b->sha1_checksum_ctx,
                        b->result_pool));

  /* Check and see if we already have a representation somewhere that's
     identical to the one we just wrote out. */
  SVN_ERR(get_shared_rep(&old_rep, b->fs, rep, b->file, b->rep_offset, NULL,
                         b->result_pool, b->scratch_pool));

  if (old_rep)
    {
      /* We need to erase from the protorev the data we just wrote. */
      SVN_ERR(svn_io_file_trunc(b->file, b->rep_offset, b->scratch_pool));

      /* Use the old rep for this content. */
      b->noderev->data_rep = old_rep;
    }
  else
    {
      /* Write out our cosmetic end marker. */
      SVN_ERR(svn_stream_puts(b->rep_stream, "ENDREP\n"));
      SVN_ERR(allocate_item_index(&rep->item_index, b->fs, &rep->txn_id,
                                  b->rep_offset, b->scratch_pool));

      b->noderev->data_rep = rep;
    }

  /* Remove cleanup callback. */
  apr_pool_cleanup_kill(b->scratch_pool, b, rep_write_cleanup);

  /* Write out the new node-rev information. */
  SVN_ERR(svn_fs_fs__put_node_revision(b->fs, b->noderev->id, b->noderev,
                                       FALSE, b->scratch_pool));
  if (!old_rep && svn_fs_fs__use_log_addressing(b->fs))
    {
      svn_fs_fs__p2l_entry_t entry;

      entry.offset = b->rep_offset;
      SVN_ERR(svn_io_file_get_offset(&offset, b->file, b->scratch_pool));
      entry.size = offset - b->rep_offset;
      entry.type = SVN_FS_FS__ITEM_TYPE_FILE_REP;
      entry.item.revision = SVN_INVALID_REVNUM;
      entry.item.number = rep->item_index;
      SVN_ERR(fnv1a_checksum_finalize(&entry.fnv1_checksum,
                                      b->fnv1a_checksum_ctx,
                                      b->scratch_pool));

      SVN_ERR(store_p2l_index_entry(b->fs, &rep->txn_id, &entry,
                                    b->scratch_pool));
    }

  SVN_ERR(svn_io_file_close(b->file, b->scratch_pool));

  /* Write the sha1->rep mapping *after* we successfully written node
   * revision to disk. */
  if (!old_rep)
    SVN_ERR(store_sha1_rep_mapping(b->fs, b->noderev, b->scratch_pool));

  SVN_ERR(unlock_proto_rev(b->fs, &rep->txn_id, b->lockcookie,
                           b->scratch_pool));
  svn_pool_destroy(b->scratch_pool);

  return SVN_NO_ERROR;
}

/* Store a writable stream in *CONTENTS_P that will receive all data
   written and store it as the file data representation referenced by
   NODEREV in filesystem FS.  Perform temporary allocations in
   POOL.  Only appropriate for file data, not props or directory
   contents. */
static svn_error_t *
set_representation(svn_stream_t **contents_p,
                   svn_fs_t *fs,
                   node_revision_t *noderev,
                   apr_pool_t *pool)
{
  struct rep_write_baton *wb;

  if (! svn_fs_fs__id_is_txn(noderev->id))
    return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
                             _("Attempted to write to non-transaction '%s'"),
                             svn_fs_fs__id_unparse(noderev->id, pool)->data);

  SVN_ERR(rep_write_get_baton(&wb, fs, noderev, pool));

  *contents_p = svn_stream_create(wb, pool);
  svn_stream_set_write(*contents_p, rep_write_contents);
  svn_stream_set_close(*contents_p, rep_write_contents_close);

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_fs__set_contents(svn_stream_t **stream,
                        svn_fs_t *fs,
                        node_revision_t *noderev,
                        apr_pool_t *pool)
{
  if (noderev->kind != svn_node_file)
    return svn_error_create(SVN_ERR_FS_NOT_FILE, NULL,
                            _("Can't set text contents of a directory"));

  return set_representation(stream, fs, noderev, pool);
}

svn_error_t *
svn_fs_fs__create_successor(const svn_fs_id_t **new_id_p,
                            svn_fs_t *fs,
                            const svn_fs_id_t *old_idp,
                            node_revision_t *new_noderev,
                            const svn_fs_fs__id_part_t *copy_id,
                            const svn_fs_fs__id_part_t *txn_id,
                            apr_pool_t *pool)
{
  const svn_fs_id_t *id;

  if (! copy_id)
    copy_id = svn_fs_fs__id_copy_id(old_idp);
  id = svn_fs_fs__id_txn_create(svn_fs_fs__id_node_id(old_idp), copy_id,
                                txn_id, pool);

  new_noderev->id = id;

  if (! new_noderev->copyroot_path)
    {
      new_noderev->copyroot_path = apr_pstrdup(pool,
                                               new_noderev->created_path);
      new_noderev->copyroot_rev = svn_fs_fs__id_rev(new_noderev->id);
    }

  SVN_ERR(svn_fs_fs__put_node_revision(fs, new_noderev->id, new_noderev, FALSE,
                                       pool));

  *new_id_p = id;

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_fs__set_proplist(svn_fs_t *fs,
                        node_revision_t *noderev,
                        apr_hash_t *proplist,
                        apr_pool_t *pool)
{
  const char *filename
    = svn_fs_fs__path_txn_node_props(fs, noderev->id, pool);
  apr_file_t *file;
  svn_stream_t *out;

  /* Dump the property list to the mutable property file. */
  SVN_ERR(svn_io_file_open(&file, filename,
                           APR_WRITE | APR_CREATE | APR_TRUNCATE
                           | APR_BUFFERED, APR_OS_DEFAULT, pool));
  out = svn_stream_from_aprfile2(file, TRUE, pool);
  SVN_ERR(svn_hash_write2(proplist, out, SVN_HASH_TERMINATOR, pool));
  SVN_ERR(svn_io_file_close(file, pool));

  /* Mark the node-rev's prop rep as mutable, if not already done. */
  if (!noderev->prop_rep || !is_txn_rep(noderev->prop_rep))
    {
      noderev->prop_rep = apr_pcalloc(pool, sizeof(*noderev->prop_rep));
      noderev->prop_rep->txn_id = *svn_fs_fs__id_txn_id(noderev->id);
      SVN_ERR(set_uniquifier(fs, noderev->prop_rep, pool));
      noderev->prop_rep->revision = SVN_INVALID_REVNUM;
      SVN_ERR(svn_fs_fs__put_node_revision(fs, noderev->id, noderev, FALSE,
                                           pool));
    }

  return SVN_NO_ERROR;
}

/* This baton is used by the stream created for write_container_rep. */
struct write_container_baton
{
  svn_stream_t *stream;

  apr_size_t size;

  svn_checksum_ctx_t *md5_ctx;

  /* SHA1 calculation is optional. If not needed, this will be NULL. */
  svn_checksum_ctx_t *sha1_ctx;
};

/* The handler for the write_container_rep stream.  BATON is a
   write_container_baton, DATA has the data to write and *LEN is the number
   of bytes to write. */
static svn_error_t *
write_container_handler(void *baton,
                        const char *data,
                        apr_size_t *len)
{
  struct write_container_baton *whb = baton;

  SVN_ERR(svn_checksum_update(whb->md5_ctx, data, *len));
  if (whb->sha1_ctx)
    SVN_ERR(svn_checksum_update(whb->sha1_ctx, data, *len));

  SVN_ERR(svn_stream_write(whb->stream, data, len));
  whb->size += *len;

  return SVN_NO_ERROR;
}

/* Callback function type.  Write the data provided by BATON into STREAM. */
typedef svn_error_t *
(* collection_writer_t)(svn_stream_t *stream, void *baton, apr_pool_t *pool);

/* Implement collection_writer_t writing the C string->svn_string_t hash
   given as BATON. */
static svn_error_t *
write_hash_to_stream(svn_stream_t *stream,
                     void *baton,
                     apr_pool_t *pool)
{
  apr_hash_t *hash = baton;
  SVN_ERR(svn_hash_write2(hash, stream, SVN_HASH_TERMINATOR, pool));

  return SVN_NO_ERROR;
}

/* Implement collection_writer_t writing the svn_fs_dirent_t* array given
   as BATON. */
static svn_error_t *
write_directory_to_stream(svn_stream_t *stream,
                          void *baton,
                          apr_pool_t *pool)
{
  apr_array_header_t *dir = baton;
  SVN_ERR(unparse_dir_entries(dir, stream, pool));

  return SVN_NO_ERROR;
}

/* Write out the COLLECTION as a text representation to file FILE using
   WRITER.  In the process, record position, the total size of the dump and
   MD5 as well as SHA1 in REP.   Add the representation of type ITEM_TYPE to
   the indexes if necessary.

   If ALLOW_REP_SHARING is FALSE, rep-sharing will not be used, regardless
   of any other option and rep-sharing settings.  If rep sharing has been
   enabled and REPS_HASH is not NULL, it will be used in addition to the
   on-disk cache to find earlier reps with the same content.  If such
   existing reps can be found, we will truncate the one just written from
   the file and return the existing rep.

   Perform temporary allocations in SCRATCH_POOL. */
static svn_error_t *
write_container_rep(representation_t *rep,
                    apr_file_t *file,
                    void *collection,
                    collection_writer_t writer,
                    svn_fs_t *fs,
                    apr_hash_t *reps_hash,
                    svn_boolean_t allow_rep_sharing,
                    apr_uint32_t item_type,
                    apr_pool_t *scratch_pool)
{
  svn_stream_t *stream;
  struct write_container_baton *whb;
  svn_checksum_ctx_t *fnv1a_checksum_ctx;
  apr_off_t offset = 0;

  SVN_ERR(svn_io_file_get_offset(&offset, file, scratch_pool));

  whb = apr_pcalloc(scratch_pool, sizeof(*whb));

  whb->stream = svn_stream_from_aprfile2(file, TRUE, scratch_pool);
  if (svn_fs_fs__use_log_addressing(fs))
    whb->stream = fnv1a_wrap_stream(&fnv1a_checksum_ctx, whb->stream,
                                    scratch_pool);
  else
    fnv1a_checksum_ctx = NULL;
  whb->size = 0;
  whb->md5_ctx = svn_checksum_ctx_create(svn_checksum_md5, scratch_pool);
  if (item_type != SVN_FS_FS__ITEM_TYPE_DIR_REP)
    whb->sha1_ctx = svn_checksum_ctx_create(svn_checksum_sha1, scratch_pool);

  stream = svn_stream_create(whb, scratch_pool);
  svn_stream_set_write(stream, write_container_handler);

  SVN_ERR(svn_stream_puts(whb->stream, "PLAIN\n"));

  SVN_ERR(writer(stream, collection, scratch_pool));

  /* Store the results. */
  SVN_ERR(digests_final(rep, whb->md5_ctx, whb->sha1_ctx, scratch_pool));

  /* Update size info. */
  rep->expanded_size = whb->size;
  rep->size = whb->size;

  /* Check and see if we already have a representation somewhere that's
     identical to the one we just wrote out. */
  if (allow_rep_sharing)
    {
      representation_t *old_rep;
      SVN_ERR(get_shared_rep(&old_rep, fs, rep, file, offset, reps_hash,
                             scratch_pool, scratch_pool));

      if (old_rep)
        {
          /* We need to erase from the protorev the data we just wrote. */
          SVN_ERR(svn_io_file_trunc(file, offset, scratch_pool));

          /* Use the old rep for this content. */
          memcpy(rep, old_rep, sizeof (*rep));
          return SVN_NO_ERROR;
        }
    }

  /* Write out our cosmetic end marker. */
  SVN_ERR(svn_stream_puts(whb->stream, "ENDREP\n"));

  SVN_ERR(allocate_item_index(&rep->item_index, fs, &rep->txn_id,
                              offset, scratch_pool));

  if (svn_fs_fs__use_log_addressing(fs))
    {
      svn_fs_fs__p2l_entry_t entry;

      entry.offset = offset;
      SVN_ERR(svn_io_file_get_offset(&offset, file, scratch_pool));
      entry.size = offset - entry.offset;
      entry.type = item_type;
      entry.item.revision = SVN_INVALID_REVNUM;
      entry.item.number = rep->item_index;
      SVN_ERR(fnv1a_checksum_finalize(&entry.fnv1_checksum,
                                      fnv1a_checksum_ctx,
                                      scratch_pool));

      SVN_ERR(store_p2l_index_entry(fs, &rep->txn_id, &entry, scratch_pool));
    }

  return SVN_NO_ERROR;
}

/* Write out the COLLECTION pertaining to the NODEREV in FS as a deltified
   text representation to file FILE using WRITER.  In the process, record the
   total size and the md5 digest in REP and add the representation of type
   ITEM_TYPE to the indexes if necessary.

   If ALLOW_REP_SHARING is FALSE, rep-sharing will not be used, regardless
   of any other option and rep-sharing settings.  If rep sharing has been
   enabled and REPS_HASH is not NULL, it will be used in addition to the
   on-disk cache to find earlier reps with the same content.  If such
   existing reps can be found, we will truncate the one just written from
   the file and return the existing rep.

   If ITEM_TYPE is IS_PROPS equals SVN_FS_FS__ITEM_TYPE_*_PROPS, assume
   that we want to a props representation as the base for our delta.
   Perform temporary allocations in SCRATCH_POOL.
 */
static svn_error_t *
write_container_delta_rep(representation_t *rep,
                          apr_file_t *file,
                          void *collection,
                          collection_writer_t writer,
                          svn_fs_t *fs,
                          node_revision_t *noderev,
                          apr_hash_t *reps_hash,
                          svn_boolean_t allow_rep_sharing,
                          apr_uint32_t item_type,
                          apr_pool_t *scratch_pool)
{
  svn_txdelta_window_handler_t diff_wh;
  void *diff_whb;

  svn_stream_t *file_stream;
  svn_stream_t *stream;
  representation_t *base_rep;
  svn_checksum_ctx_t *fnv1a_checksum_ctx;
  svn_stream_t *source;
  svn_fs_fs__rep_header_t header = { 0 };

  apr_off_t rep_end = 0;
  apr_off_t delta_start = 0;
  apr_off_t offset = 0;

  struct write_container_baton *whb;
  svn_boolean_t is_props = (item_type == SVN_FS_FS__ITEM_TYPE_FILE_PROPS)
                        || (item_type == SVN_FS_FS__ITEM_TYPE_DIR_PROPS);

  /* Get the base for this delta. */
  SVN_ERR(choose_delta_base(&base_rep, fs, noderev, is_props, scratch_pool));
  SVN_ERR(svn_fs_fs__get_contents(&source, fs, base_rep, FALSE, scratch_pool));

  SVN_ERR(svn_io_file_get_offset(&offset, file, scratch_pool));

  /* Write out the rep header. */
  if (base_rep)
    {
      header.base_revision = base_rep->revision;
      header.base_item_index = base_rep->item_index;
      header.base_length = base_rep->size;
      header.type = svn_fs_fs__rep_delta;
    }
  else
    {
      header.type = svn_fs_fs__rep_self_delta;
    }

  file_stream = svn_stream_from_aprfile2(file, TRUE, scratch_pool);
  if (svn_fs_fs__use_log_addressing(fs))
    file_stream = fnv1a_wrap_stream(&fnv1a_checksum_ctx, file_stream,
                                    scratch_pool);
  else
    fnv1a_checksum_ctx = NULL;
  SVN_ERR(svn_fs_fs__write_rep_header(&header, file_stream, scratch_pool));
  SVN_ERR(svn_io_file_get_offset(&delta_start, file, scratch_pool));

  /* Prepare to write the svndiff data. */
  txdelta_to_svndiff(&diff_wh, &diff_whb, file_stream, fs, scratch_pool);

  whb = apr_pcalloc(scratch_pool, sizeof(*whb));
  whb->stream = svn_txdelta_target_push(diff_wh, diff_whb, source,
                                        scratch_pool);
  whb->size = 0;
  whb->md5_ctx = svn_checksum_ctx_create(svn_checksum_md5, scratch_pool);
  if (item_type != SVN_FS_FS__ITEM_TYPE_DIR_REP)
    whb->sha1_ctx = svn_checksum_ctx_create(svn_checksum_sha1, scratch_pool);

  /* serialize the hash */
  stream = svn_stream_create(whb, scratch_pool);
  svn_stream_set_write(stream, write_container_handler);

  SVN_ERR(writer(stream, collection, scratch_pool));
  SVN_ERR(svn_stream_close(whb->stream));

  /* Store the results. */
  SVN_ERR(digests_final(rep, whb->md5_ctx, whb->sha1_ctx, scratch_pool));

  /* Update size info. */
  SVN_ERR(svn_io_file_get_offset(&rep_end, file, scratch_pool));
  rep->size = rep_end - delta_start;
  rep->expanded_size = whb->size;

  /* Check and see if we already have a representation somewhere that's
     identical to the one we just wrote out. */
  if (allow_rep_sharing)
    {
      representation_t *old_rep;
      SVN_ERR(get_shared_rep(&old_rep, fs, rep, file, offset, reps_hash,
                             scratch_pool, scratch_pool));

      if (old_rep)
        {
          /* We need to erase from the protorev the data we just wrote. */
          SVN_ERR(svn_io_file_trunc(file, offset, scratch_pool));

          /* Use the old rep for this content. */
          memcpy(rep, old_rep, sizeof (*rep));
          return SVN_NO_ERROR;
        }
    }

  /* Write out our cosmetic end marker. */
  SVN_ERR(svn_stream_puts(file_stream, "ENDREP\n"));

  SVN_ERR(allocate_item_index(&rep->item_index, fs, &rep->txn_id,
                              offset, scratch_pool));

  if (svn_fs_fs__use_log_addressing(fs))
    {
      svn_fs_fs__p2l_entry_t entry;

      entry.offset = offset;
      SVN_ERR(svn_io_file_get_offset(&offset, file, scratch_pool));
      entry.size = offset - entry.offset;
      entry.type = item_type;
      entry.item.revision = SVN_INVALID_REVNUM;
      entry.item.number = rep->item_index;
      SVN_ERR(fnv1a_checksum_finalize(&entry.fnv1_checksum,
                                      fnv1a_checksum_ctx,
                                      scratch_pool));

      SVN_ERR(store_p2l_index_entry(fs, &rep->txn_id, &entry, scratch_pool));
    }

  return SVN_NO_ERROR;
}

/* Sanity check ROOT_NODEREV, a candidate for being the root node-revision
   of (not yet committed) revision REV in FS.  Use POOL for temporary
   allocations.

   If you change this function, consider updating svn_fs_fs__verify() too.
 */
static svn_error_t *
validate_root_noderev(svn_fs_t *fs,
                      node_revision_t *root_noderev,
                      svn_revnum_t rev,
                      apr_pool_t *pool)
{
  svn_revnum_t head_revnum = rev-1;
  int head_predecessor_count;

  SVN_ERR_ASSERT(rev > 0);

  /* Compute HEAD_PREDECESSOR_COUNT. */
  {
    svn_fs_root_t *head_revision;
    const svn_fs_id_t *head_root_id;
    node_revision_t *head_root_noderev;

    /* Get /@HEAD's noderev. */
    SVN_ERR(svn_fs_fs__revision_root(&head_revision, fs, head_revnum, pool));
    SVN_ERR(svn_fs_fs__node_id(&head_root_id, head_revision, "/", pool));
    SVN_ERR(svn_fs_fs__get_node_revision(&head_root_noderev, fs, head_root_id,
                                         pool, pool));
    head_predecessor_count = head_root_noderev->predecessor_count;
  }

  /* Check that the root noderev's predecessor count equals REV.

     This kind of corruption was seen on svn.apache.org (both on
     the root noderev and on other fspaths' noderevs); see
     issue #4129.

     Normally (rev == root_noderev->predecessor_count), but here we
     use a more roundabout check that should only trigger on new instances
     of the corruption, rather than trigger on each and every new commit
     to a repository that has triggered the bug somewhere in its root
     noderev's history.
   */
  if (   (root_noderev->predecessor_count - head_predecessor_count)
      != (rev - head_revnum))
    {
      return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
                               _("predecessor count for "
                                 "the root node-revision is wrong: "
                                 "found (%d+%ld != %d), committing r%ld"),
                                 head_predecessor_count,
                                 rev - head_revnum, /* This is equal to 1. */
                                 root_noderev->predecessor_count,
                                 rev);
    }

  return SVN_NO_ERROR;
}

/* Given the potentially txn-local id PART, update that to a permanent ID
 * based on the REVISION currently being written and the START_ID for that
 * revision.  Use the repo FORMAT to decide which implementation to use.
 */
static void
get_final_id(svn_fs_fs__id_part_t *part,
             svn_revnum_t revision,
             apr_uint64_t start_id,
             int format)
{
  if (part->revision == SVN_INVALID_REVNUM)
    {
      if (format >= SVN_FS_FS__MIN_NO_GLOBAL_IDS_FORMAT)
        {
          part->revision = revision;
        }
      else
        {
          part->revision = 0;
          part->number += start_id;
        }
    }
}

/* Copy a node-revision specified by id ID in fileystem FS from a
   transaction into the proto-rev-file FILE.  Set *NEW_ID_P to a
   pointer to the new node-id which will be allocated in POOL.
   If this is a directory, copy all children as well.

   START_NODE_ID and START_COPY_ID are
   the first available node and copy ids for this filesystem, for older
   FS formats.

   REV is the revision number that this proto-rev-file will represent.

   INITIAL_OFFSET is the offset of the proto-rev-file on entry to
   commit_body.

   Collect the pair_cache_key_t of all directories written to the
   committed cache in DIRECTORY_IDS.

   If REPS_TO_CACHE is not NULL, append to it a copy (allocated in
   REPS_POOL) of each data rep that is new in this revision.

   If REPS_HASH is not NULL, append copies (allocated in REPS_POOL)
   of the representations of each property rep that is new in this
   revision.

   AT_ROOT is true if the node revision being written is the root
   node-revision.  It is only controls additional sanity checking
   logic.

   Temporary allocations are also from POOL. */
static svn_error_t *
write_final_rev(const svn_fs_id_t **new_id_p,
                apr_file_t *file,
                svn_revnum_t rev,
                svn_fs_t *fs,
                const svn_fs_id_t *id,
                apr_uint64_t start_node_id,
                apr_uint64_t start_copy_id,
                apr_off_t initial_offset,
                apr_array_header_t *directory_ids,
                apr_array_header_t *reps_to_cache,
                apr_hash_t *reps_hash,
                apr_pool_t *reps_pool,
                svn_boolean_t at_root,
                apr_pool_t *pool)
{
  node_revision_t *noderev;
  apr_off_t my_offset;
  const svn_fs_id_t *new_id;
  svn_fs_fs__id_part_t node_id, copy_id, rev_item;
  fs_fs_data_t *ffd = fs->fsap_data;
  const svn_fs_fs__id_part_t *txn_id = svn_fs_fs__id_txn_id(id);
  svn_stream_t *file_stream;
  svn_checksum_ctx_t *fnv1a_checksum_ctx;
  apr_pool_t *subpool;

  *new_id_p = NULL;

  /* Check to see if this is a transaction node. */
  if (! svn_fs_fs__id_is_txn(id))
    return SVN_NO_ERROR;

  subpool = svn_pool_create(pool);
  SVN_ERR(svn_fs_fs__get_node_revision(&noderev, fs, id, pool, subpool));

  if (noderev->kind == svn_node_dir)
    {
      apr_array_header_t *entries;
      int i;

      /* This is a directory.  Write out all the children first. */

      SVN_ERR(svn_fs_fs__rep_contents_dir(&entries, fs, noderev, pool,
                                          subpool));
      for (i = 0; i < entries->nelts; ++i)
        {
          svn_fs_dirent_t *dirent
            = APR_ARRAY_IDX(entries, i, svn_fs_dirent_t *);

          svn_pool_clear(subpool);
          SVN_ERR(write_final_rev(&new_id, file, rev, fs, dirent->id,
                                  start_node_id, start_copy_id, initial_offset,
                                  directory_ids, reps_to_cache, reps_hash,
                                  reps_pool, FALSE, subpool));
          if (new_id && (svn_fs_fs__id_rev(new_id) == rev))
            dirent->id = svn_fs_fs__id_copy(new_id, pool);
        }

      if (noderev->data_rep && is_txn_rep(noderev->data_rep))
        {
          pair_cache_key_t *key;
          svn_fs_fs__dir_data_t dir_data;

          /* Write out the contents of this directory as a text rep. */
          noderev->data_rep->revision = rev;
          if (ffd->deltify_directories)
            SVN_ERR(write_container_delta_rep(noderev->data_rep, file,
                                              entries,
                                              write_directory_to_stream,
                                              fs, noderev, NULL, FALSE,
                                              SVN_FS_FS__ITEM_TYPE_DIR_REP,
                                              pool));
          else
            SVN_ERR(write_container_rep(noderev->data_rep, file, entries,
                                        write_directory_to_stream, fs, NULL,
                                        FALSE, SVN_FS_FS__ITEM_TYPE_DIR_REP,
                                        pool));

          reset_txn_in_rep(noderev->data_rep);

          /* Cache the new directory contents.  Otherwise, subsequent reads
           * or commits will likely have to reconstruct, verify and parse
           * it again. */
          key = apr_array_push(directory_ids);
          key->revision = noderev->data_rep->revision;
          key->second = noderev->data_rep->item_index;

          /* Store directory contents under the new revision number but mark
           * it as "stale" by setting the file length to 0.  Committed dirs
           * will report -1, in-txn dirs will report > 0, so that this can
           * never match.  We reset that to -1 after the commit is complete.
           */
          dir_data.entries = entries;
          dir_data.txn_filesize = 0;

          SVN_ERR(svn_cache__set(ffd->dir_cache, key, &dir_data, subpool));
        }
    }
  else
    {
      /* This is a file.  We should make sure the data rep, if it
         exists in a "this" state, gets rewritten to our new revision
         num. */

      if (noderev->data_rep && is_txn_rep(noderev->data_rep))
        {
          reset_txn_in_rep(noderev->data_rep);
          noderev->data_rep->revision = rev;

          if (!svn_fs_fs__use_log_addressing(fs))
            {
              /* See issue 3845.  Some unknown mechanism caused the
                 protorev file to get truncated, so check for that
                 here.  */
              if (noderev->data_rep->item_index + noderev->data_rep->size
                  > initial_offset)
                return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
                                        _("Truncated protorev file detected"));
            }
        }
    }

  svn_pool_destroy(subpool);

  /* Fix up the property reps. */
  if (noderev->prop_rep && is_txn_rep(noderev->prop_rep))
    {
      apr_hash_t *proplist;
      apr_uint32_t item_type = noderev->kind == svn_node_dir
                             ? SVN_FS_FS__ITEM_TYPE_DIR_PROPS
                             : SVN_FS_FS__ITEM_TYPE_FILE_PROPS;
      SVN_ERR(svn_fs_fs__get_proplist(&proplist, fs, noderev, pool));
      noderev->prop_rep->txn_id = *txn_id;
      SVN_ERR(set_uniquifier(fs, noderev->prop_rep, pool));
      noderev->prop_rep->revision = rev;

      if (ffd->deltify_properties)
        SVN_ERR(write_container_delta_rep(noderev->prop_rep, file, proplist,
                                          write_hash_to_stream, fs, noderev,
                                          reps_hash, TRUE, item_type, pool));
      else
        SVN_ERR(write_container_rep(noderev->prop_rep, file, proplist,
                                    write_hash_to_stream, fs, reps_hash,
                                    TRUE, item_type, pool));

      reset_txn_in_rep(noderev->prop_rep);
    }

  /* Convert our temporary ID into a permanent revision one. */
  node_id = *svn_fs_fs__id_node_id(noderev->id);
  get_final_id(&node_id, rev, start_node_id, ffd->format);
  copy_id = *svn_fs_fs__id_copy_id(noderev->id);
  get_final_id(&copy_id, rev, start_copy_id, ffd->format);

  if (noderev->copyroot_rev == SVN_INVALID_REVNUM)
    noderev->copyroot_rev = rev;

  /* root nodes have a fixed ID in log addressing mode */
  SVN_ERR(svn_io_file_get_offset(&my_offset, file, pool));
  if (svn_fs_fs__use_log_addressing(fs) && at_root)
    {
      /* reference the root noderev from the log-to-phys index */
      rev_item.number = SVN_FS_FS__ITEM_INDEX_ROOT_NODE;
      SVN_ERR(store_l2p_index_entry(fs, txn_id, my_offset,
                                    rev_item.number, pool));
    }
  else
    SVN_ERR(allocate_item_index(&rev_item.number, fs, txn_id,
                                my_offset, pool));

  rev_item.revision = rev;
  new_id = svn_fs_fs__id_rev_create(&node_id, &copy_id, &rev_item, pool);

  noderev->id = new_id;

  if (ffd->rep_sharing_allowed)
    {
      /* Save the data representation's hash in the rep cache. */
      if (   noderev->data_rep && noderev->kind == svn_node_file
          && noderev->data_rep->revision == rev)
        {
          SVN_ERR_ASSERT(reps_to_cache && reps_pool);
          APR_ARRAY_PUSH(reps_to_cache, representation_t *)
            = svn_fs_fs__rep_copy(noderev->data_rep, reps_pool);
        }

      if (noderev->prop_rep && noderev->prop_rep->revision == rev)
        {
          /* Add new property reps to hash and on-disk cache. */
          representation_t *copy
            = svn_fs_fs__rep_copy(noderev->prop_rep, reps_pool);

          SVN_ERR_ASSERT(reps_to_cache && reps_pool);
          APR_ARRAY_PUSH(reps_to_cache, representation_t *) = copy;

          apr_hash_set(reps_hash,
                        copy->sha1_digest,
                        APR_SHA1_DIGESTSIZE,
                        copy);
        }
    }

  /* don't serialize SHA1 for dir content to disk (waste of space) */
  /* ### Could clients record bogus last-changed-revisions (issue #4700)? */
  if (noderev->data_rep && noderev->kind == svn_node_dir)
    noderev->data_rep->has_sha1 = FALSE;

  /* Compatibility: while we don't need to serialize SHA1 for props (it is
     not used), older formats can only have representation strings that either
     have both the SHA1 value *and* the uniquifier, or don't have them at all.
     For such formats, both values get written to the disk only if the SHA1
     is present.

     We cannot omit the uniquifier, as doing so breaks svn_fs_props_changed()
     for properties with shared representations, see issues #4623 and #4700.
     Therefore, we skip writing SHA1, but only for the newer formats where
     this dependency is untied and we can write the uniquifier to the disk
     without the SHA1.
   */
  if (ffd->format >= SVN_FS_FS__MIN_REP_STRING_OPTIONAL_VALUES_FORMAT &&
      noderev->prop_rep)
    {
      noderev->prop_rep->has_sha1 = FALSE;
    }

  /* Workaround issue #4031: is-fresh-txn-root in revision files. */
  noderev->is_fresh_txn_root = FALSE;

  /* Write out our new node-revision. */
  if (at_root)
    SVN_ERR(validate_root_noderev(fs, noderev, rev, pool));

  file_stream = svn_stream_from_aprfile2(file, TRUE, pool);
  if (svn_fs_fs__use_log_addressing(fs))
    file_stream = fnv1a_wrap_stream(&fnv1a_checksum_ctx, file_stream, pool);
  else
    fnv1a_checksum_ctx = NULL;

  SVN_ERR(svn_fs_fs__write_noderev(file_stream, noderev, ffd->format,
                                   svn_fs_fs__fs_supports_mergeinfo(fs),
                                   pool));

  /* reference the root noderev from the log-to-phys index */
  if (svn_fs_fs__use_log_addressing(fs))
    {
      svn_fs_fs__p2l_entry_t entry;
      rev_item.revision = SVN_INVALID_REVNUM;

      entry.offset = my_offset;
      SVN_ERR(svn_io_file_get_offset(&my_offset, file, pool));
      entry.size = my_offset - entry.offset;
      entry.type = SVN_FS_FS__ITEM_TYPE_NODEREV;
      entry.item = rev_item;
      SVN_ERR(fnv1a_checksum_finalize(&entry.fnv1_checksum,
                                      fnv1a_checksum_ctx,
                                      pool));

      SVN_ERR(store_p2l_index_entry(fs, txn_id, &entry, pool));
    }

  /* Return our ID that references the revision file. */
  *new_id_p = noderev->id;

  return SVN_NO_ERROR;
}

/* Write the changed path info CHANGED_PATHS from transaction TXN_ID to the
   permanent rev-file FILE in filesystem FS.  *OFFSET_P is set the to offset
   in the file of the beginning of this information.  Perform temporary
   allocations in POOL. */
static svn_error_t *
write_final_changed_path_info(apr_off_t *offset_p,
                              apr_file_t *file,
                              svn_fs_t *fs,
                              const svn_fs_fs__id_part_t *txn_id,
                              apr_hash_t *changed_paths,
                              apr_pool_t *pool)
{
  apr_off_t offset;
  svn_stream_t *stream;
  svn_checksum_ctx_t *fnv1a_checksum_ctx;

  SVN_ERR(svn_io_file_get_offset(&offset, file, pool));

  /* write to target file & calculate checksum if needed */
  stream = svn_stream_from_aprfile2(file, TRUE, pool);
  if (svn_fs_fs__use_log_addressing(fs))
    stream = fnv1a_wrap_stream(&fnv1a_checksum_ctx, stream, pool);
  else
    fnv1a_checksum_ctx = NULL;

  SVN_ERR(svn_fs_fs__write_changes(stream, fs, changed_paths, TRUE, pool));

  *offset_p = offset;

  /* reference changes from the indexes */
  if (svn_fs_fs__use_log_addressing(fs))
    {
      svn_fs_fs__p2l_entry_t entry;

      entry.offset = offset;
      SVN_ERR(svn_io_file_get_offset(&offset, file, pool));
      entry.size = offset - entry.offset;
      entry.type = SVN_FS_FS__ITEM_TYPE_CHANGES;
      entry.item.revision = SVN_INVALID_REVNUM;
      entry.item.number = SVN_FS_FS__ITEM_INDEX_CHANGES;
      SVN_ERR(fnv1a_checksum_finalize(&entry.fnv1_checksum,
                                      fnv1a_checksum_ctx,
                                      pool));

      SVN_ERR(store_p2l_index_entry(fs, txn_id, &entry, pool));
      SVN_ERR(store_l2p_index_entry(fs, txn_id, entry.offset,
                                    SVN_FS_FS__ITEM_INDEX_CHANGES, pool));
    }

  return SVN_NO_ERROR;
}

/* Open a new svn_fs_t handle to FS, set that handle's concept of "current
   youngest revision" to NEW_REV, and call svn_fs_fs__verify_root() on
   NEW_REV's revision root.

   Intended to be called as the very last step in a commit before 'current'
   is bumped.  This implies that we are holding the write lock. */
static svn_error_t *
verify_before_commit(svn_fs_t *fs,
                     svn_revnum_t new_rev,
                     apr_pool_t *pool)
{
  fs_fs_data_t *ffd = fs->fsap_data;
  svn_fs_t *ft; /* fs++ == ft */
  svn_fs_root_t *root;
  fs_fs_data_t *ft_ffd;
  apr_hash_t *fs_config;

  SVN_ERR_ASSERT(ffd->svn_fs_open_);

  /* make sure FT does not simply return data cached by other instances
   * but actually retrieves it from disk at least once.
   */
  fs_config = apr_hash_make(pool);
  svn_hash_sets(fs_config, SVN_FS_CONFIG_FSFS_CACHE_NS,
                           svn_uuid_generate(pool));
  SVN_ERR(ffd->svn_fs_open_(&ft, fs->path,
                            fs_config,
                            pool,
                            pool));
  ft_ffd = ft->fsap_data;
  /* Don't let FT consult rep-cache.db, either. */
  ft_ffd->rep_sharing_allowed = FALSE;

  /* Time travel! */
  ft_ffd->youngest_rev_cache = new_rev;

  SVN_ERR(svn_fs_fs__revision_root(&root, ft, new_rev, pool));
  SVN_ERR_ASSERT(root->is_txn_root == FALSE && root->rev == new_rev);
  SVN_ERR_ASSERT(ft_ffd->youngest_rev_cache == new_rev);
  SVN_ERR(svn_fs_fs__verify_root(root, pool));

  return SVN_NO_ERROR;
}

/* Update the 'current' file to hold the correct next node and copy_ids
   from transaction TXN_ID in filesystem FS.  The current revision is
   set to REV.  Perform temporary allocations in POOL. */
static svn_error_t *
write_final_current(svn_fs_t *fs,
                    const svn_fs_fs__id_part_t *txn_id,
                    svn_revnum_t rev,
                    apr_uint64_t start_node_id,
                    apr_uint64_t start_copy_id,
                    apr_pool_t *pool)
{
  apr_uint64_t txn_node_id;
  apr_uint64_t txn_copy_id;
  fs_fs_data_t *ffd = fs->fsap_data;

  if (ffd->format >= SVN_FS_FS__MIN_NO_GLOBAL_IDS_FORMAT)
    return svn_fs_fs__write_current(fs, rev, 0, 0, pool);

  /* To find the next available ids, we add the id that used to be in
     the 'current' file, to the next ids from the transaction file. */
  SVN_ERR(read_next_ids(&txn_node_id, &txn_copy_id, fs, txn_id, pool));

  start_node_id += txn_node_id;
  start_copy_id += txn_copy_id;

  return svn_fs_fs__write_current(fs, rev, start_node_id, start_copy_id,
                                  pool);
}

/* Verify that the user registered with FS has all the locks necessary to
   permit all the changes associated with TXN_NAME.
   The FS write lock is assumed to be held by the caller. */
static svn_error_t *
verify_locks(svn_fs_t *fs,
             const svn_fs_fs__id_part_t *txn_id,
             apr_hash_t *changed_paths,
             apr_pool_t *pool)
{
  apr_pool_t *iterpool;
  apr_array_header_t *changed_paths_sorted;
  svn_stringbuf_t *last_recursed = NULL;
  int i;

  /* Make an array of the changed paths, and sort them depth-first-ily.  */
  changed_paths_sorted = svn_sort__hash(changed_paths,
                                        svn_sort_compare_items_as_paths,
                                        pool);

  /* Now, traverse the array of changed paths, verify locks.  Note
     that if we need to do a recursive verification a path, we'll skip
     over children of that path when we get to them. */
  iterpool = svn_pool_create(pool);
  for (i = 0; i < changed_paths_sorted->nelts; i++)
    {
      const svn_sort__item_t *item;
      const char *path;
      svn_fs_path_change2_t *change;
      svn_boolean_t recurse = TRUE;

      svn_pool_clear(iterpool);

      item = &APR_ARRAY_IDX(changed_paths_sorted, i, svn_sort__item_t);

      /* Fetch the change associated with our path.  */
      path = item->key;
      change = item->value;

      /* If this path has already been verified as part of a recursive
         check of one of its parents, no need to do it again.  */
      if (last_recursed
          && svn_fspath__skip_ancestor(last_recursed->data, path))
        continue;

      /* What does it mean to succeed at lock verification for a given
         path?  For an existing file or directory getting modified
         (text, props), it means we hold the lock on the file or
         directory.  For paths being added or removed, we need to hold
         the locks for that path and any children of that path.

         WHEW!  We have no reliable way to determine the node kind
         of deleted items, but fortunately we are going to do a
         recursive check on deleted paths regardless of their kind.  */
      if (change->change_kind == svn_fs_path_change_modify)
        recurse = FALSE;
      SVN_ERR(svn_fs_fs__allow_locked_operation(path, fs, recurse, TRUE,
                                                iterpool));

      /* If we just did a recursive check, remember the path we
         checked (so children can be skipped).  */
      if (recurse)
        {
          if (! last_recursed)
            last_recursed = svn_stringbuf_create(path, pool);
          else
            svn_stringbuf_set(last_recursed, path);
        }
    }
  svn_pool_destroy(iterpool);
  return SVN_NO_ERROR;
}

/* Writes final revision properties to file PATH applying permissions
   from file PERMS_REFERENCE. This involves setting svn:date and
   removing any temporary properties associated with the commit flags. */
static svn_error_t *
write_final_revprop(const char *path,
                    const char *perms_reference,
                    svn_fs_txn_t *txn,
                    svn_boolean_t flush_to_disk,
                    apr_pool_t *pool)
{
  apr_hash_t *txnprops;
  svn_string_t date;
  svn_string_t *client_date;
  apr_file_t *revprop_file;
  svn_stream_t *stream;

  SVN_ERR(svn_fs_fs__txn_proplist(&txnprops, txn, pool));

  /* Remove any temporary txn props representing 'flags'. */
  svn_hash_sets(txnprops, SVN_FS__PROP_TXN_CHECK_OOD, NULL);
  svn_hash_sets(txnprops, SVN_FS__PROP_TXN_CHECK_LOCKS, NULL);

  client_date = svn_hash_gets(txnprops, SVN_FS__PROP_TXN_CLIENT_DATE);
  if (client_date)
    {
      svn_hash_sets(txnprops, SVN_FS__PROP_TXN_CLIENT_DATE, NULL);
    }

  /* Update commit time to ensure that svn:date revprops remain ordered if
     requested. */
  if (!client_date || strcmp(client_date->data, "1"))
    {
      date.data = svn_time_to_cstring(apr_time_now(), pool);
      date.len = strlen(date.data);
      svn_hash_sets(txnprops, SVN_PROP_REVISION_DATE, &date);
    }

  /* Create new revprops file. Tell OS to truncate existing file,
     since  file may already exists from failed transaction. */
  SVN_ERR(svn_io_file_open(&revprop_file, path,
                           APR_WRITE | APR_CREATE | APR_TRUNCATE
                           | APR_BUFFERED, APR_OS_DEFAULT, pool));

  stream = svn_stream_from_aprfile2(revprop_file, TRUE, pool);
  SVN_ERR(svn_hash_write2(txnprops, stream, SVN_HASH_TERMINATOR, pool));
  SVN_ERR(svn_stream_close(stream));

  if (flush_to_disk)
    SVN_ERR(svn_io_file_flush_to_disk(revprop_file, pool));
  SVN_ERR(svn_io_file_close(revprop_file, pool));

  SVN_ERR(svn_io_copy_perms(perms_reference, path, pool));

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_fs__add_index_data(svn_fs_t *fs,
                          apr_file_t *file,
                          const char *l2p_proto_index,
                          const char *p2l_proto_index,
                          svn_revnum_t revision,
                          apr_pool_t *pool)
{
  apr_off_t l2p_offset;
  apr_off_t p2l_offset;
  svn_stringbuf_t *footer;
  unsigned char footer_length;
  svn_checksum_t *l2p_checksum;
  svn_checksum_t *p2l_checksum;

  /* Append the actual index data to the pack file. */
  l2p_offset = 0;
  SVN_ERR(svn_io_file_seek(file, APR_END, &l2p_offset, pool));
  SVN_ERR(svn_fs_fs__l2p_index_append(&l2p_checksum, fs, file,
                                      l2p_proto_index, revision,
                                      pool, pool));

  p2l_offset = 0;
  SVN_ERR(svn_io_file_seek(file, APR_END, &p2l_offset, pool));
  SVN_ERR(svn_fs_fs__p2l_index_append(&p2l_checksum, fs, file,
                                      p2l_proto_index, revision,
                                      pool, pool));

  /* Append footer. */
  footer = svn_fs_fs__unparse_footer(l2p_offset, l2p_checksum,
                                     p2l_offset, p2l_checksum, pool, pool);
  SVN_ERR(svn_io_file_write_full(file, footer->data, footer->len, NULL,
                                 pool));

  footer_length = footer->len;
  SVN_ERR_ASSERT(footer_length == footer->len);
  SVN_ERR(svn_io_file_write_full(file, &footer_length, 1, NULL, pool));

  return SVN_NO_ERROR;
}

/* Mark the directories cached in FS with the keys from DIRECTORY_IDS
 * as "valid" now.  Use SCRATCH_POOL for temporaries. */
static svn_error_t *
promote_cached_directories(svn_fs_t *fs,
                           apr_array_header_t *directory_ids,
                           apr_pool_t *scratch_pool)
{
  fs_fs_data_t *ffd = fs->fsap_data;
  apr_pool_t *iterpool;
  int i;

  if (!ffd->dir_cache)
    return SVN_NO_ERROR;

  iterpool = svn_pool_create(scratch_pool);
  for (i = 0; i < directory_ids->nelts; ++i)
    {
      const pair_cache_key_t *key
        = &APR_ARRAY_IDX(directory_ids, i, pair_cache_key_t);

      svn_pool_clear(iterpool);

      /* Currently, the entry for KEY - if it still exists - is marked
       * as "stale" and would not be used.  Mark it as current for in-
       * revison data. */
      SVN_ERR(svn_cache__set_partial(ffd->dir_cache, key,
                                     svn_fs_fs__reset_txn_filesize, NULL,
                                     iterpool));
    }

  svn_pool_destroy(iterpool);

  return SVN_NO_ERROR;
}

/* Baton used for commit_body below. */
struct commit_baton {
  svn_revnum_t *new_rev_p;
  svn_fs_t *fs;
  svn_fs_txn_t *txn;
  apr_array_header_t *reps_to_cache;
  apr_hash_t *reps_hash;
  apr_pool_t *reps_pool;
};

/* The work-horse for svn_fs_fs__commit, called with the FS write lock.
   This implements the svn_fs_fs__with_write_lock() 'body' callback
   type.  BATON is a 'struct commit_baton *'. */
static svn_error_t *
commit_body(void *baton, apr_pool_t *pool)
{
  struct commit_baton *cb = baton;
  fs_fs_data_t *ffd = cb->fs->fsap_data;
  const char *old_rev_filename, *rev_filename, *proto_filename;
  const char *revprop_filename;
  const svn_fs_id_t *root_id, *new_root_id;
  apr_uint64_t start_node_id;
  apr_uint64_t start_copy_id;
  svn_revnum_t old_rev, new_rev;
  apr_file_t *proto_file;
  void *proto_file_lockcookie;
  apr_off_t initial_offset, changed_path_offset;
  const svn_fs_fs__id_part_t *txn_id = svn_fs_fs__txn_get_id(cb->txn);
  apr_hash_t *changed_paths;
  apr_array_header_t *directory_ids = apr_array_make(pool, 4,
                                                     sizeof(pair_cache_key_t));

  /* Re-Read the current repository format.  All our repo upgrade and
     config evaluation strategies are such that existing information in
     FS and FFD remains valid.

     Although we don't recommend upgrading hot repositories, people may
     still do it and we must make sure to either handle them gracefully
     or to error out.

     Committing pre-format 3 txns will fail after upgrade to format 3+
     because the proto-rev cannot be found; no further action needed.
     Upgrades from pre-f7 to f7+ means a potential change in addressing
     mode for the final rev.  We must be sure to detect that cause because
     the failure would only manifest once the new revision got committed.
   */
  SVN_ERR(svn_fs_fs__read_format_file(cb->fs, pool));

  /* Read the current youngest revision and, possibly, the next available
     node id and copy id (for old format filesystems).  Update the cached
     value for the youngest revision, because we have just checked it. */
  SVN_ERR(svn_fs_fs__read_current(&old_rev, &start_node_id, &start_copy_id,
                                  cb->fs, pool));
  ffd->youngest_rev_cache = old_rev;

  /* Check to make sure this transaction is based off the most recent
     revision. */
  if (cb->txn->base_rev != old_rev)
    return svn_error_create(SVN_ERR_FS_TXN_OUT_OF_DATE, NULL,
                            _("Transaction out of date"));

  /* We need the changes list for verification as well as for writing it
     to the final rev file. */
  SVN_ERR(svn_fs_fs__txn_changes_fetch(&changed_paths, cb->fs, txn_id,
                                       pool));

  /* Locks may have been added (or stolen) between the calling of
     previous svn_fs.h functions and svn_fs_commit_txn(), so we need
     to re-examine every changed-path in the txn and re-verify all
     discovered locks. */
  SVN_ERR(verify_locks(cb->fs, txn_id, changed_paths, pool));

  /* We are going to be one better than this puny old revision. */
  new_rev = old_rev + 1;

  /* Get a write handle on the proto revision file. */
  SVN_ERR(get_writable_proto_rev(&proto_file, &proto_file_lockcookie,
                                 cb->fs, txn_id, pool));
  SVN_ERR(svn_io_file_get_offset(&initial_offset, proto_file, pool));

  /* Write out all the node-revisions and directory contents. */
  root_id = svn_fs_fs__id_txn_create_root(txn_id, pool);
  SVN_ERR(write_final_rev(&new_root_id, proto_file, new_rev, cb->fs, root_id,
                          start_node_id, start_copy_id, initial_offset,
                          directory_ids, cb->reps_to_cache, cb->reps_hash,
                          cb->reps_pool, TRUE, pool));

  /* Write the changed-path information. */
  SVN_ERR(write_final_changed_path_info(&changed_path_offset, proto_file,
                                        cb->fs, txn_id, changed_paths,
                                        pool));

  if (svn_fs_fs__use_log_addressing(cb->fs))
    {
      /* Append the index data to the rev file. */
      SVN_ERR(svn_fs_fs__add_index_data(cb->fs, proto_file,
                      svn_fs_fs__path_l2p_proto_index(cb->fs, txn_id, pool),
                      svn_fs_fs__path_p2l_proto_index(cb->fs, txn_id, pool),
                      new_rev, pool));
    }
  else
    {
      /* Write the final line. */

      svn_stringbuf_t *trailer
        = svn_fs_fs__unparse_revision_trailer
                  ((apr_off_t)svn_fs_fs__id_item(new_root_id),
                   changed_path_offset,
                   pool);
      SVN_ERR(svn_io_file_write_full(proto_file, trailer->data, trailer->len,
                                     NULL, pool));
    }

  if (ffd->flush_to_disk)
    SVN_ERR(svn_io_file_flush_to_disk(proto_file, pool));
  SVN_ERR(svn_io_file_close(proto_file, pool));

  /* We don't unlock the prototype revision file immediately to avoid a
     race with another caller writing to the prototype revision file
     before we commit it. */

  /* Create the shard for the rev and revprop file, if we're sharding and
     this is the first revision of a new shard.  We don't care if this
     fails because the shard already existed for some reason. */
  if (ffd->max_files_per_dir && new_rev % ffd->max_files_per_dir == 0)
    {
      /* Create the revs shard. */
        {
          const char *new_dir
            = svn_fs_fs__path_rev_shard(cb->fs, new_rev, pool);
          svn_error_t *err
            = svn_io_dir_make(new_dir, APR_OS_DEFAULT, pool);
          if (err && !APR_STATUS_IS_EEXIST(err->apr_err))
            return svn_error_trace(err);
          svn_error_clear(err);
          SVN_ERR(svn_io_copy_perms(svn_dirent_join(cb->fs->path,
                                                    PATH_REVS_DIR,
                                                    pool),
                                    new_dir, pool));
        }

      /* Create the revprops shard. */
      SVN_ERR_ASSERT(! svn_fs_fs__is_packed_revprop(cb->fs, new_rev));
        {
          const char *new_dir
            = svn_fs_fs__path_revprops_shard(cb->fs, new_rev, pool);
          svn_error_t *err
            = svn_io_dir_make(new_dir, APR_OS_DEFAULT, pool);
          if (err && !APR_STATUS_IS_EEXIST(err->apr_err))
            return svn_error_trace(err);
          svn_error_clear(err);
          SVN_ERR(svn_io_copy_perms(svn_dirent_join(cb->fs->path,
                                                    PATH_REVPROPS_DIR,
                                                    pool),
                                    new_dir, pool));
        }
    }

  /* Move the finished rev file into place.

     ### This "breaks" the transaction by removing the protorev file
     ### but the revision is not yet complete.  If this commit does
     ### not complete for any reason the transaction will be lost. */
  old_rev_filename = svn_fs_fs__path_rev_absolute(cb->fs, old_rev, pool);
  rev_filename = svn_fs_fs__path_rev(cb->fs, new_rev, pool);
  proto_filename = svn_fs_fs__path_txn_proto_rev(cb->fs, txn_id, pool);
  SVN_ERR(svn_fs_fs__move_into_place(proto_filename, rev_filename,
                                     old_rev_filename, ffd->flush_to_disk,
                                     pool));

  /* Now that we've moved the prototype revision file out of the way,
     we can unlock it (since further attempts to write to the file
     will fail as it no longer exists).  We must do this so that we can
     remove the transaction directory later. */
  SVN_ERR(unlock_proto_rev(cb->fs, txn_id, proto_file_lockcookie, pool));

  /* Write final revprops file. */
  SVN_ERR_ASSERT(! svn_fs_fs__is_packed_revprop(cb->fs, new_rev));
  revprop_filename = svn_fs_fs__path_revprops(cb->fs, new_rev, pool);
  SVN_ERR(write_final_revprop(revprop_filename, old_rev_filename,
                              cb->txn, ffd->flush_to_disk, pool));

  /* Run paranoia checks. */
  if (ffd->verify_before_commit)
    {
      SVN_ERR(verify_before_commit(cb->fs, new_rev, pool));
    }

  /* Update the 'current' file. */
  SVN_ERR(write_final_current(cb->fs, txn_id, new_rev, start_node_id,
                              start_copy_id, pool));

  /* At this point the new revision is committed and globally visible
     so let the caller know it succeeded by giving it the new revision
     number, which fulfills svn_fs_commit_txn() contract.  Any errors
     after this point do not change the fact that a new revision was
     created. */
  *cb->new_rev_p = new_rev;

  ffd->youngest_rev_cache = new_rev;

  /* Make the directory contents alreday cached for the new revision
   * visible. */
  SVN_ERR(promote_cached_directories(cb->fs, directory_ids, pool));

  /* Remove this transaction directory. */
  SVN_ERR(svn_fs_fs__purge_txn(cb->fs, cb->txn->id, pool));

  return SVN_NO_ERROR;
}

/* Add the representations in REPS_TO_CACHE (an array of representation_t *)
 * to the rep-cache database of FS. */
static svn_error_t *
write_reps_to_cache(svn_fs_t *fs,
                    const apr_array_header_t *reps_to_cache,
                    apr_pool_t *scratch_pool)
{
  int i;

  for (i = 0; i < reps_to_cache->nelts; i++)
    {
      representation_t *rep = APR_ARRAY_IDX(reps_to_cache, i, representation_t *);

      SVN_ERR(svn_fs_fs__set_rep_reference(fs, rep, scratch_pool));
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_fs__commit(svn_revnum_t *new_rev_p,
                  svn_fs_t *fs,
                  svn_fs_txn_t *txn,
                  apr_pool_t *pool)
{
  struct commit_baton cb;
  fs_fs_data_t *ffd = fs->fsap_data;

  cb.new_rev_p = new_rev_p;
  cb.fs = fs;
  cb.txn = txn;

  if (ffd->rep_sharing_allowed)
    {
      cb.reps_to_cache = apr_array_make(pool, 5, sizeof(representation_t *));
      cb.reps_hash = apr_hash_make(pool);
      cb.reps_pool = pool;
    }
  else
    {
      cb.reps_to_cache = NULL;
      cb.reps_hash = NULL;
      cb.reps_pool = NULL;
    }

  SVN_ERR(svn_fs_fs__with_write_lock(fs, commit_body, &cb, pool));

  /* At this point, *NEW_REV_P has been set, so errors below won't affect
     the success of the commit.  (See svn_fs_commit_txn().)  */

  if (ffd->rep_sharing_allowed)
    {
      svn_error_t *err;

      SVN_ERR(svn_fs_fs__open_rep_cache(fs, pool));

      /* Write new entries to the rep-sharing database.
       *
       * We use an sqlite transaction to speed things up;
       * see <http://www.sqlite.org/faq.html#q19>.
       */
      /* ### A commit that touches thousands of files will starve other
             (reader/writer) commits for the duration of the below call.
             Maybe write in batches? */
      SVN_ERR(svn_sqlite__begin_transaction(ffd->rep_cache_db));
      err = write_reps_to_cache(fs, cb.reps_to_cache, pool);
      err = svn_sqlite__finish_transaction(ffd->rep_cache_db, err);

      if (svn_error_find_cause(err, SVN_ERR_SQLITE_ROLLBACK_FAILED))
        {
          /* Failed rollback means that our db connection is unusable, and
             the only thing we can do is close it.  The connection will be
             reopened during the next operation with rep-cache.db. */
          return svn_error_trace(
              svn_error_compose_create(err,
                                       svn_fs_fs__close_rep_cache(fs)));
        }
      else if (err)
        return svn_error_trace(err);
    }

  return SVN_NO_ERROR;
}


svn_error_t *
svn_fs_fs__list_transactions(apr_array_header_t **names_p,
                             svn_fs_t *fs,
                             apr_pool_t *pool)
{
  const char *txn_dir;
  apr_hash_t *dirents;
  apr_hash_index_t *hi;
  apr_array_header_t *names;
  apr_size_t ext_len = strlen(PATH_EXT_TXN);

  names = apr_array_make(pool, 1, sizeof(const char *));

  /* Get the transactions directory. */
  txn_dir = svn_fs_fs__path_txns_dir(fs, pool);

  /* Now find a listing of this directory. */
  SVN_ERR(svn_io_get_dirents3(&dirents, txn_dir, TRUE, pool, pool));

  /* Loop through all the entries and return anything that ends with '.txn'. */
  for (hi = apr_hash_first(pool, dirents); hi; hi = apr_hash_next(hi))
    {
      const char *name = apr_hash_this_key(hi);
      apr_ssize_t klen = apr_hash_this_key_len(hi);
      const char *id;

      /* The name must end with ".txn" to be considered a transaction. */
      if ((apr_size_t) klen <= ext_len
          || (strcmp(name + klen - ext_len, PATH_EXT_TXN)) != 0)
        continue;

      /* Truncate the ".txn" extension and store the ID. */
      id = apr_pstrndup(pool, name, strlen(name) - ext_len);
      APR_ARRAY_PUSH(names, const char *) = id;
    }

  *names_p = names;

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_fs__open_txn(svn_fs_txn_t **txn_p,
                    svn_fs_t *fs,
                    const char *name,
                    apr_pool_t *pool)
{
  svn_fs_txn_t *txn;
  fs_txn_data_t *ftd;
  svn_node_kind_t kind;
  transaction_t *local_txn;
  svn_fs_fs__id_part_t txn_id;

  SVN_ERR(svn_fs_fs__id_txn_parse(&txn_id, name));

  /* First check to see if the directory exists. */
  SVN_ERR(svn_io_check_path(svn_fs_fs__path_txn_dir(fs, &txn_id, pool),
                            &kind, pool));

  /* Did we find it? */
  if (kind != svn_node_dir)
    return svn_error_createf(SVN_ERR_FS_NO_SUCH_TRANSACTION, NULL,
                             _("No such transaction '%s'"),
                             name);

  txn = apr_pcalloc(pool, sizeof(*txn));
  ftd = apr_pcalloc(pool, sizeof(*ftd));
  ftd->txn_id = txn_id;

  /* Read in the root node of this transaction. */
  txn->id = apr_pstrdup(pool, name);
  txn->fs = fs;

  SVN_ERR(svn_fs_fs__get_txn(&local_txn, fs, &txn_id, pool));

  txn->base_rev = svn_fs_fs__id_rev(local_txn->base_id);

  txn->vtable = &txn_vtable;
  txn->fsap_data = ftd;
  *txn_p = txn;

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_fs__txn_proplist(apr_hash_t **table_p,
                        svn_fs_txn_t *txn,
                        apr_pool_t *pool)
{
  apr_hash_t *proplist = apr_hash_make(pool);
  SVN_ERR(get_txn_proplist(proplist, txn->fs, svn_fs_fs__txn_get_id(txn),
                           pool));
  *table_p = proplist;

  return SVN_NO_ERROR;
}


svn_error_t *
svn_fs_fs__delete_node_revision(svn_fs_t *fs,
                                const svn_fs_id_t *id,
                                apr_pool_t *pool)
{
  node_revision_t *noderev;

  SVN_ERR(svn_fs_fs__get_node_revision(&noderev, fs, id, pool, pool));

  /* Delete any mutable property representation. */
  if (noderev->prop_rep && is_txn_rep(noderev->prop_rep))
    SVN_ERR(svn_io_remove_file2(svn_fs_fs__path_txn_node_props(fs, id, pool),
                                FALSE, pool));

  /* Delete any mutable data representation. */
  if (noderev->data_rep && is_txn_rep(noderev->data_rep)
      && noderev->kind == svn_node_dir)
    {
      fs_fs_data_t *ffd = fs->fsap_data;
      SVN_ERR(svn_io_remove_file2(svn_fs_fs__path_txn_node_children(fs, id,
                                                                    pool),
                                  FALSE, pool));

      /* remove the corresponding entry from the cache, if such exists */
      if (ffd->txn_dir_cache)
        {
          const char *key = svn_fs_fs__id_unparse(id, pool)->data;
          SVN_ERR(svn_cache__set(ffd->txn_dir_cache, key, NULL, pool));
        }
    }

  return svn_io_remove_file2(svn_fs_fs__path_txn_node_rev(fs, id, pool),
                             FALSE, pool);
}



/*** Transactions ***/

svn_error_t *
svn_fs_fs__get_txn_ids(const svn_fs_id_t **root_id_p,
                       const svn_fs_id_t **base_root_id_p,
                       svn_fs_t *fs,
                       const svn_fs_fs__id_part_t *txn_id,
                       apr_pool_t *pool)
{
  transaction_t *txn;
  SVN_ERR(svn_fs_fs__get_txn(&txn, fs, txn_id, pool));
  *root_id_p = txn->root_id;
  *base_root_id_p = txn->base_id;
  return SVN_NO_ERROR;
}


/* Generic transaction operations.  */

svn_error_t *
svn_fs_fs__txn_prop(svn_string_t **value_p,
                    svn_fs_txn_t *txn,
                    const char *propname,
                    apr_pool_t *pool)
{
  apr_hash_t *table;
  svn_fs_t *fs = txn->fs;

  SVN_ERR(svn_fs__check_fs(fs, TRUE));
  SVN_ERR(svn_fs_fs__txn_proplist(&table, txn, pool));

  *value_p = svn_hash_gets(table, propname);

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_fs__begin_txn(svn_fs_txn_t **txn_p,
                     svn_fs_t *fs,
                     svn_revnum_t rev,
                     apr_uint32_t flags,
                     apr_pool_t *pool)
{
  svn_string_t date;
  fs_txn_data_t *ftd;
  apr_hash_t *props = apr_hash_make(pool);

  SVN_ERR(svn_fs__check_fs(fs, TRUE));

  SVN_ERR(svn_fs_fs__create_txn(txn_p, fs, rev, pool));

  /* Put a datestamp on the newly created txn, so we always know
     exactly how old it is.  (This will help sysadmins identify
     long-abandoned txns that may need to be manually removed.)  When
     a txn is promoted to a revision, this property will be
     automatically overwritten with a revision datestamp. */
  date.data = svn_time_to_cstring(apr_time_now(), pool);
  date.len = strlen(date.data);

  svn_hash_sets(props, SVN_PROP_REVISION_DATE, &date);

  /* Set temporary txn props that represent the requested 'flags'
     behaviors. */
  if (flags & SVN_FS_TXN_CHECK_OOD)
    svn_hash_sets(props, SVN_FS__PROP_TXN_CHECK_OOD,
                  svn_string_create("true", pool));

  if (flags & SVN_FS_TXN_CHECK_LOCKS)
    svn_hash_sets(props, SVN_FS__PROP_TXN_CHECK_LOCKS,
                  svn_string_create("true", pool));

  if (flags & SVN_FS_TXN_CLIENT_DATE)
    svn_hash_sets(props, SVN_FS__PROP_TXN_CLIENT_DATE,
                  svn_string_create("0", pool));

  ftd = (*txn_p)->fsap_data;
  return svn_error_trace(set_txn_proplist(fs, &ftd->txn_id, props, pool));
}
