[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

RE: svn commit: r1694502 [1/6] - in /subversion/trunk: ./ notes/subversion/include/private/ subversion/libsvn_fs_x/ subversion/libsvn_subr/subversion/tests/cmdline/ subversion/tests/libsvn_fs/subversion/tests/libsvn_fs_x/

From: <bert_at_qqmail.nl>
Date: Fri, 7 Aug 2015 02:25:25 +0200

[And now to the proper list]

On the buildbots I see
[[[
..\..\..\subversion\tests\libsvn_fs_x\fs-x-pack-test.c:873,
..\..\..\subversion\libsvn_fs_x\batch_fsync.c:386,
..\..\..\subversion\libsvn_fs_x\batch_fsync.c:343,
..\..\..\subversion\libsvn_subr\io.c:3515: (apr_err=720005)
svn_tests: E720005: Can't open file 'E:\svn-local\tests\subversion\tests\libsvn_fs_x': Access is denied. 
FAIL:  fs-x-pack-test 13: test batch fsync
]]]
after this commit

It looks like the batch fsync introduced in this patch is trying to open a directory as a file?

That is not going to work on Windows, and probably on more platforms. Opening a directory requires other functions.

Note that this code is called inside a 'SVN_ON_POSIX' block, which I would assume shouldn't be active on Windows.

Last time we discussed batch syncing you told me/us, that you would use the original handles to perform the flush... This code appears to tell a different story?

Reopening files may, and commonly will cause a huge performance hit on Windows... because virusscanners are designed to delay those operations, until they are sure the file doesn’t contain a virus; especially if the file was just written.

              Bert

From: stefan2_at_apache.org
Sent: donderdag 6 augustus 2015 16:04
To: commits_at_subversion.apache.org
Subject: svn commit: r1694502 [1/6] - in /subversion/trunk: ./ notes/subversion/include/private/ subversion/libsvn_fs_x/ subversion/libsvn_subr/subversion/tests/cmdline/ subversion/tests/libsvn_fs/subversion/tests/libsvn_fs_x/

Author: stefan2
Date: Thu Aug 6 14:04:55 2015
New Revision: 1694502

URL: http://svn.apache.org/r1694502
Log:
Merge the fsx-1.10 development branch to trunk and remove the
BRANCH-README file. There were no conflicts.

Changes brings the latest FSX changes to /trunk.

Added:
    subversion/trunk/subversion/libsvn_fs_x/batch_fsync.c
      - copied unchanged from r1694500, subversion/branches/fsx-1.10/subversion/libsvn_fs_x/batch_fsync.c
    subversion/trunk/subversion/libsvn_fs_x/batch_fsync.h
      - copied unchanged from r1694500, subversion/branches/fsx-1.10/subversion/libsvn_fs_x/batch_fsync.h
    subversion/trunk/subversion/libsvn_fs_x/dag_cache.c
      - copied unchanged from r1694500, subversion/branches/fsx-1.10/subversion/libsvn_fs_x/dag_cache.c
    subversion/trunk/subversion/libsvn_fs_x/dag_cache.h
      - copied unchanged from r1694500, subversion/branches/fsx-1.10/subversion/libsvn_fs_x/dag_cache.h
Modified:
    subversion/trunk/ (props changed)
    subversion/trunk/notes/ (props changed)
    subversion/trunk/subversion/include/private/svn_mutex.h
    subversion/trunk/subversion/libsvn_fs_x/ (props changed)
    subversion/trunk/subversion/libsvn_fs_x/cached_data.c
    subversion/trunk/subversion/libsvn_fs_x/cached_data.h
    subversion/trunk/subversion/libsvn_fs_x/caching.c
    subversion/trunk/subversion/libsvn_fs_x/changes.c
    subversion/trunk/subversion/libsvn_fs_x/changes.h
    subversion/trunk/subversion/libsvn_fs_x/dag.c
    subversion/trunk/subversion/libsvn_fs_x/dag.h
    subversion/trunk/subversion/libsvn_fs_x/fs.c
    subversion/trunk/subversion/libsvn_fs_x/fs.h
    subversion/trunk/subversion/libsvn_fs_x/fs_x.c
    subversion/trunk/subversion/libsvn_fs_x/fs_x.h
    subversion/trunk/subversion/libsvn_fs_x/hotcopy.c
    subversion/trunk/subversion/libsvn_fs_x/hotcopy.h
    subversion/trunk/subversion/libsvn_fs_x/index.c
    subversion/trunk/subversion/libsvn_fs_x/index.h
    subversion/trunk/subversion/libsvn_fs_x/lock.c
    subversion/trunk/subversion/libsvn_fs_x/lock.h
    subversion/trunk/subversion/libsvn_fs_x/low_level.c
    subversion/trunk/subversion/libsvn_fs_x/low_level.h
    subversion/trunk/subversion/libsvn_fs_x/noderevs.c
    subversion/trunk/subversion/libsvn_fs_x/noderevs.h
    subversion/trunk/subversion/libsvn_fs_x/pack.c
    subversion/trunk/subversion/libsvn_fs_x/pack.h
    subversion/trunk/subversion/libsvn_fs_x/recovery.c
    subversion/trunk/subversion/libsvn_fs_x/recovery.h
    subversion/trunk/subversion/libsvn_fs_x/reps.c
    subversion/trunk/subversion/libsvn_fs_x/reps.h
    subversion/trunk/subversion/libsvn_fs_x/rev_file.c
    subversion/trunk/subversion/libsvn_fs_x/rev_file.h
    subversion/trunk/subversion/libsvn_fs_x/revprops.c
    subversion/trunk/subversion/libsvn_fs_x/revprops.h
    subversion/trunk/subversion/libsvn_fs_x/string_table.c
    subversion/trunk/subversion/libsvn_fs_x/string_table.h
    subversion/trunk/subversion/libsvn_fs_x/temp_serializer.c
    subversion/trunk/subversion/libsvn_fs_x/temp_serializer.h
    subversion/trunk/subversion/libsvn_fs_x/transaction.c
    subversion/trunk/subversion/libsvn_fs_x/transaction.h
    subversion/trunk/subversion/libsvn_fs_x/tree.c
    subversion/trunk/subversion/libsvn_fs_x/tree.h
    subversion/trunk/subversion/libsvn_fs_x/util.c
    subversion/trunk/subversion/libsvn_fs_x/util.h
    subversion/trunk/subversion/libsvn_fs_x/verify.c
    subversion/trunk/subversion/libsvn_fs_x/verify.h
    subversion/trunk/subversion/libsvn_subr/mutex.c
    subversion/trunk/subversion/tests/cmdline/svnadmin_tests.py
    subversion/trunk/subversion/tests/libsvn_fs/fs-test.c
    subversion/trunk/subversion/tests/libsvn_fs_x/ (props changed)
    subversion/trunk/subversion/tests/libsvn_fs_x/fs-x-pack-test.c

Propchange: subversion/trunk/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Aug 6 14:04:55 2015
@@ -23,6 +23,7 @@
 /subversion/branches/fsfs-lock-many:1571740-1577217
 /subversion/branches/fsfs-pack:873717-874575
 /subversion/branches/fsx:1507845-1509914
+/subversion/branches/fsx-1.10:1658219-1694500
 /subversion/branches/fsx-id:1645603-1649011
 /subversion/branches/gnome-keyring:870558-871410
 /subversion/branches/gpg-agent-password-store:1005036-1150766

Propchange: subversion/trunk/notes/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Aug 6 14:04:55 2015
@@ -9,6 +9,7 @@
 /subversion/branches/fs-rep-sharing/notes:869036-873803
 /subversion/branches/fsfs-lock-many/notes:1571740-1577217
 /subversion/branches/fsfs-pack/notes:873717-874575
+/subversion/branches/fsx-1.10/notes:1658219-1694500
 /subversion/branches/gnome-keyring/notes:870558-871410
 /subversion/branches/http-protocol-v2/notes:874395-876041
 /subversion/branches/in-memory-cache/notes:869829-871452

Modified: subversion/trunk/subversion/include/private/svn_mutex.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_mutex.h?rev=1694502&r1=1694501&r2=1694502&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_mutex.h (original)
+++ subversion/trunk/subversion/include/private/svn_mutex.h Thu Aug 6 14:04:55 2015
@@ -104,6 +104,17 @@ do {
   SVN_ERR(svn_mutex__unlock(svn_mutex__m, (expr))); \
 } while (0)
 
+#if APR_HAS_THREADS
+
+/** Return the APR mutex encapsulated in @a mutex.
+ *
+ * @note This function should only be called by APR wrapper code.
+ */
+apr_thread_mutex_t *
+svn_mutex__get(svn_mutex__t *mutex);
+
+#endif
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Propchange: subversion/trunk/subversion/libsvn_fs_x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Aug 6 14:04:55 2015
@@ -22,6 +22,7 @@
 /subversion/branches/fsfs-lock-many/subversion/libsvn_fs_x:1571740-1577217
 /subversion/branches/fsfs-pack/subversion/libsvn_fs_x:873717-874575
 /subversion/branches/fsx/subversion/libsvn_fs_x:1507845-1508040
+/subversion/branches/fsx-1.10/subversion/libsvn_fs_x:1658219-1694500
 /subversion/branches/fsx-id/subversion/libsvn_fs_x:1645603-1649011
 /subversion/branches/gnome-keyring/subversion/libsvn_fs_x:870558-871410
 /subversion/branches/gpg-agent-password-store/subversion/libsvn_fs_x:1005036-1150766

Modified: subversion/trunk/subversion/libsvn_fs_x/cached_data.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/cached_data.c?rev=1694502&r1=1694501&r2=1694502&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/cached_data.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/cached_data.c Thu Aug 6 14:04:55 2015
@@ -173,21 +173,6 @@ dgb__log_access(svn_fs_t *fs,
   return SVN_NO_ERROR;
 }
 
-/* Convenience wrapper around svn_io_file_aligned_seek, taking filesystem
- FS instead of a block size. */
-static svn_error_t *
-aligned_seek(svn_fs_t *fs,
- apr_file_t *file,
- apr_off_t *buffer_start,
- apr_off_t offset,
- apr_pool_t *scratch_pool)
-{
- svn_fs_x__data_t *ffd = fs->fsap_data;
- return svn_error_trace(svn_io_file_aligned_seek(file, ffd->block_size,
- buffer_start, offset,
- scratch_pool));
-}
-
 /* Open the revision file for the item given by ID in filesystem FS and
    store the newly opened file in FILE. Seek to the item's location before
    returning.
@@ -207,11 +192,10 @@ open_and_seek_revision(svn_fs_x__revisio
 
   SVN_ERR(svn_fs_x__ensure_revision_exists(rev, fs, scratch_pool));
 
- SVN_ERR(svn_fs_x__open_pack_or_rev_file(&rev_file, fs, rev, result_pool,
- scratch_pool));
+ SVN_ERR(svn_fs_x__rev_file_init(&rev_file, fs, rev, result_pool));
   SVN_ERR(svn_fs_x__item_offset(&offset, &sub_item, fs, rev_file, id,
                                 scratch_pool));
- SVN_ERR(aligned_seek(fs, rev_file->file, NULL, offset, scratch_pool));
+ SVN_ERR(svn_fs_x__rev_file_seek(rev_file, NULL, offset));
 
   *file = rev_file;
 
@@ -233,12 +217,12 @@ open_and_seek_transaction(svn_fs_x__revi
   apr_uint32_t sub_item = 0;
   apr_int64_t txn_id = svn_fs_x__get_txn_id(rep->id.change_set);
 
- SVN_ERR(svn_fs_x__open_proto_rev_file(file, fs, txn_id, result_pool,
- scratch_pool));
+ SVN_ERR(svn_fs_x__rev_file_open_proto_rev(file, fs, txn_id, result_pool,
+ scratch_pool));
 
   SVN_ERR(svn_fs_x__item_offset(&offset, &sub_item, fs, *file, &rep->id,
                                 scratch_pool));
- SVN_ERR(aligned_seek(fs, (*file)->file, NULL, offset, scratch_pool));
+ SVN_ERR(svn_fs_x__rev_file_seek(*file, NULL, offset));
 
   return SVN_NO_ERROR;
 }
@@ -294,6 +278,7 @@ get_node_revision_body(svn_fs_x__noderev
   if (svn_fs_x__is_txn(id->change_set))
     {
       apr_file_t *file;
+ svn_stream_t *stream;
 
       /* This is a transaction node-rev. Its storage logic is very
          different from that of rev / pack files. */
@@ -314,10 +299,9 @@ get_node_revision_body(svn_fs_x__noderev
           return svn_error_trace(err);
         }
 
- SVN_ERR(svn_fs_x__read_noderev(noderev_p,
- svn_stream_from_aprfile2(file,
- FALSE,
- scratch_pool),
+ /* Be sure to close the file ASAP. */
+ stream = svn_stream_from_aprfile2(file, FALSE, scratch_pool);
+ SVN_ERR(svn_fs_x__read_noderev(noderev_p, stream,
                                      result_pool, scratch_pool));
     }
   else
@@ -328,8 +312,8 @@ get_node_revision_body(svn_fs_x__noderev
       svn_revnum_t revision = svn_fs_x__get_revnum(id->change_set);
       svn_fs_x__pair_cache_key_t key;
 
- SVN_ERR(svn_fs_x__open_pack_or_rev_file(&revision_file, fs, revision,
- scratch_pool, scratch_pool));
+ SVN_ERR(svn_fs_x__rev_file_init(&revision_file, fs, revision,
+ scratch_pool));
 
       /* First, try a noderevs container cache lookup. */
       if ( svn_fs_x__is_packed_rev(fs, revision)
@@ -420,8 +404,8 @@ svn_fs_x__get_mergeinfo_count(apr_int64_
       svn_revnum_t revision = svn_fs_x__get_revnum(id->change_set);
 
       svn_fs_x__revision_file_t *rev_file;
- SVN_ERR(svn_fs_x__open_pack_or_rev_file(&rev_file, fs, revision,
- scratch_pool, scratch_pool));
+ SVN_ERR(svn_fs_x__rev_file_init(&rev_file, fs, revision,
+ scratch_pool));
 
       if ( svn_fs_x__is_packed_rev(fs, revision)
           && ffd->noderevs_container_cache)
@@ -502,39 +486,13 @@ typedef struct rep_state_t
   int chunk_index; /* number of the window to read */
 } rep_state_t;
 
-/* Simple wrapper around svn_fs_x__get_file_offset to simplify callers. */
-static svn_error_t *
-get_file_offset(apr_off_t *offset,
- rep_state_t *rs,
- apr_pool_t *scratch_pool)
-{
- return svn_error_trace(svn_fs_x__get_file_offset(offset,
- rs->sfile->rfile->file,
- scratch_pool));
-}
-
-/* Simple wrapper around svn_io_file_aligned_seek to simplify callers. */
-static svn_error_t *
-rs_aligned_seek(rep_state_t *rs,
- apr_off_t *buffer_start,
- apr_off_t offset,
- apr_pool_t *scratch_pool)
-{
- svn_fs_x__data_t *ffd = rs->sfile->fs->fsap_data;
- return svn_error_trace(svn_io_file_aligned_seek(rs->sfile->rfile->file,
- ffd->block_size,
- buffer_start, offset,
- scratch_pool));
-}
-
 /* Open FILE->FILE and FILE->STREAM if they haven't been opened, yet. */
 static svn_error_t*
 auto_open_shared_file(shared_file_t *file)
 {
   if (file->rfile == NULL)
- SVN_ERR(svn_fs_x__open_pack_or_rev_file(&file->rfile, file->fs,
- file->revision, file->pool,
- file->pool));
+ SVN_ERR(svn_fs_x__rev_file_init(&file->rfile, file->fs,
+ file->revision, file->pool));
 
   return SVN_NO_ERROR;
 }
@@ -568,9 +526,8 @@ auto_read_diff_version(rep_state_t *rs,
   if (rs->ver == -1)
     {
       char buf[4];
- SVN_ERR(rs_aligned_seek(rs, NULL, rs->start, scratch_pool));
- SVN_ERR(svn_io_file_read_full2(rs->sfile->rfile->file, buf,
- sizeof(buf), NULL, NULL, scratch_pool));
+ SVN_ERR(svn_fs_x__rev_file_seek(rs->sfile->rfile, NULL, rs->start));
+ SVN_ERR(svn_fs_x__rev_file_read(rs->sfile->rfile, buf, sizeof(buf)));
 
       /* ### Layering violation */
       if (! ((buf[0] == 'S') && (buf[1] == 'V') && (buf[2] == 'N')))
@@ -677,6 +634,8 @@ create_rep_state_body(rep_state_t **rep_
   /* read rep header, if necessary */
   if (!is_cached)
     {
+ svn_stream_t *stream;
+
       /* we will need the on-disk location for non-txn reps */
       apr_off_t offset;
       svn_boolean_t in_container = TRUE;
@@ -728,12 +687,13 @@ create_rep_state_body(rep_state_t **rep_
               return SVN_NO_ERROR;
             }
 
- SVN_ERR(rs_aligned_seek(rs, NULL, offset, scratch_pool));
+ SVN_ERR(svn_fs_x__rev_file_seek(rs->sfile->rfile, NULL, offset));
         }
 
- SVN_ERR(svn_fs_x__read_rep_header(&rh, rs->sfile->rfile->stream,
+ SVN_ERR(svn_fs_x__rev_file_stream(&stream, rs->sfile->rfile));
+ SVN_ERR(svn_fs_x__read_rep_header(&rh, stream,
                                         result_pool, scratch_pool));
- SVN_ERR(get_file_offset(&rs->start, rs, result_pool));
+ SVN_ERR(svn_fs_x__rev_file_offset(&rs->start, rs->sfile->rfile));
 
       /* populate the cache if appropriate */
       if (SVN_IS_VALID_REVNUM(revision))
@@ -816,8 +776,7 @@ svn_fs_x__check_rep(svn_fs_x__representa
   svn_revnum_t revision = svn_fs_x__get_revnum(rep->id.change_set);
 
   svn_fs_x__revision_file_t *rev_file;
- SVN_ERR(svn_fs_x__open_pack_or_rev_file(&rev_file, fs, revision,
- scratch_pool, scratch_pool));
+ SVN_ERR(svn_fs_x__rev_file_init(&rev_file, fs, revision, scratch_pool));
 
   /* Does REP->ID refer to an actual item? Which one is it? */
   SVN_ERR(svn_fs_x__item_offset(&offset, &sub_item, fs, rev_file, &rep->id,
@@ -1326,6 +1285,8 @@ read_delta_window(svn_txdelta_window_t *
   apr_off_t start_offset;
   apr_off_t end_offset;
   apr_pool_t *iterpool;
+ svn_stream_t *stream;
+ svn_fs_x__revision_file_t *file;
 
   SVN_ERR_ASSERT(rs->chunk_index <= this_chunk);
 
@@ -1340,6 +1301,7 @@ read_delta_window(svn_txdelta_window_t *
 
   /* someone has to actually read the data from file. Open it */
   SVN_ERR(auto_open_shared_file(rs->sfile));
+ file = rs->sfile->rfile;
 
   /* invoke the 'block-read' feature for non-txn data.
      However, don't do that if we are in the middle of some representation,
@@ -1348,8 +1310,8 @@ read_delta_window(svn_txdelta_window_t *
       && svn_fs_x__is_revision(rs->rep_id.change_set)
       && rs->window_cache)
     {
- SVN_ERR(block_read(NULL, rs->sfile->fs, &rs->rep_id,
- rs->sfile->rfile, result_pool, scratch_pool));
+ SVN_ERR(block_read(NULL, rs->sfile->fs, &rs->rep_id, file,
+ result_pool, scratch_pool));
 
       /* reading the whole block probably also provided us with the
          desired txdelta window */
@@ -1367,18 +1329,19 @@ read_delta_window(svn_txdelta_window_t *
   /* RS->FILE may be shared between RS instances -> make sure we point
    * to the right data. */
   start_offset = rs->start + rs->current;
- SVN_ERR(rs_aligned_seek(rs, NULL, start_offset, scratch_pool));
+ SVN_ERR(svn_fs_x__rev_file_seek(file, NULL, start_offset));
 
   /* Skip windows to reach the current chunk if we aren't there yet. */
   iterpool = svn_pool_create(scratch_pool);
   while (rs->chunk_index < this_chunk)
     {
- apr_file_t *file = rs->sfile->rfile->file;
+ apr_file_t *apr_file;
       svn_pool_clear(iterpool);
 
- SVN_ERR(svn_txdelta_skip_svndiff_window(file, rs->ver, iterpool));
+ SVN_ERR(svn_fs_x__rev_file_get(&apr_file, file));
+ SVN_ERR(svn_txdelta_skip_svndiff_window(apr_file, rs->ver, iterpool));
       rs->chunk_index++;
- SVN_ERR(svn_fs_x__get_file_offset(&start_offset, file, iterpool));
+ SVN_ERR(svn_fs_x__get_file_offset(&start_offset, apr_file, iterpool));
 
       rs->current = start_offset - rs->start;
       if (rs->current >= rs->size)
@@ -1390,9 +1353,10 @@ read_delta_window(svn_txdelta_window_t *
   svn_pool_destroy(iterpool);
 
   /* Actually read the next window. */
- SVN_ERR(svn_txdelta_read_svndiff_window(nwin, rs->sfile->rfile->stream,
- rs->ver, result_pool));
- SVN_ERR(get_file_offset(&end_offset, rs, scratch_pool));
+ SVN_ERR(svn_fs_x__rev_file_stream(&stream, file));
+ SVN_ERR(svn_txdelta_read_svndiff_window(nwin, stream, rs->ver,
+ result_pool));
+ SVN_ERR(svn_fs_x__rev_file_offset(&end_offset, file));
   rs->current = end_offset - rs->start;
   if (rs->current > rs->size)
     return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
@@ -1430,6 +1394,7 @@ read_container_window(svn_stringbuf_t **
   /* already in cache? */
   baton.fs = fs;
   baton.idx = rs->sub_item;
+
   SVN_ERR(svn_cache__get_partial((void**)&extractor, &is_cached,
                                  ffd->reps_container_cache, &key,
                                  svn_fs_x__reps_get_func, &baton,
@@ -1648,23 +1613,23 @@ cache_windows(svn_filesize_t *fulltext_l
       else
         {
           svn_txdelta_window_t *window;
+ svn_fs_x__revision_file_t *file = rs->sfile->rfile;
+ svn_stream_t *stream;
           apr_off_t start_offset = rs->start + rs->current;
           apr_off_t end_offset;
           apr_off_t block_start;
 
           /* navigate to & read the current window */
- SVN_ERR(rs_aligned_seek(rs, &block_start, start_offset, iterpool));
- SVN_ERR(svn_txdelta_read_svndiff_window(&window,
- rs->sfile->rfile->stream,
- rs->ver, iterpool));
+ SVN_ERR(svn_fs_x__rev_file_stream(&stream, file));
+ SVN_ERR(svn_fs_x__rev_file_seek(file, &block_start, start_offset));
+ SVN_ERR(svn_txdelta_read_svndiff_window(&window, stream, rs->ver,
+ iterpool));
 
           /* aggregate expanded window size */
           *fulltext_len += window->tview_len;
 
           /* determine on-disk window size */
- SVN_ERR(svn_fs_x__get_file_offset(&end_offset,
- rs->sfile->rfile->file,
- iterpool));
+ SVN_ERR(svn_fs_x__rev_file_offset(&end_offset, rs->sfile->rfile));
           rs->current = end_offset - rs->start;
           if (rs->current > rs->size)
             return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
@@ -1693,11 +1658,12 @@ cache_windows(svn_filesize_t *fulltext_l
 static svn_error_t *
 read_rep_header(svn_fs_x__rep_header_t **rep_header,
                 svn_fs_t *fs,
- svn_stream_t *stream,
+ svn_fs_x__revision_file_t *file,
                 svn_fs_x__representation_cache_key_t *key,
                 apr_pool_t *pool)
 {
   svn_fs_x__data_t *ffd = fs->fsap_data;
+ svn_stream_t *stream;
   svn_boolean_t is_cached = FALSE;
 
   SVN_ERR(svn_cache__get((void**)rep_header, &is_cached,
@@ -1705,6 +1671,7 @@ read_rep_header(svn_fs_x__rep_header_t *
   if (is_cached)
     return SVN_NO_ERROR;
 
+ SVN_ERR(svn_fs_x__rev_file_stream(&stream, file));
   SVN_ERR(svn_fs_x__read_rep_header(rep_header, stream, pool, pool));
   SVN_ERR(svn_cache__set(ffd->rep_header_cache, key, *rep_header, pool));
 
@@ -1732,8 +1699,7 @@ svn_fs_x__get_representation_length(svn_
   key.revision = svn_fs_x__get_revnum(entry->items[0].change_set);
   key.is_packed = svn_fs_x__is_packed_rev(fs, key.revision);
   key.item_index = entry->items[0].number;
- SVN_ERR(read_rep_header(&rep_header, fs, rev_file->stream, &key,
- scratch_pool));
+ SVN_ERR(read_rep_header(&rep_header, fs, rev_file, &key, scratch_pool));
 
   /* prepare representation reader state (rs) structure */
   SVN_ERR(init_rep_state(&rs, rep_header, fs, rev_file, entry,
@@ -2773,8 +2739,7 @@ svn_fs_x__get_changes(apr_array_header_t
   /* Provide revision file. */
 
   SVN_ERR(svn_fs_x__ensure_revision_exists(rev, fs, scratch_pool));
- SVN_ERR(svn_fs_x__open_pack_or_rev_file(&revision_file, fs, rev,
- scratch_pool, scratch_pool));
+ SVN_ERR(svn_fs_x__rev_file_init(&revision_file, fs, rev, scratch_pool));
 
   /* try cache lookup first */
 
@@ -2839,7 +2804,7 @@ block_read_contents(svn_fs_t *fs,
   header_key.is_packed = svn_fs_x__is_packed_rev(fs, header_key.revision);
   header_key.item_index = key->second;
 
- SVN_ERR(read_rep_header(&rep_header, fs, rev_file->stream, &header_key,
+ SVN_ERR(read_rep_header(&rep_header, fs, rev_file, &header_key,
                           scratch_pool));
   SVN_ERR(init_rep_state(&rs, rep_header, fs, rev_file, entry, scratch_pool));
   SVN_ERR(cache_windows(&fulltext_len, fs, &rs, max_offset, scratch_pool));
@@ -2866,8 +2831,7 @@ read_item(svn_stream_t **stream,
   svn_stringbuf_t *text = svn_stringbuf_create_ensure(entry->size, pool);
   text->len = entry->size;
   text->data[text->len] = 0;
- SVN_ERR(svn_io_file_read_full2(rev_file->file, text->data, text->len,
- NULL, NULL, pool));
+ SVN_ERR(svn_fs_x__rev_file_read(rev_file, text->data, text->len));
 
   /* Return (construct, calculate) stream and checksum. */
   *stream = svn_stream_from_stringbuf(text, pool);
@@ -3156,8 +3120,7 @@ block_read(void **result,
   do
     {
       /* fetch list of items in the block surrounding OFFSET */
- SVN_ERR(aligned_seek(fs, revision_file->file, &block_start, offset,
- iterpool));
+ SVN_ERR(svn_fs_x__rev_file_seek(revision_file, &block_start, offset));
       SVN_ERR(svn_fs_x__p2l_index_lookup(&entries, fs, revision_file,
                                          revision, block_start,
                                          ffd->block_size, scratch_pool,
@@ -3196,8 +3159,8 @@ block_read(void **result,
               key.revision = svn_fs_x__get_revnum(entry->items[0].change_set);
               key.second = entry->items[0].number;
 
- SVN_ERR(svn_io_file_seek(revision_file->file, SEEK_SET,
- &entry->offset, iterpool));
+ SVN_ERR(svn_fs_x__rev_file_seek(revision_file, NULL,
+ entry->offset));
               switch (entry->type)
                 {
                   case SVN_FS_X__ITEM_TYPE_FILE_REP:

Modified: subversion/trunk/subversion/libsvn_fs_x/cached_data.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/cached_data.h?rev=1694502&r1=1694501&r2=1694502&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/cached_data.h (original)
+++ subversion/trunk/subversion/libsvn_fs_x/cached_data.h Thu Aug 6 14:04:55 2015
@@ -20,8 +20,8 @@
  * ====================================================================
  */
 
-#ifndef SVN_LIBSVN_FS__CACHED_DATA_H
-#define SVN_LIBSVN_FS__CACHED_DATA_H
+#ifndef SVN_LIBSVN_FS_X_CACHED_DATA_H
+#define SVN_LIBSVN_FS_X_CACHED_DATA_H
 
 #include "svn_pools.h"
 #include "svn_fs.h"

Modified: subversion/trunk/subversion/libsvn_fs_x/caching.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/caching.c?rev=1694502&r1=1694501&r2=1694502&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/caching.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/caching.c Thu Aug 6 14:04:55 2015
@@ -23,8 +23,7 @@
 #include "fs.h"
 #include "fs_x.h"
 #include "id.h"
-#include "dag.h"
-#include "tree.h"
+#include "dag_cache.h"
 #include "index.h"
 #include "changes.h"
 #include "noderevs.h"
@@ -418,22 +417,6 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
                               apr_pool_cleanup_null);
 #endif
 
- /* Rough estimate: revision DAG nodes have size around 320 bytes, so
- * let's put 16 on a page. */
- SVN_ERR(create_cache(&(ffd->rev_node_cache),
- NULL,
- membuffer,
- 1024, 16,
- svn_fs_x__dag_serialize,
- svn_fs_x__dag_deserialize,
- APR_HASH_KEY_STRING,
- apr_pstrcat(scratch_pool, prefix, "DAG", SVN_VA_NULL),
- SVN_CACHE__MEMBUFFER_LOW_PRIORITY,
- has_namespace,
- fs,
- no_handler, FALSE,
- fs->pool, scratch_pool));
-
   /* 1st level DAG node cache */
   ffd->dag_node_cache = svn_fs_x__create_dag_cache(fs->pool);
 
@@ -546,36 +529,6 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
                        has_namespace,
                        fs,
                        no_handler, !cache_fulltexts,
- fs->pool, scratch_pool));
-
- SVN_ERR(create_cache(&(ffd->mergeinfo_cache),
- NULL,
- membuffer,
- 0, 0, /* Do not use inprocess cache */
- svn_fs_x__serialize_mergeinfo,
- svn_fs_x__deserialize_mergeinfo,
- APR_HASH_KEY_STRING,
- apr_pstrcat(scratch_pool, prefix, "MERGEINFO",
- SVN_VA_NULL),
- 0,
- has_namespace,
- fs,
- no_handler, !cache_fulltexts,
- fs->pool, scratch_pool));
-
- SVN_ERR(create_cache(&(ffd->mergeinfo_existence_cache),
- NULL,
- membuffer,
- 0, 0, /* Do not use inprocess cache */
- /* Values are svn_stringbuf_t */
- NULL, NULL,
- APR_HASH_KEY_STRING,
- apr_pstrcat(scratch_pool, prefix, "HAS_MERGEINFO",
- SVN_VA_NULL),
- 0,
- has_namespace,
- fs,
- no_handler, !cache_fulltexts,
                        fs->pool, scratch_pool));
 
   /* if enabled, cache revprops */

Modified: subversion/trunk/subversion/libsvn_fs_x/changes.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/changes.c?rev=1694502&r1=1694501&r2=1694502&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/changes.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/changes.c Thu Aug 6 14:04:55 2015
@@ -222,7 +222,7 @@ svn_error_t *
 svn_fs_x__changes_get_list(apr_array_header_t **list,
                            const svn_fs_x__changes_t *changes,
                            apr_size_t idx,
- apr_pool_t *pool)
+ apr_pool_t *result_pool)
 {
   int first;
   int last;
@@ -235,7 +235,7 @@ svn_fs_x__changes_get_list(apr_array_hea
   /* validate index */
   if (idx + 1 >= (apr_size_t)changes->offsets->nelts)
     return svn_error_createf(SVN_ERR_FS_CONTAINER_INDEX, NULL,
- apr_psprintf(pool,
+ apr_psprintf(result_pool,
                                           _("Changes list index %%%s"
                                             " exceeds container size %%d"),
                                           APR_SIZE_T_FMT),
@@ -246,18 +246,19 @@ svn_fs_x__changes_get_list(apr_array_hea
   last = APR_ARRAY_IDX(changes->offsets, (int)idx + 1, int);
 
   /* construct result */
- *list = apr_array_make(pool, last - first, sizeof(svn_fs_x__change_t*));
+ *list = apr_array_make(result_pool, last - first,
+ sizeof(svn_fs_x__change_t*));
   for (i = first; i < last; ++i)
     {
       const binary_change_t *binary_change
         = &APR_ARRAY_IDX(changes->changes, i, binary_change_t);
 
       /* convert BINARY_CHANGE into a standard FSX svn_fs_x__change_t */
- svn_fs_x__change_t *change = apr_pcalloc(pool, sizeof(*change));
+ svn_fs_x__change_t *change = apr_pcalloc(result_pool, sizeof(*change));
       change->path.data = svn_fs_x__string_table_get(changes->paths,
                                                      binary_change->path,
                                                      &change->path.len,
- pool);
+ result_pool);
 
       if (binary_change->noderev_id.change_set != SVN_FS_X__INVALID_CHANGE_SET)
         change->noderev_id = binary_change->noderev_id;
@@ -276,7 +277,7 @@ svn_fs_x__changes_get_list(apr_array_hea
           = svn_fs_x__string_table_get(changes->paths,
                                         binary_change->copyfrom_path,
                                         NULL,
- pool);
+ result_pool);
 
       /* add it to the result */
       APR_ARRAY_PUSH(*list, svn_fs_x__change_t*) = change;
@@ -437,14 +438,14 @@ svn_error_t *
 svn_fs_x__deserialize_changes_container(void **out,
                                          void *data,
                                          apr_size_t data_len,
- apr_pool_t *pool)
+ apr_pool_t *result_pool)
 {
   svn_fs_x__changes_t *changes = (svn_fs_x__changes_t *)data;
 
   /* de-serialize sub-structures */
   svn_fs_x__deserialize_string_table(changes, &changes->paths);
- svn_fs_x__deserialize_apr_array(changes, &changes->changes, pool);
- svn_fs_x__deserialize_apr_array(changes, &changes->offsets, pool);
+ svn_fs_x__deserialize_apr_array(changes, &changes->changes, result_pool);
+ svn_fs_x__deserialize_apr_array(changes, &changes->offsets, result_pool);
 
   /* done */
   *out = changes;

Modified: subversion/trunk/subversion/libsvn_fs_x/changes.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/changes.h?rev=1694502&r1=1694501&r2=1694502&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/changes.h (original)
+++ subversion/trunk/subversion/libsvn_fs_x/changes.h Thu Aug 6 14:04:55 2015
@@ -20,8 +20,8 @@
  * ====================================================================
  */
 
-#ifndef SVN_LIBSVN_FS__CHANGES_H
-#define SVN_LIBSVN_FS__CHANGES_H
+#ifndef SVN_LIBSVN_FS_X_CHANGES_H
+#define SVN_LIBSVN_FS_X_CHANGES_H
 
 #include "svn_io.h"
 #include "fs.h"
@@ -78,7 +78,7 @@ svn_error_t *
 svn_fs_x__changes_get_list(apr_array_header_t **list,
                            const svn_fs_x__changes_t *changes,
                            apr_size_t idx,
- apr_pool_t *pool);
+ apr_pool_t *result_pool);
 
 /* I/O interface. */
 
@@ -114,7 +114,7 @@ svn_error_t *
 svn_fs_x__deserialize_changes_container(void **out,
                                         void *data,
                                         apr_size_t data_len,
- apr_pool_t *pool);
+ apr_pool_t *result_pool);
 
 /* Implements svn_cache__partial_getter_func_t for svn_fs_x__changes_t,
  * setting *OUT to the change list (apr_array_header_t *) selected by

Modified: subversion/trunk/subversion/libsvn_fs_x/dag.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/dag.c?rev=1694502&r1=1694501&r2=1694502&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/dag.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/dag.c Thu Aug 6 14:04:55 2015
@@ -1,4 +1,4 @@
-/* dag.c : DAG-like interface filesystem, private to libsvn_fs
+/* dag.c : DAG-like interface filesystem
  *
  * ====================================================================
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -41,6 +41,7 @@
 #include "svn_private_config.h"
 #include "private/svn_temp_serializer.h"
 #include "temp_serializer.h"
+#include "dag_cache.h"
 
 

 /* Initializing a filesystem. */
@@ -50,34 +51,12 @@ struct dag_node_t
   /* The filesystem this dag node came from. */
   svn_fs_t *fs;
 
- /* The node revision ID for this dag node. */
- svn_fs_x__id_t id;
-
- /* In the special case that this node is the root of a transaction
- that has not yet been modified, the revision of this node is the
- respective txn's base rev. Otherwise, this is SVN_INVALID_REVNUM
- for txn nodes and the respective crev for committed nodes.
- (Used in svn_fs_node_created_rev.) */
- svn_revnum_t revision;
-
- /* The node's type (file, dir, etc.) */
- svn_node_kind_t kind;
-
- /* The node's NODE-REVISION, or NULL if we haven't read it in yet.
- This is allocated in this node's POOL.
-
- If you're willing to respect all the rules above, you can munge
- this yourself, but you're probably better off just calling
- `get_node_revision' and `set_node_revision', which take care of
- things for you. */
+ /* The node's NODE-REVISION. */
   svn_fs_x__noderev_t *node_revision;
 
   /* The pool to allocate NODE_REVISION in. */
   apr_pool_t *node_pool;
 
- /* the path at which this node was created. */
- const char *created_path;
-
   /* Directory entry lookup hint to speed up consecutive calls to
      svn_fs_x__rep_contents_dir_entry(). Only used for directory nodes.
      Any value is legal but should default to APR_SIZE_MAX. */
@@ -90,20 +69,20 @@ struct dag_node_t
 svn_node_kind_t
 svn_fs_x__dag_node_kind(dag_node_t *node)
 {
- return node->kind;
+ return node->node_revision->kind;
 }
 
 const svn_fs_x__id_t *
 svn_fs_x__dag_get_id(const dag_node_t *node)
 {
- return &node->id;
+ return &node->node_revision->noderev_id;
 }
 
 
 const char *
 svn_fs_x__dag_get_created_path(dag_node_t *node)
 {
- return node->created_path;
+ return node->node_revision->created_path;
 }
 
 
@@ -144,94 +123,35 @@ copy_node_revision(svn_fs_x__noderev_t *
 }
 
 
-/* Set *NODEREV_P to the cached node-revision for NODE.
- If the node-revision was not already cached in NODE, read it in,
- allocating the cache in NODE->NODE_POOL.
-
- If you plan to change the contents of NODE, be careful! We're
- handing you a pointer directly to our cached node-revision, not
- your own copy. If you change it as part of some operation, but
- then some Berkeley DB function deadlocks or gets an error, you'll
- need to back out your changes, or else the cache will reflect
- changes that never got committed. It's probably best not to change
- the structure at all. */
-static svn_error_t *
-get_node_revision(svn_fs_x__noderev_t **noderev_p,
- dag_node_t *node)
-{
- /* If we've already got a copy, there's no need to read it in. */
- if (! node->node_revision)
- {
- svn_fs_x__noderev_t *noderev;
- apr_pool_t *scratch_pool = svn_pool_create(node->node_pool);
-
- SVN_ERR(svn_fs_x__get_node_revision(&noderev, node->fs, &node->id,
- node->node_pool, scratch_pool));
- node->node_revision = noderev;
- svn_pool_destroy(scratch_pool);
- }
-
- /* Now NODE->node_revision is set. */
- *noderev_p = node->node_revision;
- return SVN_NO_ERROR;
-}
-
-/* Return the node revision ID of NODE. The value returned is shared
- with NODE, and will be deallocated when NODE is. */
-svn_error_t *
-svn_fs_x__dag_get_node_id(svn_fs_x__id_t *node_id,
- dag_node_t *node)
+const svn_fs_x__id_t *
+svn_fs_x__dag_get_node_id(dag_node_t *node)
 {
- svn_fs_x__noderev_t *noderev;
- SVN_ERR(get_node_revision(&noderev, node));
-
- *node_id = noderev->node_id;
- return SVN_NO_ERROR;
+ return &node->node_revision->node_id;
 }
 
-/* Return the node revision ID of NODE. The value returned is shared
- with NODE, and will be deallocated when NODE is. */
-svn_error_t *
-svn_fs_x__dag_get_copy_id(svn_fs_x__id_t *copy_id,
- dag_node_t *node)
+const svn_fs_x__id_t *
+svn_fs_x__dag_get_copy_id(dag_node_t *node)
 {
- svn_fs_x__noderev_t *noderev;
- SVN_ERR(get_node_revision(&noderev, node));
-
- *copy_id = noderev->copy_id;
- return SVN_NO_ERROR;
+ return &node->node_revision->copy_id;
 }
 
-/* Return the node ID of NODE. The value returned is shared with NODE,
- and will be deallocated when NODE is. */
-svn_error_t *
-svn_fs_x__dag_related_node(svn_boolean_t *same,
- dag_node_t *lhs,
+svn_boolean_t
+svn_fs_x__dag_related_node(dag_node_t *lhs,
                            dag_node_t *rhs)
 {
- svn_fs_x__id_t lhs_node, rhs_node;
-
- SVN_ERR(svn_fs_x__dag_get_node_id(&lhs_node, lhs));
- SVN_ERR(svn_fs_x__dag_get_node_id(&rhs_node, rhs));
- *same = svn_fs_x__id_eq(&lhs_node, &rhs_node);
-
- return SVN_NO_ERROR;
+ return svn_fs_x__id_eq(&lhs->node_revision->node_id,
+ &rhs->node_revision->node_id);
 }
 
-svn_error_t *
-svn_fs_x__dag_same_line_of_history(svn_boolean_t *same,
- dag_node_t *lhs,
+svn_boolean_t
+svn_fs_x__dag_same_line_of_history(dag_node_t *lhs,
                                    dag_node_t *rhs)
 {
- svn_fs_x__noderev_t *lhs_noderev, *rhs_noderev;
-
- SVN_ERR(get_node_revision(&lhs_noderev, lhs));
- SVN_ERR(get_node_revision(&rhs_noderev, rhs));
-
- *same = svn_fs_x__id_eq(&lhs_noderev->node_id, &rhs_noderev->node_id)
- && svn_fs_x__id_eq(&lhs_noderev->copy_id, &rhs_noderev->copy_id);
+ svn_fs_x__noderev_t *lhs_noderev = lhs->node_revision;
+ svn_fs_x__noderev_t *rhs_noderev = rhs->node_revision;
 
- return SVN_NO_ERROR;
+ return svn_fs_x__id_eq(&lhs_noderev->node_id, &rhs_noderev->node_id)
+ && svn_fs_x__id_eq(&lhs_noderev->copy_id, &rhs_noderev->copy_id);
 }
 
 svn_boolean_t
@@ -240,7 +160,6 @@ svn_fs_x__dag_check_mutable(const dag_no
   return svn_fs_x__is_txn(svn_fs_x__dag_get_id(node)->change_set);
 }
 
-
 svn_error_t *
 svn_fs_x__dag_get_node(dag_node_t **node,
                        svn_fs_t *fs,
@@ -254,7 +173,6 @@ svn_fs_x__dag_get_node(dag_node_t **node
   /* Construct the node. */
   new_node = apr_pcalloc(result_pool, sizeof(*new_node));
   new_node->fs = fs;
- new_node->id = *id;
   new_node->hint = APR_SIZE_MAX;
 
   /* Grab the contents so we can inspect the node's kind and created path. */
@@ -263,17 +181,6 @@ svn_fs_x__dag_get_node(dag_node_t **node
   new_node->node_pool = result_pool;
   new_node->node_revision = noderev;
 
- /* Initialize the KIND and CREATED_PATH attributes */
- new_node->kind = noderev->kind;
- new_node->created_path = noderev->created_path;
-
- /* Support our quirky svn_fs_node_created_rev API.
- Untouched txn roots report the base rev as theirs. */
- new_node->revision
- = ( svn_fs_x__is_fresh_txn_root(noderev)
- ? svn_fs_x__get_revnum(noderev->predecessor_id.change_set)
- : svn_fs_x__get_revnum(id->change_set));
-
   /* Return a fresh new node */
   *node = new_node;
   return SVN_NO_ERROR;
@@ -283,76 +190,50 @@ svn_fs_x__dag_get_node(dag_node_t **node
 svn_revnum_t
 svn_fs_x__dag_get_revision(const dag_node_t *node)
 {
- return node->revision;
+ svn_fs_x__noderev_t *noderev = node->node_revision;
+ return ( svn_fs_x__is_fresh_txn_root(noderev)
+ ? svn_fs_x__get_revnum(noderev->predecessor_id.change_set)
+ : svn_fs_x__get_revnum(noderev->noderev_id.change_set));
 }
 
-
-svn_error_t *
-svn_fs_x__dag_get_predecessor_id(svn_fs_x__id_t *id_p,
- dag_node_t *node)
+const svn_fs_x__id_t *
+svn_fs_x__dag_get_predecessor_id(dag_node_t *node)
 {
- svn_fs_x__noderev_t *noderev;
-
- SVN_ERR(get_node_revision(&noderev, node));
- *id_p = noderev->predecessor_id;
-
- return SVN_NO_ERROR;
+ return &node->node_revision->predecessor_id;
 }
 
-
-svn_error_t *
-svn_fs_x__dag_get_predecessor_count(int *count,
- dag_node_t *node)
+int
+svn_fs_x__dag_get_predecessor_count(dag_node_t *node)
 {
- svn_fs_x__noderev_t *noderev;
-
- SVN_ERR(get_node_revision(&noderev, node));
- *count = noderev->predecessor_count;
- return SVN_NO_ERROR;
+ return node->node_revision->predecessor_count;
 }
 
-svn_error_t *
-svn_fs_x__dag_get_mergeinfo_count(apr_int64_t *count,
- dag_node_t *node)
+apr_int64_t
+svn_fs_x__dag_get_mergeinfo_count(dag_node_t *node)
 {
- svn_fs_x__noderev_t *noderev;
-
- SVN_ERR(get_node_revision(&noderev, node));
- *count = noderev->mergeinfo_count;
- return SVN_NO_ERROR;
+ return node->node_revision->mergeinfo_count;
 }
 
-svn_error_t *
-svn_fs_x__dag_has_mergeinfo(svn_boolean_t *has_mergeinfo,
- dag_node_t *node)
+svn_boolean_t
+svn_fs_x__dag_has_mergeinfo(dag_node_t *node)
 {
- svn_fs_x__noderev_t *noderev;
-
- SVN_ERR(get_node_revision(&noderev, node));
- *has_mergeinfo = noderev->has_mergeinfo;
- return SVN_NO_ERROR;
+ return node->node_revision->has_mergeinfo;
 }
 
-svn_error_t *
-svn_fs_x__dag_has_descendants_with_mergeinfo(svn_boolean_t *do_they,
- dag_node_t *node)
+svn_boolean_t
+svn_fs_x__dag_has_descendants_with_mergeinfo(dag_node_t *node)
 {
- svn_fs_x__noderev_t *noderev;
+ svn_fs_x__noderev_t *noderev = node->node_revision;
 
- if (node->kind != svn_node_dir)
- {
- *do_they = FALSE;
- return SVN_NO_ERROR;
- }
+ if (noderev->kind != svn_node_dir)
+ return FALSE;
 
- SVN_ERR(get_node_revision(&noderev, node));
   if (noderev->mergeinfo_count > 1)
- *do_they = TRUE;
+ return TRUE;
   else if (noderev->mergeinfo_count == 1 && !noderev->has_mergeinfo)
- *do_they = TRUE;
- else
- *do_they = FALSE;
- return SVN_NO_ERROR;
+ return TRUE;
+
+ return FALSE;
 }
 
 

@@ -362,16 +243,15 @@ svn_fs_x__dag_has_descendants_with_merge
 
 /* Set *ID_P to the noderev-id for entry NAME in PARENT. If no such
    entry, set *ID_P to NULL but do not error. */
-static svn_error_t *
-dir_entry_id_from_node(svn_fs_x__id_t *id_p,
+svn_error_t *
+svn_fs_x__dir_entry_id(svn_fs_x__id_t *id_p,
                        dag_node_t *parent,
                        const char *name,
                        apr_pool_t *scratch_pool)
 {
   svn_fs_x__dirent_t *dirent;
- svn_fs_x__noderev_t *noderev;
+ svn_fs_x__noderev_t *noderev = parent->node_revision;
 
- SVN_ERR(get_node_revision(&noderev, parent));
   if (noderev->kind != svn_node_dir)
     return svn_error_create(SVN_ERR_FS_NOT_DIRECTORY, NULL,
                             _("Can't get entries of non-directory"));
@@ -411,14 +291,16 @@ set_entry(dag_node_t *parent,
           svn_fs_x__txn_id_t txn_id,
           apr_pool_t *scratch_pool)
 {
- svn_fs_x__noderev_t *parent_noderev;
-
- /* Get the parent's node-revision. */
- SVN_ERR(get_node_revision(&parent_noderev, parent));
+ svn_fs_x__noderev_t *parent_noderev = parent->node_revision;
 
   /* Set the new entry. */
- return svn_fs_x__set_entry(parent->fs, txn_id, parent_noderev, name, id,
- kind, parent->node_pool, scratch_pool);
+ SVN_ERR(svn_fs_x__set_entry(parent->fs, txn_id, parent_noderev, name, id,
+ kind, parent->node_pool, scratch_pool));
+
+ /* Update cached data. */
+ svn_fs_x__update_dag_cache(parent);
+
+ return SVN_NO_ERROR;
 }
 
 
@@ -439,7 +321,8 @@ make_entry(dag_node_t **child_p,
            apr_pool_t *result_pool,
            apr_pool_t *scratch_pool)
 {
- svn_fs_x__noderev_t new_noderev, *parent_noderev;
+ svn_fs_x__noderev_t new_noderev;
+ svn_fs_x__noderev_t *parent_noderev = parent->node_revision;
 
   /* Make sure that NAME is a single path component. */
   if (! svn_path_is_single_path_component(name))
@@ -448,7 +331,7 @@ make_entry(dag_node_t **child_p,
        _("Attempted to create a node with an illegal name '%s'"), name);
 
   /* Make sure that parent is a directory */
- if (parent->kind != svn_node_dir)
+ if (parent_noderev->kind != svn_node_dir)
     return svn_error_create
       (SVN_ERR_FS_NOT_DIRECTORY, NULL,
        _("Attempted to create entry in non-directory parent"));
@@ -464,7 +347,6 @@ make_entry(dag_node_t **child_p,
   new_noderev.kind = is_dir ? svn_node_dir : svn_node_file;
   new_noderev.created_path = svn_fspath__join(parent_path, name, result_pool);
 
- SVN_ERR(get_node_revision(&parent_noderev, parent));
   new_noderev.copyroot_path = apr_pstrdup(result_pool,
                                           parent_noderev->copyroot_path);
   new_noderev.copyroot_rev = parent_noderev->copyroot_rev;
@@ -495,9 +377,7 @@ svn_fs_x__dag_dir_entries(apr_array_head
                           apr_pool_t *result_pool,
                           apr_pool_t *scratch_pool)
 {
- svn_fs_x__noderev_t *noderev;
-
- SVN_ERR(get_node_revision(&noderev, node));
+ svn_fs_x__noderev_t *noderev = node->node_revision;
 
   if (noderev->kind != svn_node_dir)
     return svn_error_create(SVN_ERR_FS_NOT_DIRECTORY, NULL,
@@ -517,7 +397,7 @@ svn_fs_x__dag_set_entry(dag_node_t *node
                         apr_pool_t *scratch_pool)
 {
   /* Check it's a directory. */
- if (node->kind != svn_node_dir)
+ if (node->node_revision->kind != svn_node_dir)
     return svn_error_create
       (SVN_ERR_FS_NOT_DIRECTORY, NULL,
        _("Attempted to set entry in non-directory node"));
@@ -541,16 +421,8 @@ svn_fs_x__dag_get_proplist(apr_hash_t **
                            apr_pool_t *result_pool,
                            apr_pool_t *scratch_pool)
 {
- svn_fs_x__noderev_t *noderev;
- apr_hash_t *proplist = NULL;
-
- SVN_ERR(get_node_revision(&noderev, node));
-
- SVN_ERR(svn_fs_x__get_proplist(&proplist, node->fs, noderev, result_pool,
- scratch_pool));
-
- *proplist_p = proplist;
-
+ SVN_ERR(svn_fs_x__get_proplist(proplist_p, node->fs, node->node_revision,
+ result_pool, scratch_pool));
   return SVN_NO_ERROR;
 }
 
@@ -560,37 +432,51 @@ svn_fs_x__dag_set_proplist(dag_node_t *n
                            apr_hash_t *proplist,
                            apr_pool_t *scratch_pool)
 {
- svn_fs_x__noderev_t *noderev;
-
   /* Sanity check: this node better be mutable! */
   if (! svn_fs_x__dag_check_mutable(node))
     {
- svn_string_t *idstr = svn_fs_x__id_unparse(&node->id, scratch_pool);
+ svn_string_t *idstr
+ = svn_fs_x__id_unparse(&node->node_revision->noderev_id,
+ scratch_pool);
       return svn_error_createf
         (SVN_ERR_FS_NOT_MUTABLE, NULL,
          "Can't set proplist on *immutable* node-revision %s",
          idstr->data);
     }
 
- /* Go get a fresh NODE-REVISION for this node. */
- SVN_ERR(get_node_revision(&noderev, node));
-
   /* Set the new proplist. */
- return svn_fs_x__set_proplist(node->fs, noderev, proplist, scratch_pool);
+ SVN_ERR(svn_fs_x__set_proplist(node->fs, node->node_revision, proplist,
+ scratch_pool));
+ svn_fs_x__update_dag_cache(node);
+
+ return SVN_NO_ERROR;
 }
 
+/* Write NODE's NODEREV element to disk. Update the DAG cache.
+ Use SCRATCH_POOL for temporary allocations. */
+static svn_error_t *
+noderev_changed(dag_node_t *node,
+ apr_pool_t *scratch_pool)
+{
+ SVN_ERR(svn_fs_x__put_node_revision(node->fs, node->node_revision,
+ scratch_pool));
+ svn_fs_x__update_dag_cache(node);
+
+ return SVN_NO_ERROR;
+}
 
 svn_error_t *
 svn_fs_x__dag_increment_mergeinfo_count(dag_node_t *node,
                                         apr_int64_t increment,
                                         apr_pool_t *scratch_pool)
 {
- svn_fs_x__noderev_t *noderev;
+ svn_fs_x__noderev_t *noderev = node->node_revision;
 
   /* Sanity check: this node better be mutable! */
   if (! svn_fs_x__dag_check_mutable(node))
     {
- svn_string_t *idstr = svn_fs_x__id_unparse(&node->id, scratch_pool);
+ svn_string_t *idstr = svn_fs_x__id_unparse(&noderev->noderev_id,
+ scratch_pool);
       return svn_error_createf
         (SVN_ERR_FS_NOT_MUTABLE, NULL,
          "Can't increment mergeinfo count on *immutable* node-revision %s",
@@ -600,13 +486,11 @@ svn_fs_x__dag_increment_mergeinfo_count(
   if (increment == 0)
     return SVN_NO_ERROR;
 
- /* Go get a fresh NODE-REVISION for this node. */
- SVN_ERR(get_node_revision(&noderev, node));
-
   noderev->mergeinfo_count += increment;
   if (noderev->mergeinfo_count < 0)
     {
- svn_string_t *idstr = svn_fs_x__id_unparse(&node->id, scratch_pool);
+ svn_string_t *idstr = svn_fs_x__id_unparse(&noderev->noderev_id,
+ scratch_pool);
       return svn_error_createf
         (SVN_ERR_FS_CORRUPT, NULL,
          apr_psprintf(scratch_pool,
@@ -617,7 +501,8 @@ svn_fs_x__dag_increment_mergeinfo_count(
     }
   if (noderev->mergeinfo_count > 1 && noderev->kind == svn_node_file)
     {
- svn_string_t *idstr = svn_fs_x__id_unparse(&node->id, scratch_pool);
+ svn_string_t *idstr = svn_fs_x__id_unparse(&noderev->noderev_id,
+ scratch_pool);
       return svn_error_createf
         (SVN_ERR_FS_CORRUPT, NULL,
          apr_psprintf(scratch_pool,
@@ -628,7 +513,7 @@ svn_fs_x__dag_increment_mergeinfo_count(
     }
 
   /* Flush it out. */
- return svn_fs_x__put_node_revision(node->fs, noderev, scratch_pool);
+ return noderev_changed(node, scratch_pool);
 }
 
 svn_error_t *
@@ -636,55 +521,38 @@ svn_fs_x__dag_set_has_mergeinfo(dag_node
                                 svn_boolean_t has_mergeinfo,
                                 apr_pool_t *scratch_pool)
 {
- svn_fs_x__noderev_t *noderev;
-
   /* Sanity check: this node better be mutable! */
   if (! svn_fs_x__dag_check_mutable(node))
     {
- svn_string_t *idstr = svn_fs_x__id_unparse(&node->id, scratch_pool);
+ svn_string_t *idstr
+ = svn_fs_x__id_unparse(&node->node_revision->noderev_id,
+ scratch_pool);
       return svn_error_createf
         (SVN_ERR_FS_NOT_MUTABLE, NULL,
          "Can't set mergeinfo flag on *immutable* node-revision %s",
          idstr->data);
     }
 
- /* Go get a fresh NODE-REVISION for this node. */
- SVN_ERR(get_node_revision(&noderev, node));
-
- noderev->has_mergeinfo = has_mergeinfo;
+ node->node_revision->has_mergeinfo = has_mergeinfo;
 
   /* Flush it out. */
- return svn_fs_x__put_node_revision(node->fs, noderev, scratch_pool);
+ return noderev_changed(node, scratch_pool);
 }
 
 

 /*** Roots. ***/
 
 svn_error_t *
-svn_fs_x__dag_revision_root(dag_node_t **node_p,
- svn_fs_t *fs,
- svn_revnum_t rev,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- svn_fs_x__id_t root_id;
-
- svn_fs_x__init_rev_root(&root_id, rev);
- return svn_fs_x__dag_get_node(node_p, fs, &root_id, result_pool,
- scratch_pool);
-}
-
-
-svn_error_t *
-svn_fs_x__dag_txn_root(dag_node_t **node_p,
- svn_fs_t *fs,
- svn_fs_x__txn_id_t txn_id,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
+svn_fs_x__dag_root(dag_node_t **node_p,
+ svn_fs_t *fs,
+ svn_fs_x__change_set_t change_set,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
 {
   svn_fs_x__id_t root_id;
+ root_id.change_set = change_set;
+ root_id.number = SVN_FS_X__ITEM_INDEX_ROOT_NODE;
 
- svn_fs_x__init_txn_root(&root_id, txn_id);
   return svn_fs_x__dag_get_node(node_p, fs, &root_id, result_pool,
                                 scratch_pool);
 }
@@ -734,14 +602,11 @@ svn_fs_x__dag_clone_child(dag_node_t **c
     }
   else
     {
- svn_fs_x__noderev_t *noderev, *parent_noderev;
-
- /* Go get a fresh NODE-REVISION for current child node. */
- SVN_ERR(get_node_revision(&noderev, cur_entry));
+ svn_fs_x__noderev_t *noderev = cur_entry->node_revision;
 
       if (is_parent_copyroot)
         {
- SVN_ERR(get_node_revision(&parent_noderev, parent));
+ svn_fs_x__noderev_t *parent_noderev = parent->node_revision;
           noderev->copyroot_rev = parent_noderev->copyroot_rev;
           noderev->copyroot_path = apr_pstrdup(scratch_pool,
                                                parent_noderev->copyroot_path);
@@ -796,7 +661,7 @@ delete_if_mutable(svn_fs_t *fs,
     return SVN_NO_ERROR;
 
   /* Else it's mutable. Recurse on directories... */
- if (node->kind == svn_node_dir)
+ if (node->node_revision->kind == svn_node_dir)
     {
       apr_array_header_t *entries;
       int i;
@@ -829,13 +694,13 @@ svn_fs_x__dag_delete(dag_node_t *parent,
                      svn_fs_x__txn_id_t txn_id,
                      apr_pool_t *scratch_pool)
 {
- svn_fs_x__noderev_t *parent_noderev;
+ svn_fs_x__noderev_t *parent_noderev = parent->node_revision;
   svn_fs_t *fs = parent->fs;
   svn_fs_x__dirent_t *dirent;
   apr_pool_t *subpool;
 
   /* Make sure parent is a directory. */
- if (parent->kind != svn_node_dir)
+ if (parent_noderev->kind != svn_node_dir)
     return svn_error_createf
       (SVN_ERR_FS_NOT_DIRECTORY, NULL,
        "Attempted to delete entry '%s' from *non*-directory node", name);
@@ -852,9 +717,9 @@ svn_fs_x__dag_delete(dag_node_t *parent,
       (SVN_ERR_FS_NOT_SINGLE_PATH_COMPONENT, NULL,
        "Attempted to delete a node with an illegal name '%s'", name);
 
- /* Get a fresh NODE-REVISION for the parent node. */
- SVN_ERR(get_node_revision(&parent_noderev, parent));
-
+ /* We allocate a few potentially heavy temporary objects (file buffers
+ and directories). Make sure we don't keep them around for longer
+ than necessary. */
   subpool = svn_pool_create(scratch_pool);
 
   /* Search this directory for a dirent with that NAME. */
@@ -871,13 +736,13 @@ svn_fs_x__dag_delete(dag_node_t *parent,
        "Delete failed--directory has no entry '%s'", name);
 
   /* If mutable, remove it and any mutable children from db. */
- SVN_ERR(delete_if_mutable(parent->fs, &dirent->id, scratch_pool));
- svn_pool_destroy(subpool);
+ SVN_ERR(delete_if_mutable(parent->fs, &dirent->id, subpool));
 
   /* Remove this entry from its parent's entries list. */
- return svn_fs_x__set_entry(parent->fs, txn_id, parent_noderev, name,
- NULL, svn_node_unknown, parent->node_pool,
- scratch_pool);
+ SVN_ERR(set_entry(parent, name, NULL, svn_node_unknown, txn_id, subpool));
+
+ svn_pool_destroy(subpool);
+ return SVN_NO_ERROR;
 }
 
 
@@ -916,23 +781,16 @@ svn_fs_x__dag_get_contents(svn_stream_t
                            dag_node_t *file,
                            apr_pool_t *result_pool)
 {
- svn_fs_x__noderev_t *noderev;
- svn_stream_t *contents;
-
   /* Make sure our node is a file. */
- if (file->kind != svn_node_file)
+ if (file->node_revision->kind != svn_node_file)
     return svn_error_createf
       (SVN_ERR_FS_NOT_FILE, NULL,
        "Attempted to get textual contents of a *non*-file node");
 
- /* Go get a fresh node-revision for FILE. */
- SVN_ERR(get_node_revision(&noderev, file));
-
   /* Get a stream to the contents. */
- SVN_ERR(svn_fs_x__get_contents(&contents, file->fs,
- noderev->data_rep, TRUE, result_pool));
-
- *contents_p = contents;
+ SVN_ERR(svn_fs_x__get_contents(contents_p, file->fs,
+ file->node_revision->data_rep, TRUE,
+ result_pool));
 
   return SVN_NO_ERROR;
 }
@@ -945,23 +803,16 @@ svn_fs_x__dag_get_file_delta_stream(svn_
                                     apr_pool_t *result_pool,
                                     apr_pool_t *scratch_pool)
 {
- svn_fs_x__noderev_t *src_noderev;
- svn_fs_x__noderev_t *tgt_noderev;
+ svn_fs_x__noderev_t *src_noderev = source ? source->node_revision : NULL;
+ svn_fs_x__noderev_t *tgt_noderev = target->node_revision;
 
   /* Make sure our nodes are files. */
- if ((source && source->kind != svn_node_file)
- || target->kind != svn_node_file)
+ if ((source && src_noderev->kind != svn_node_file)
+ || tgt_noderev->kind != svn_node_file)
     return svn_error_createf
       (SVN_ERR_FS_NOT_FILE, NULL,
        "Attempted to get textual contents of a *non*-file node");
 
- /* Go get fresh node-revisions for the nodes. */
- if (source)
- SVN_ERR(get_node_revision(&src_noderev, source));
- else
- src_noderev = NULL;
- SVN_ERR(get_node_revision(&tgt_noderev, target));
-
   /* Get the delta stream. */
   return svn_fs_x__get_file_delta_stream(stream_p, target->fs,
                                          src_noderev, tgt_noderev,
@@ -976,13 +827,8 @@ svn_fs_x__dag_try_process_file_contents(
                                         void* baton,
                                         apr_pool_t *scratch_pool)
 {
- svn_fs_x__noderev_t *noderev;
-
- /* Go get fresh node-revisions for the nodes. */
- SVN_ERR(get_node_revision(&noderev, node));
-
   return svn_fs_x__try_process_file_contents(success, node->fs,
- noderev,
+ node->node_revision,
                                              processor, baton, scratch_pool);
 }
 
@@ -991,18 +837,13 @@ svn_error_t *
 svn_fs_x__dag_file_length(svn_filesize_t *length,
                           dag_node_t *file)
 {
- svn_fs_x__noderev_t *noderev;
-
   /* Make sure our node is a file. */
- if (file->kind != svn_node_file)
+ if (file->node_revision->kind != svn_node_file)
     return svn_error_createf
       (SVN_ERR_FS_NOT_FILE, NULL,
        "Attempted to get length of a *non*-file node");
 
- /* Go get a fresh node-revision for FILE, and . */
- SVN_ERR(get_node_revision(&noderev, file));
-
- return svn_fs_x__file_length(length, noderev);
+ return svn_fs_x__file_length(length, file->node_revision);
 }
 
 
@@ -1012,16 +853,13 @@ svn_fs_x__dag_file_checksum(svn_checksum
                             svn_checksum_kind_t kind,
                             apr_pool_t *result_pool)
 {
- svn_fs_x__noderev_t *noderev;
-
- if (file->kind != svn_node_file)
+ if (file->node_revision->kind != svn_node_file)
     return svn_error_createf
       (SVN_ERR_FS_NOT_FILE, NULL,
        "Attempted to get checksum of a *non*-file node");
 
- SVN_ERR(get_node_revision(&noderev, file));
-
- return svn_fs_x__file_checksum(checksum, noderev, kind, result_pool);
+ return svn_fs_x__file_checksum(checksum, file->node_revision, kind,
+ result_pool);
 }
 
 
@@ -1030,11 +868,8 @@ svn_fs_x__dag_get_edit_stream(svn_stream
                               dag_node_t *file,
                               apr_pool_t *result_pool)
 {
- svn_fs_x__noderev_t *noderev;
- svn_stream_t *ws;
-
   /* Make sure our node is a file. */
- if (file->kind != svn_node_file)
+ if (file->node_revision->kind != svn_node_file)
     return svn_error_createf
       (SVN_ERR_FS_NOT_FILE, NULL,
        "Attempted to set textual contents of a *non*-file node");
@@ -1045,13 +880,8 @@ svn_fs_x__dag_get_edit_stream(svn_stream
       (SVN_ERR_FS_NOT_MUTABLE, NULL,
        "Attempted to set textual contents of an immutable node");
 
- /* Get the node revision. */
- SVN_ERR(get_node_revision(&noderev, file));
-
- SVN_ERR(svn_fs_x__set_contents(&ws, file->fs, noderev, result_pool));
-
- *contents = ws;
-
+ SVN_ERR(svn_fs_x__set_contents(contents, file->fs, file->node_revision,
+ result_pool));
   return SVN_NO_ERROR;
 }
 
@@ -1072,9 +902,10 @@ svn_fs_x__dag_finalize_edits(dag_node_t
         return svn_checksum_mismatch_err(checksum, file_checksum,
                                          scratch_pool,
                                          _("Checksum mismatch for '%s'"),
- file->created_path);
+ file->node_revision->created_path);
     }
 
+ svn_fs_x__update_dag_cache(file);
   return SVN_NO_ERROR;
 }
 
@@ -1086,101 +917,14 @@ svn_fs_x__dag_dup(const dag_node_t *node
   /* Allocate our new node. */
   dag_node_t *new_node = apr_pmemdup(result_pool, node, sizeof(*new_node));
 
- /* Only copy cached svn_fs_x__noderev_t for immutable nodes. */
- if (node->node_revision && !svn_fs_x__dag_check_mutable(node))
- {
- new_node->node_revision = copy_node_revision(node->node_revision,
- result_pool);
- new_node->created_path = new_node->node_revision->created_path;
- }
- else
- {
- new_node->node_revision = NULL;
- new_node->created_path = apr_pstrdup(result_pool, node->created_path);
- }
-
+ /* Copy sub-structures. */
+ new_node->node_revision = copy_node_revision(node->node_revision,
+ result_pool);
   new_node->node_pool = result_pool;
 
   return new_node;
 }
 
-dag_node_t *
-svn_fs_x__dag_copy_into_pool(dag_node_t *node,
- apr_pool_t *result_pool)
-{
- return (node->node_pool == result_pool
- ? node
- : svn_fs_x__dag_dup(node, result_pool));
-}
-
-svn_error_t *
-svn_fs_x__dag_serialize(void **data,
- apr_size_t *data_len,
- void *in,
- apr_pool_t *pool)
-{
- dag_node_t *node = in;
- svn_stringbuf_t *serialized;
-
- /* create an serialization context and serialize the dag node as root */
- svn_temp_serializer__context_t *context =
- svn_temp_serializer__init(node,
- sizeof(*node),
- 1024 - SVN_TEMP_SERIALIZER__OVERHEAD,
- pool);
-
- /* for mutable nodes, we will _never_ cache the noderev */
- if (node->node_revision && !svn_fs_x__dag_check_mutable(node))
- {
- svn_fs_x__noderev_serialize(context, &node->node_revision);
- }
- else
- {
- svn_temp_serializer__set_null(context,
- (const void * const *)&node->node_revision);
- svn_temp_serializer__add_string(context, &node->created_path);
- }
-
- /* The deserializer will use its own pool. */
- svn_temp_serializer__set_null(context,
- (const void * const *)&node->node_pool);
-
- /* return serialized data */
- serialized = svn_temp_serializer__get(context);
- *data = serialized->data;
- *data_len = serialized->len;
-
- return SVN_NO_ERROR;
-}
-
-svn_error_t *
-svn_fs_x__dag_deserialize(void **out,
- void *data,
- apr_size_t data_len,
- apr_pool_t *pool)
-{
- dag_node_t *node = (dag_node_t *)data;
- if (data_len == 0)
- return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
- _("Empty noderev in cache"));
-
- /* Copy the _full_ buffer as it also contains the sub-structures. */
- node->fs = NULL;
-
- /* fixup all references to sub-structures */
- svn_fs_x__noderev_deserialize(node, &node->node_revision, pool);
- node->node_pool = pool;
-
- if (node->node_revision)
- node->created_path = node->node_revision->created_path;
- else
- svn_temp_deserializer__resolve(node, (void**)&node->created_path);
-
- /* return result */
- *out = node;
-
- return SVN_NO_ERROR;
-}
 
 svn_error_t *
 svn_fs_x__dag_open(dag_node_t **child_p,
@@ -1192,7 +936,7 @@ svn_fs_x__dag_open(dag_node_t **child_p,
   svn_fs_x__id_t node_id;
 
   /* Ensure that NAME exists in PARENT's entry list. */
- SVN_ERR(dir_entry_id_from_node(&node_id, parent, name, scratch_pool));
+ SVN_ERR(svn_fs_x__dir_entry_id(&node_id, parent, name, scratch_pool));
   if (! svn_fs_x__id_used(&node_id))
     {
       *child_p = NULL;
@@ -1219,13 +963,12 @@ svn_fs_x__dag_copy(dag_node_t *to_node,
 
   if (preserve_history)
     {
- svn_fs_x__noderev_t *from_noderev, *to_noderev;
+ svn_fs_x__noderev_t *to_noderev;
       svn_fs_x__id_t copy_id;
       svn_fs_t *fs = svn_fs_x__dag_get_fs(from_node);
 
       /* Make a copy of the original node revision. */
- SVN_ERR(get_node_revision(&from_noderev, from_node));
- to_noderev = copy_node_revision(from_noderev, scratch_pool);
+ to_noderev = copy_node_revision(from_node->node_revision, scratch_pool);
 
       /* Reserve a copy ID for this new copy. */
       SVN_ERR(svn_fs_x__reserve_copy_id(&copy_id, fs, txn_id, scratch_pool));
@@ -1253,7 +996,8 @@ svn_fs_x__dag_copy(dag_node_t *to_node,
     }
 
   /* Set the entry in to_node to the new id. */
- return svn_fs_x__dag_set_entry(to_node, entry, id, from_node->kind,
+ return svn_fs_x__dag_set_entry(to_node, entry, id,
+ from_node->node_revision->kind,
                                  txn_id, scratch_pool);
 }
 
@@ -1269,7 +1013,8 @@ svn_fs_x__dag_things_different(svn_boole
                                svn_boolean_t strict,
                                apr_pool_t *scratch_pool)
 {
- svn_fs_x__noderev_t *noderev1, *noderev2;
+ svn_fs_x__noderev_t *noderev1 = node1->node_revision;
+ svn_fs_x__noderev_t *noderev2 = node2->node_revision;
   svn_fs_t *fs;
   svn_boolean_t same;
 
@@ -1280,10 +1025,6 @@ svn_fs_x__dag_things_different(svn_boole
 
   fs = svn_fs_x__dag_get_fs(node1);
 
- /* The node revision skels for these two nodes. */
- SVN_ERR(get_node_revision(&noderev1, node1));
- SVN_ERR(get_node_revision(&noderev2, node2));
-
   /* Compare property keys. */
   if (props_changed != NULL)
     {
@@ -1300,48 +1041,25 @@ svn_fs_x__dag_things_different(svn_boole
   return SVN_NO_ERROR;
 }
 
-svn_error_t *
+void
 svn_fs_x__dag_get_copyroot(svn_revnum_t *rev,
                            const char **path,
                            dag_node_t *node)
 {
- svn_fs_x__noderev_t *noderev;
-
- /* Go get a fresh node-revision for NODE. */
- SVN_ERR(get_node_revision(&noderev, node));
-
- *rev = noderev->copyroot_rev;
- *path = noderev->copyroot_path;
-
- return SVN_NO_ERROR;
+ *rev = node->node_revision->copyroot_rev;
+ *path = node->node_revision->copyroot_path;
 }
 
-svn_error_t *
-svn_fs_x__dag_get_copyfrom_rev(svn_revnum_t *rev,
- dag_node_t *node)
+svn_revnum_t
+svn_fs_x__dag_get_copyfrom_rev(dag_node_t *node)
 {
- svn_fs_x__noderev_t *noderev;
-
- /* Go get a fresh node-revision for NODE. */
- SVN_ERR(get_node_revision(&noderev, node));
-
- *rev = noderev->copyfrom_rev;
-
- return SVN_NO_ERROR;
+ return node->node_revision->copyfrom_rev;
 }
 
-svn_error_t *
-svn_fs_x__dag_get_copyfrom_path(const char **path,
- dag_node_t *node)
+const char *
+svn_fs_x__dag_get_copyfrom_path(dag_node_t *node)
 {
- svn_fs_x__noderev_t *noderev;
-
- /* Go get a fresh node-revision for NODE. */
- SVN_ERR(get_node_revision(&noderev, node));
-
- *path = noderev->copyfrom_path;
-
- return SVN_NO_ERROR;
+ return node->node_revision->copyfrom_path;
 }
 
 svn_error_t *
@@ -1349,20 +1067,17 @@ svn_fs_x__dag_update_ancestry(dag_node_t
                               dag_node_t *source,
                               apr_pool_t *scratch_pool)
 {
- svn_fs_x__noderev_t *source_noderev, *target_noderev;
+ svn_fs_x__noderev_t *source_noderev = source->node_revision;
+ svn_fs_x__noderev_t *target_noderev = target->node_revision;
 
   if (! svn_fs_x__dag_check_mutable(target))
     return svn_error_createf
       (SVN_ERR_FS_NOT_MUTABLE, NULL,
        _("Attempted to update ancestry of non-mutable node"));
 
- SVN_ERR(get_node_revision(&source_noderev, source));
- SVN_ERR(get_node_revision(&target_noderev, target));
-
   target_noderev->predecessor_id = source_noderev->noderev_id;
   target_noderev->predecessor_count = source_noderev->predecessor_count;
   target_noderev->predecessor_count++;
 
- return svn_fs_x__put_node_revision(target->fs, target_noderev,
- scratch_pool);
+ return noderev_changed(target, scratch_pool);
 }

Modified: subversion/trunk/subversion/libsvn_fs_x/dag.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/dag.h?rev=1694502&r1=1694501&r2=1694502&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/dag.h (original)
+++ subversion/trunk/subversion/libsvn_fs_x/dag.h Thu Aug 6 14:04:55 2015
@@ -1,4 +1,4 @@
-/* dag.h : DAG-like interface filesystem, private to libsvn_fs
+/* dag.h : DAG-like interface filesystem
  *
  * ====================================================================
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -20,8 +20,8 @@
  * ====================================================================
  */
 
-#ifndef SVN_LIBSVN_FS_DAG_H
-#define SVN_LIBSVN_FS_DAG_H
+#ifndef SVN_LIBSVN_FS_X_DAG_H
+#define SVN_LIBSVN_FS_X_DAG_H
 
 #include "svn_fs.h"
 #include "svn_delta.h"
@@ -82,28 +82,6 @@ dag_node_t *
 svn_fs_x__dag_dup(const dag_node_t *node,
                   apr_pool_t *result_pool);
 
-/* If NODE has been allocated in POOL, return NODE. Otherwise, return
- a copy created in RESULT_POOL with svn_fs_fs__dag_dup. */
-dag_node_t *
-svn_fs_x__dag_copy_into_pool(dag_node_t *node,
- apr_pool_t *result_pool);
-
-/* Serialize a DAG node, except don't try to preserve the 'fs' member.
- Implements svn_cache__serialize_func_t */
-svn_error_t *
-svn_fs_x__dag_serialize(void **data,
- apr_size_t *data_len,
- void *in,
- apr_pool_t *pool);
-
-/* Deserialize a DAG node, leaving the 'fs' member as NULL.
- Implements svn_cache__deserialize_func_t */
-svn_error_t *
-svn_fs_x__dag_deserialize(void **out,
- void *data,
- apr_size_t data_len,
- apr_pool_t *pool);
-
 /* Return the filesystem containing NODE. */
 svn_fs_t *
 svn_fs_x__dag_get_fs(dag_node_t *node);
@@ -128,27 +106,23 @@ svn_fs_x__dag_get_id(const dag_node_t *n
 
 /* Return the node ID of NODE. The value returned is shared with NODE,
    and will be deallocated when NODE is. */
-svn_error_t *
-svn_fs_x__dag_get_node_id(svn_fs_x__id_t *node_id,
- dag_node_t *node);
+const svn_fs_x__id_t *
+svn_fs_x__dag_get_node_id(dag_node_t *node);
 
 /* Return the copy ID of NODE. The value returned is shared with NODE,
    and will be deallocated when NODE is. */
-svn_error_t *
-svn_fs_x__dag_get_copy_id(svn_fs_x__id_t *copy_id,
- dag_node_t *node);
+const svn_fs_x__id_t *
+svn_fs_x__dag_get_copy_id(dag_node_t *node);
 
-/* Set *SAME to TRUE, if nodes LHS and RHS have the same node ID. */
-svn_error_t *
-svn_fs_x__dag_related_node(svn_boolean_t *same,
- dag_node_t *lhs,
+/* Return TRUE, iff nodes LHS and RHS have the same node ID. */
+svn_boolean_t
+svn_fs_x__dag_related_node(dag_node_t *lhs,
                            dag_node_t *rhs);
 
-/* Set *SAME to TRUE, if nodes LHS and RHS have the same node and copy IDs.
+/* Return TRUE, iff nodes LHS and RHS have the same node and copy IDs.
  */
-svn_error_t *
-svn_fs_x__dag_same_line_of_history(svn_boolean_t *same,
- dag_node_t *lhs,
+svn_boolean_t
+svn_fs_x__dag_same_line_of_history(dag_node_t *lhs,
                                    dag_node_t *rhs);
 
 /* Return the created path of NODE. The value returned is shared
@@ -157,41 +131,31 @@ const char *
 svn_fs_x__dag_get_created_path(dag_node_t *node);
 
 
-/* Set *ID_P to the node revision ID of NODE's immediate predecessor.
+/* Return the node revision ID of NODE's immediate predecessor.
  */
-svn_error_t *
-svn_fs_x__dag_get_predecessor_id(svn_fs_x__id_t *id_p,
- dag_node_t *node);
-
+const svn_fs_x__id_t *
+svn_fs_x__dag_get_predecessor_id(dag_node_t *node);
 
-/* Set *COUNT to the number of predecessors NODE has (recursively).
+/* Return the number of predecessors NODE has (recursively).
  */
-/* ### This function is currently only used by 'verify'. */
-svn_error_t *
-svn_fs_x__dag_get_predecessor_count(int *count,
- dag_node_t *node);
+int
+svn_fs_x__dag_get_predecessor_count(dag_node_t *node);
 
-/* Set *COUNT to the number of node under NODE (inclusive) with
- svn:mergeinfo properties.
+/* Return the number of node under NODE (inclusive) with svn:mergeinfo
+ properties.
  */
-svn_error_t *
-svn_fs_x__dag_get_mergeinfo_count(apr_int64_t *count,
- dag_node_t *node);
+apr_int64_t
+svn_fs_x__dag_get_mergeinfo_count(dag_node_t *node);
 
-/* Set *DO_THEY to a flag indicating whether or not NODE is a
- directory with at least one descendant (not including itself) with
- svn:mergeinfo.
+/* Return TRUE, iff NODE is a directory with at least one descendant (not
+ including itself) with svn:mergeinfo.
  */
-svn_error_t *
-svn_fs_x__dag_has_descendants_with_mergeinfo(svn_boolean_t *do_they,
- dag_node_t *node);
+svn_boolean_t
+svn_fs_x__dag_has_descendants_with_mergeinfo(dag_node_t *node);
 
-/* Set *HAS_MERGEINFO to a flag indicating whether or not NODE itself
- has svn:mergeinfo set on it.
- */
-svn_error_t *
-svn_fs_x__dag_has_mergeinfo(svn_boolean_t *has_mergeinfo,
- dag_node_t *node);
+/* Return TRUE, iff NODE itself has svn:mergeinfo set on it. */
+svn_boolean_t
+svn_fs_x__dag_has_mergeinfo(dag_node_t *node);
 
 /* Return non-zero IFF NODE is currently mutable. */
 svn_boolean_t
@@ -252,25 +216,15 @@ svn_fs_x__dag_set_has_mergeinfo(dag_node
 /* Revision and transaction roots. */
 
 
-/* Open the root of revision REV of filesystem FS, allocating from
+/* Open the root of change set CHANGE_SET of filesystem FS, allocating from
    RESULT_POOL. Set *NODE_P to the new node. Use SCRATCH_POOL for
    temporary allocations.*/
 svn_error_t *
-svn_fs_x__dag_revision_root(dag_node_t **node_p,
- svn_fs_t *fs,
- svn_revnum_t rev,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool);
-
-
-/* Set *NODE_P to the root of transaction TXN_ID in FS, allocating
- from RESULT_POOL. Use SCRATCH_POOL for temporary allocations. */
-svn_error_t *
-svn_fs_x__dag_txn_root(dag_node_t **node_p,
- svn_fs_t *fs,
- svn_fs_x__txn_id_t txn_id,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool);
+svn_fs_x__dag_root(dag_node_t **node_p,
+ svn_fs_t *fs,
+ svn_fs_x__change_set_t change_set,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
 
 

 /* Directories. */
@@ -289,6 +243,14 @@ svn_fs_x__dag_open(dag_node_t **child_p,
                    apr_pool_t *scratch_pool);
 
 
+/* Set *ID_P to the noderev-id for entry NAME in PARENT. If no such
+ entry exists, set *ID_P to "unused" but do not error. */
+svn_error_t *
+svn_fs_x__dir_entry_id(svn_fs_x__id_t *id_p,
+ dag_node_t *parent,
+ const char *name,
+ apr_pool_t *scratch_pool);
+
 /* Set *ENTRIES_P to an array of NODE's entries, sorted by entry names,
    and the values are svn_fs_x__dirent_t. The returned table (and elements)
    is allocated in RESULT_POOL, temporaries in SCRATCH_POOL. */
@@ -548,22 +510,20 @@ svn_fs_x__dag_things_different(svn_boole
 /* Set *REV and *PATH to the copyroot revision and path of node NODE, or
    to SVN_INVALID_REVNUM and NULL if no copyroot exists.
  */
-svn_error_t *
+void
 svn_fs_x__dag_get_copyroot(svn_revnum_t *rev,
                            const char **path,
                            dag_node_t *node);
 
-/* Set *REV to the copyfrom revision associated with NODE.
+/* Return the copyfrom revision associated with NODE.
  */
-svn_error_t *
-svn_fs_x__dag_get_copyfrom_rev(svn_revnum_t *rev,
- dag_node_t *node);
+svn_revnum_t
+svn_fs_x__dag_get_copyfrom_rev(dag_node_t *node);
 
-/* Set *PATH to the copyfrom path associated with NODE.
+/* Return the copyfrom path associated with NODE.
  */
-svn_error_t *
-svn_fs_x__dag_get_copyfrom_path(const char **path,
- dag_node_t *node);
+const char *
+svn_fs_x__dag_get_copyfrom_path(dag_node_t *node);
 
 /* Update *TARGET so that SOURCE is it's predecessor.
 
@@ -577,4 +537,4 @@ svn_fs_x__dag_update_ancestry(dag_node_t
 }
 #endif /* __cplusplus */
 
-#endif /* SVN_LIBSVN_FS_DAG_H */
+#endif /* SVN_LIBSVN_FS_X_DAG_H */

Modified: subversion/trunk/subversion/libsvn_fs_x/fs.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/fs.c?rev=1694502&r1=1694501&r2=1694502&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/fs.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/fs.c Thu Aug 6 14:04:55 2015
@@ -32,6 +32,7 @@
 #include "svn_delta.h"
 #include "svn_version.h"
 #include "svn_pools.h"
+#include "batch_fsync.h"
 #include "fs.h"
 #include "fs_x.h"
 #include "pack.h"
@@ -663,6 +664,8 @@ svn_fs_x__init(const svn_version_t *load
                              loader_version->major);
   SVN_ERR(svn_ver_check_list2(x_version(), checklist, svn_ver_equal));
 
+ SVN_ERR(svn_fs_x__batch_fsync_init());
+
   *vtable = &library_vtable;
   return SVN_NO_ERROR;
 }

Modified: subversion/trunk/subversion/libsvn_fs_x/fs.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/fs.h?rev=1694502&r1=1694501&r2=1694502&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/fs.h (original)
+++ subversion/trunk/subversion/libsvn_fs_x/fs.h Thu Aug 6 14:04:55 2015
@@ -1,4 +1,4 @@
-/* fs.h : interface to Subversion filesystem, private to libsvn_fs
+/* fs.h : interface to Subversion filesystem
  *
  * ====================================================================
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -20,8 +20,8 @@
  * ====================================================================
  */
 
-#ifndef SVN_LIBSVN_FS_X_H
-#define SVN_LIBSVN_FS_X_H
+#ifndef SVN_LIBSVN_FS_X_FS_H
+#define SVN_LIBSVN_FS_X_FS_H
 
 #include <apr_pools.h>
 #include <apr_hash.h>
@@ -53,14 +53,14 @@ extern "C" {
 #define PATH_FORMAT "format" /* Contains format number */
 #define PATH_UUID "uuid" /* Contains UUID */
 #define PATH_CURRENT "current" /* Youngest revision */
+#define PATH_NEXT "next" /* Revision begin written. */
 #define PATH_LOCK_FILE "write-lock" /* Revision lock file */
 #define PATH_PACK_LOCK_FILE "pack-lock" /* Pack lock file */
 #define PATH_REVS_DIR "revs" /* Directory of revisions */
-#define PATH_REVPROPS_DIR "revprops" /* Directory of revprops */
 #define PATH_TXNS_DIR "transactions" /* Directory of transactions */
-#define PATH_NODE_ORIGINS_DIR "node-origins" /* Lazy node-origin cache */
 #define PATH_TXN_PROTOS_DIR "txn-protorevs" /* Directory of proto-revs */
 #define PATH_TXN_CURRENT "txn-current" /* File with next txn key */
+#define PATH_TXN_NEXT "txn-next" /* Will become txn-current */
 #define PATH_TXN_CURRENT_LOCK "txn-current-lock" /* Lock for txn-current */
 #define PATH_LOCKS_DIR "locks" /* Directory of locks */
 #define PATH_MIN_UNPACKED_REV "min-unpacked-rev" /* Oldest revision which
@@ -81,8 +81,6 @@ extern "C" {
 /* Names of special files and file extensions for transactions */
 #define PATH_CHANGES "changes" /* Records changes made so far */
 #define PATH_TXN_PROPS "props" /* Transaction properties */
-#define PATH_TXN_PROPS_FINAL "props-final" /* Final transaction properties
- before moving to revprops */
 #define PATH_NEXT_IDS "next-ids" /* Next temporary ID assignments */
 #define PATH_PREFIX_NODE "node." /* Prefix for node filename */
 #define PATH_EXT_TXN ".txn" /* Extension of txn dir */
@@ -124,7 +122,11 @@ extern "C" {
    Note: If you bump this, please update the switch statement in
          svn_fs_x__create() as well.
  */
-#define SVN_FS_X__FORMAT_NUMBER 1
+#define SVN_FS_X__FORMAT_NUMBER 2
+
+/* Latest experimental format number. Experimental formats are only
+ compatible with themselves. */
+#define SVN_FS_X__EXPERIMENTAL_FORMAT_NUMBER 2
 
 /* On most operating systems apr implements file locks per process, not
    per file. On Windows apr implements the locking as per file handle
@@ -179,11 +181,15 @@ typedef struct svn_fs_x__shared_data_t
      declaration here. Any subset may be acquired and held at any given
      time but their relative acquisition order must not change.
 
- (lock 'txn-current' before 'pack' before 'write' before 'txn-list') */
+ (lock 'pack' before 'write' before 'txn-current' before 'txn-list') */
 
   /* A lock for intra-process synchronization when accessing the TXNS list. */
   svn_mutex__t *txn_list_lock;
 
+ /* A lock for intra-process synchronization when locking the
+ txn-current file. */
+ svn_mutex__t *txn_current_lock;
+
   /* A lock for intra-process synchronization when grabbing the
      repository write lock. */
   svn_mutex__t *fs_write_lock;
@@ -192,10 +198,6 @@ typedef struct svn_fs_x__shared_data_t
      repository pack operation lock. */
   svn_mutex__t *fs_pack_lock;
 
- /* A lock for intra-process synchronization when locking the
- txn-current file. */
- svn_mutex__t *txn_current_lock;
-
   /* The common pool, under which this object is allocated, subpools
      of which are used to allocate the transaction objects. */
   apr_pool_t *common_pool;
@@ -281,13 +283,9 @@ typedef struct svn_fs_x__data_t
      e.g. memcached may be ignored as caching is an optional feature. */
   svn_boolean_t fail_stop;
 
- /* Caches native dag_node_t* instances and acts as a 1st level cache */
+ /* Caches native dag_node_t* instances */
   svn_fs_x__dag_cache_t *dag_node_cache;
 
- /* DAG node cache for immutable nodes. Maps (revision, fspath)
- to (dag_node_t *). This is the 2nd level cache for DAG nodes. */
- svn_cache__t *rev_node_cache;
-
   /* A cache of the contents of immutable directories; maps from
      unparsed FS ID to a apr_hash_t * mapping (const char *) dirent
      names to (svn_fs_x__dirent_t *). */
@@ -345,15 +343,6 @@ typedef struct svn_fs_x__data_t
      (revision, item index) pair */
   svn_cache__t *rep_header_cache;
 
- /* Cache for svn_mergeinfo_t objects; the key is a combination of
- revision, inheritance flags and path. */
- svn_cache__t *mergeinfo_cache;
-
- /* Cache for presence of svn_mergeinfo_t on a noderev; the key is a
- combination of revision, inheritance flags and path; value is "1"
- if the node has mergeinfo, "0" if it doesn't. */
- svn_cache__t *mergeinfo_existence_cache;
-
   /* Cache for l2p_header_t objects; the key is (revision, is-packed).
      Will be NULL for pre-format7 repos */
   svn_cache__t *l2p_header_cache;
@@ -420,6 +409,10 @@ typedef struct svn_fs_x__data_t
   /* Pointer to svn_fs_open. */
   svn_error_t *(*svn_fs_open_)(svn_fs_t **, const char *, apr_hash_t *,
                                apr_pool_t *, apr_pool_t *);
+
+ /* If not 0, this is a pre-allocated transaction ID that can just be
+ used for a new txn without needing to consult 'txn-current'. */
+ apr_uint64_t next_txn_id;
 } svn_fs_x__data_t;
 
 
@@ -571,4 +564,4 @@ typedef struct svn_fs_x__change_t
 }
 #endif /* __cplusplus */
 
-#endif /* SVN_LIBSVN_FS_X_H */
+#endif /* SVN_LIBSVN_FS_X_FS_H */

Modified: subversion/trunk/subversion/libsvn_fs_x/fs_x.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/fs_x.c?rev=1694502&r1=1694501&r2=1694502&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/fs_x.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/fs_x.c Thu Aug 6 14:04:55 2015
@@ -95,13 +95,28 @@ check_format(int format)
 {
   /* Put blacklisted versions here. */
 
- /* We support all formats from 1-current simultaneously */
- if (1 <= format && format <= SVN_FS_X__FORMAT_NUMBER)
+ /* We support any format if it matches the current format. */
+ if (format == SVN_FS_X__FORMAT_NUMBER)
+ return SVN_NO_ERROR;
+
+ /* Experimental formats are only supported if they match the current, but
+ * that case has already been handled. So, reject any experimental format.
+ */
+ if (SVN_FS_X__EXPERIMENTAL_FORMAT_NUMBER >= format)
+ return svn_error_createf(SVN_ERR_FS_UNSUPPORTED_FORMAT, NULL,
+ _("Unsupported experimental FSX format '%d' found; current format is '%d'"),
+ format, SVN_FS_X__FORMAT_NUMBER);
+ return SVN_NO_ERROR;
+
+ /* By default, we will support any non-experimental format released so far.
+ */
+ if (format <= SVN_FS_X__FORMAT_NUMBER)
     return SVN_NO_ERROR;
 
   return svn_error_createf(SVN_ERR_FS_UNSUPPORTED_FORMAT, NULL,
- _("Expected FS format between '1' and '%d'; found format '%d'"),
- SVN_FS_X__FORMAT_NUMBER, format);
+ _("Expected FSX format between '%d' and '%d'; found format '%d'"),
+ SVN_FS_X__EXPERIMENTAL_FORMAT_NUMBER + 1, SVN_FS_X__FORMAT_NUMBER,
+ format);
 }
 
 /* Read the format file at PATH and set *PFORMAT to the format version found
@@ -850,6 +865,7 @@ write_revision_zero(svn_fs_t *fs,
   apr_array_header_t *index_entries;
   svn_fs_x__p2l_entry_t *entry;
   svn_fs_x__revision_file_t *rev_file;
+ apr_file_t *apr_file;
   const char *l2p_proto_index, *p2l_proto_index;
 
   /* Construct a skeleton r0 with no indexes. */
@@ -896,15 +912,16 @@ write_revision_zero(svn_fs_t *fs,
 
   /* Now re-open r0, create proto-index files from our entries and
       rewrite the index section of r0. */
- SVN_ERR(svn_fs_x__open_pack_or_rev_file_writable(&rev_file, fs, 0,
- subpool, subpool));
+ SVN_ERR(svn_fs_x__rev_file_open_writable(&rev_file, fs, 0,
+ subpool, subpool));
   SVN_ERR(svn_fs_x__p2l_index_from_p2l_entries(&p2l_proto_index, fs,
                                                rev_file, index_entries,
                                                subpool, subpool));
   SVN_ERR(svn_fs_x__l2p_index_from_p2l_entries(&l2p_proto_index, fs,
                                                index_entries,
                                                subpool, subpool));
- SVN_ERR(svn_fs_x__add_index_data(fs, rev_file->file, l2p_proto_index,
+ SVN_ERR(svn_fs_x__rev_file_get(&apr_file, rev_file));
+ SVN_ERR(svn_fs_x__add_index_data(fs, apr_file, l2p_proto_index,
                                    p2l_proto_index, 0, subpool));
   SVN_ERR(svn_fs_x__close_revision_file(rev_file));
 
@@ -935,14 +952,9 @@ svn_fs_x__create_file_tree(svn_fs_t *fs,
 
   /* Create the revision data directories. */
   SVN_ERR(svn_io_make_dir_recursively(
- svn_fs_x__path_rev_shard(fs, 0, scratch_pool),
+ svn_fs_x__path_shard(fs, 0, scratch_pool),
                               scratch_pool));
 
- /* Create the revprops directory. */
- SVN_ERR(svn_io_make_dir_recursively(
- svn_fs_x__path_revprops_shard(fs, 0, scratch_pool),
- scratch_pool));
-
   /* Create the transaction directory. */
   SVN_ERR(svn_io_make_dir_recursively(
                                   svn_fs_x__path_txns_dir(fs, scratch_pool),
@@ -1213,8 +1225,11 @@ svn_fs_x__info_format(int *fs_format,
     {
     case 1:
       break;
+ case 2:
+ (*supports_version)->minor = 10;
+ break;
 #ifdef SVN_DEBUG
-# if SVN_FS_X__FORMAT_NUMBER != 1
+# if SVN_FS_X__FORMAT_NUMBER != 2
 # error "Need to add a 'case' statement here"
 # endif
 #endif
Received on 2015-08-07 02:26:24 CEST

This is an archived mail posted to the Subversion Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.