You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2015/10/26 09:43:08 UTC

svn commit: r1710531 [1/3] - in /subversion/branches/move-tracking-2: ./ build/ build/ac-macros/ subversion/ subversion/bindings/javahl/native/ subversion/bindings/javahl/src/org/apache/subversion/javahl/ subversion/bindings/swig/ subversion/bindings/s...

Author: julianfoad
Date: Mon Oct 26 08:43:06 2015
New Revision: 1710531

URL: http://svn.apache.org/viewvc?rev=1710531&view=rev
Log:
On the 'move-tracking-2' branch: catch up to trunk@1710529.

Added:
    subversion/branches/move-tracking-2/subversion/bindings/javahl/native/org_apache_subversion_javahl_NativeResources.cpp
      - copied unchanged from r1710529, subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_NativeResources.cpp
Modified:
    subversion/branches/move-tracking-2/   (props changed)
    subversion/branches/move-tracking-2/build/   (props changed)
    subversion/branches/move-tracking-2/build/ac-macros/apache.m4
    subversion/branches/move-tracking-2/subversion/   (props changed)
    subversion/branches/move-tracking-2/subversion/bindings/javahl/native/SVNClient.cpp
    subversion/branches/move-tracking-2/subversion/bindings/javahl/src/org/apache/subversion/javahl/NativeResources.java
    subversion/branches/move-tracking-2/subversion/bindings/swig/core.i
    subversion/branches/move-tracking-2/subversion/bindings/swig/python/tests/run_all.py
    subversion/branches/move-tracking-2/subversion/include/private/svn_atomic.h
    subversion/branches/move-tracking-2/subversion/include/private/svn_ra_svn_private.h
    subversion/branches/move-tracking-2/subversion/include/private/svn_string_private.h
    subversion/branches/move-tracking-2/subversion/include/svn_client.h
    subversion/branches/move-tracking-2/subversion/include/svn_io.h
    subversion/branches/move-tracking-2/subversion/libsvn_fs/fs-loader.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs/fs-loader.h
    subversion/branches/move-tracking-2/subversion/libsvn_fs_base/fs.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/caching.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.h
    subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs_fs.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/revprops.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/tree.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/   (props changed)
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/cached_data.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs.h
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs_x.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs_x.h
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/hotcopy.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/hotcopy.h
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/index.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/lock.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/low_level.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/low_level.h
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/pack.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/reps.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/rev_file.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/revprops.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/temp_serializer.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/temp_serializer.h
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/transaction.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/util.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/verify.c
    subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/client.c
    subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/cyrus_auth.c
    subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/deprecated.c
    subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/editorp.c
    subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/internal_auth.c
    subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/marshal.c
    subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/ra_svn.h
    subversion/branches/move-tracking-2/subversion/libsvn_repos/log.c
    subversion/branches/move-tracking-2/subversion/libsvn_subr/atomic.c
    subversion/branches/move-tracking-2/subversion/libsvn_subr/deprecated.c
    subversion/branches/move-tracking-2/subversion/libsvn_subr/path.c
    subversion/branches/move-tracking-2/subversion/libsvn_subr/sqlite.c
    subversion/branches/move-tracking-2/subversion/libsvn_subr/stream.c
    subversion/branches/move-tracking-2/subversion/libsvn_wc/old-and-busted.c
    subversion/branches/move-tracking-2/subversion/libsvn_wc/props.c
    subversion/branches/move-tracking-2/subversion/libsvn_wc/wc-queries.sql
    subversion/branches/move-tracking-2/subversion/mod_dav_svn/merge.c
    subversion/branches/move-tracking-2/subversion/mod_dav_svn/repos.c
    subversion/branches/move-tracking-2/subversion/mod_dav_svn/status.c
    subversion/branches/move-tracking-2/subversion/po/it.po
    subversion/branches/move-tracking-2/subversion/po/ja.po
    subversion/branches/move-tracking-2/subversion/po/ko.po
    subversion/branches/move-tracking-2/subversion/po/zh_TW.po
    subversion/branches/move-tracking-2/subversion/svnbench/null-log-cmd.c
    subversion/branches/move-tracking-2/subversion/svnserve/serve.c
    subversion/branches/move-tracking-2/subversion/tests/cmdline/davautocheck.sh
    subversion/branches/move-tracking-2/subversion/tests/cmdline/svntest/main.py
    subversion/branches/move-tracking-2/subversion/tests/libsvn_fs/fs-test.c
    subversion/branches/move-tracking-2/subversion/tests/svn_test_fs.c
    subversion/branches/move-tracking-2/tools/   (props changed)
    subversion/branches/move-tracking-2/tools/dev/x509-parser.c
    subversion/branches/move-tracking-2/win-tests.py   (contents, props changed)

Propchange: subversion/branches/move-tracking-2/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Oct 26 08:43:06 2015
@@ -94,4 +94,4 @@
 /subversion/branches/verify-at-commit:1462039-1462408
 /subversion/branches/verify-keep-going:1439280-1546110
 /subversion/branches/wc-collate-path:1402685-1480384
-/subversion/trunk:1606692-1709537
+/subversion/trunk:1606692-1710529

Propchange: subversion/branches/move-tracking-2/build/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Oct 26 08:43:06 2015
@@ -82,4 +82,4 @@
 /subversion/branches/verify-at-commit/build:1462039-1462408
 /subversion/branches/verify-keep-going/build:1439280-1546110
 /subversion/branches/wc-collate-path/build:1402685-1480384
-/subversion/trunk/build:1606692-1706962
+/subversion/trunk/build:1606692-1710529

Modified: subversion/branches/move-tracking-2/build/ac-macros/apache.m4
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/build/ac-macros/apache.m4?rev=1710531&r1=1710530&r2=1710531&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/build/ac-macros/apache.m4 (original)
+++ subversion/branches/move-tracking-2/build/ac-macros/apache.m4 Mon Oct 26 08:43:06 2015
@@ -46,7 +46,7 @@ AC_ARG_WITH(apxs,
 ])
 
 if test -z "$APXS"; then
-  for i in /usr/sbin /usr/local/apache/bin /usr/local/apache2/bin /usr/bin ; do
+  for i in /usr/local/apache2/bin /usr/local/apache/bin /usr/bin /usr/sbin ; do
     if test -f "$i/apxs2"; then
       APXS="$i/apxs2"
       break

Propchange: subversion/branches/move-tracking-2/subversion/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Oct 26 08:43:06 2015
@@ -82,4 +82,4 @@
 /subversion/branches/verify-at-commit/subversion:1462039-1462408
 /subversion/branches/verify-keep-going/subversion:1439280-1546110
 /subversion/branches/wc-collate-path/subversion:1402685-1480384
-/subversion/trunk/subversion:1606692-1709537
+/subversion/trunk/subversion:1606692-1710529

Modified: subversion/branches/move-tracking-2/subversion/bindings/javahl/native/SVNClient.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/bindings/javahl/native/SVNClient.cpp?rev=1710531&r1=1710530&r2=1710531&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/bindings/javahl/native/SVNClient.cpp (original)
+++ subversion/branches/move-tracking-2/subversion/bindings/javahl/native/SVNClient.cpp Mon Oct 26 08:43:06 2015
@@ -1564,7 +1564,10 @@ void SVNClient::vacuum(const char *path,
     if (ctx == NULL)
         return;
 
-    SVN_JNI_ERR(svn_client_vacuum(path,
+    Path checkedPath(path, subPool);
+    SVN_JNI_ERR(checkedPath.error_occurred(),);
+
+    SVN_JNI_ERR(svn_client_vacuum(checkedPath.c_str(),
                                   remove_unversioned_items,
                                   remove_ignored_items,
                                   fix_recorded_timestamps,

Modified: subversion/branches/move-tracking-2/subversion/bindings/javahl/src/org/apache/subversion/javahl/NativeResources.java
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/bindings/javahl/src/org/apache/subversion/javahl/NativeResources.java?rev=1710531&r1=1710530&r2=1710531&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/bindings/javahl/src/org/apache/subversion/javahl/NativeResources.java (original)
+++ subversion/branches/move-tracking-2/subversion/bindings/javahl/src/org/apache/subversion/javahl/NativeResources.java Mon Oct 26 08:43:06 2015
@@ -141,6 +141,7 @@ public class NativeResources
      */
     private static final void init()
     {
+        initNativeLibrary();
         version = new Version();
         if (!version.isAtLeast(1, 10, 0))
         {
@@ -158,4 +159,11 @@ public class NativeResources
                 " but the run-time version is " + runtimeVersion);
         }
     }
+
+    /**
+     * Initialize the native library layer.
+     * @note This is a no-op in 1.9+, but we need it for ABI
+     *       compatibility with older versions of the native library.
+     */
+    private static native void initNativeLibrary();
 }

Modified: subversion/branches/move-tracking-2/subversion/bindings/swig/core.i
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/bindings/swig/core.i?rev=1710531&r1=1710530&r2=1710531&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/bindings/swig/core.i (original)
+++ subversion/branches/move-tracking-2/subversion/bindings/swig/core.i Mon Oct 26 08:43:06 2015
@@ -838,6 +838,7 @@ core_set_current_pool (apr_pool_t *pool)
 %include svn_mergeinfo_h.swg
 %include svn_io_h.swg
 %include svn_checksum_h.swg
+%include svn_cache_config_h.swg
 
 
 

Modified: subversion/branches/move-tracking-2/subversion/bindings/swig/python/tests/run_all.py
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/bindings/swig/python/tests/run_all.py?rev=1710531&r1=1710530&r2=1710531&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/bindings/swig/python/tests/run_all.py (original)
+++ subversion/branches/move-tracking-2/subversion/bindings/swig/python/tests/run_all.py Mon Oct 26 08:43:06 2015
@@ -21,11 +21,15 @@
 import unittest, setup_path
 import mergeinfo, core, client, delta, checksum, pool, ra, wc, repository, \
        auth, trac.versioncontrol.tests
+from svn.core import svn_cache_config_get, svn_cache_config_set
 
 # Run all tests
 
 def suite():
   """Run all tests"""
+  settings = svn_cache_config_get()
+  settings.cache_size = long(1024*1024*32) ### Need explicit long
+  svn_cache_config_set(settings)
   s = unittest.TestSuite()
   s.addTest(core.suite())
   s.addTest(checksum.suite())

Modified: subversion/branches/move-tracking-2/subversion/include/private/svn_atomic.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/private/svn_atomic.h?rev=1710531&r1=1710530&r2=1710531&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/private/svn_atomic.h (original)
+++ subversion/branches/move-tracking-2/subversion/include/private/svn_atomic.h Mon Oct 26 08:43:06 2015
@@ -134,6 +134,21 @@ svn_atomic__init_once_no_error(volatile
                                svn_atomic__str_init_func_t str_init_func,
                                void *baton);
 
+
+/**
+ * Query and increment the global counter and set @a value to the new
+ * counter value.
+ *
+ * This function is thread-safe and you should call it whenever you need
+ * a number that is unique within the current process. The values are > 0.
+ *
+ * @return the error object in case of a synchronization failure.
+ *
+ * @since New in 1.10.
+ */
+svn_error_t *
+svn_atomic__unique_counter(apr_uint64_t* value);
+
 /** @} */
 
 #ifdef __cplusplus

Modified: subversion/branches/move-tracking-2/subversion/include/private/svn_ra_svn_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/private/svn_ra_svn_private.h?rev=1710531&r1=1710530&r2=1710531&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/private/svn_ra_svn_private.h (original)
+++ subversion/branches/move-tracking-2/subversion/include/private/svn_ra_svn_private.h Mon Oct 26 08:43:06 2015
@@ -60,7 +60,7 @@ struct svn_ra_svn__item_t
   union {
     apr_uint64_t number;
     svn_string_t string;
-    const char *word;
+    svn_string_t word;
     svn_ra_svn__list_t list;
   } u;
 };
@@ -320,7 +320,6 @@ svn_ra_svn__skip_leading_garbage(svn_ra_
  */
 svn_error_t *
 svn_ra_svn__parse_tuple(const svn_ra_svn__list_t *list,
-                        apr_pool_t *pool,
                         const char *fmt, ...);
 
 /** Read a tuple from the network and parse it as a tuple, using the

Modified: subversion/branches/move-tracking-2/subversion/include/private/svn_string_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/private/svn_string_private.h?rev=1710531&r1=1710530&r2=1710531&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/private/svn_string_private.h (original)
+++ subversion/branches/move-tracking-2/subversion/include/private/svn_string_private.h Mon Oct 26 08:43:06 2015
@@ -131,6 +131,14 @@ svn_membuf__nzero(svn_membuf_t *membuf,
 svn_string_t *
 svn_stringbuf__morph_into_string(svn_stringbuf_t *strbuf);
 
+/** Utility macro to define static svn_string_t objects.  @a value must
+ * be a static string; the "" in the macro declaration tries to ensure this.
+ *
+ * Usage:
+ * static const svn_string_t my_string = SVN__STATIC_STRING("my text");
+ */
+#define SVN__STATIC_STRING(value) { value "", sizeof(value "") - 1 }
+
 /** Like strtoul but with a fixed base of 10 and without overflow checks.
  * This allows the compiler to generate massively faster (4x on 64bit LINUX)
  * code.  Overflow checks may be added on the caller side where you might

Modified: subversion/branches/move-tracking-2/subversion/include/svn_client.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/svn_client.h?rev=1710531&r1=1710530&r2=1710531&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/svn_client.h (original)
+++ subversion/branches/move-tracking-2/subversion/include/svn_client.h Mon Oct 26 08:43:06 2015
@@ -4098,16 +4098,16 @@ svn_client_mergeinfo_log_eligible(const
  * @{
  */
 
-/** Recursively vacuum a working copy directory @a dir, removing unnecessary
- * data.
+/** Recursively vacuum a working copy directory @a dir_abspath,
+ * removing unnecessary data.
  *
  * If @a include_externals is @c TRUE, recurse into externals and vacuum them
  * as well.
  *
  * If @a remove_unversioned_items is @c TRUE, remove unversioned items
- * in @a dir after successful working copy cleanup.
+ * in @a dir_abspath after successful working copy cleanup.
  * If @a remove_ignored_items is @c TRUE, remove ignored unversioned items
- * in @a dir after successful working copy cleanup.
+ * in @a dir_abspath after successful working copy cleanup.
  *
  * If @a fix_recorded_timestamps is @c TRUE, this function fixes recorded
  * timestamps for unmodified files in the working copy, reducing comparision

Modified: subversion/branches/move-tracking-2/subversion/include/svn_io.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/svn_io.h?rev=1710531&r1=1710530&r2=1710531&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/svn_io.h (original)
+++ subversion/branches/move-tracking-2/subversion/include/svn_io.h Mon Oct 26 08:43:06 2015
@@ -1147,16 +1147,27 @@ svn_error_t *
 svn_stream_for_stdout(svn_stream_t **out,
                       apr_pool_t *pool);
 
-/** Set @a *str to a string buffer allocated in @a result_pool that contains
- * all data from the current position in @a stream to its end.  @a len_hint
- * specifies the initial capacity of the string buffer and may be 0.  The
- * buffer gets automatically resized to fit the actual amount of data being
- * read from @a stream.
+/** Read the contents of @a stream into memory, from its current position
+ * to its end, returning the data in @a *result. The stream will be closed
+ * when it has been successfully and completely read.
+ *
+ * @a len_hint gives a hint about the expected length, in bytes, of the
+ * actual data that will be read from the stream. It may be 0, meaning no
+ * hint is being provided. Efficiency in time and/or in space may be
+ * better (and in general will not be worse) when the actual data length
+ * is equal or approximately equal to the length hint.
+ *
+ * The returned memory is allocated in @a result_pool.
+ *
+ * @note The present implementation is efficient when @a len_hint is big
+ * enough (but not vastly bigger than necessary), and also for actual
+ * lengths up to 64 bytes when @a len_hint is 0. Otherwise it can incur
+ * significant time and space overheads. See source code for details.
  *
  * @since New in 1.9.
  */
 svn_error_t *
-svn_stringbuf_from_stream(svn_stringbuf_t **str,
+svn_stringbuf_from_stream(svn_stringbuf_t **result,
                           svn_stream_t *stream,
                           apr_size_t len_hint,
                           apr_pool_t *result_pool);
@@ -1520,25 +1531,44 @@ svn_stream_contents_same(svn_boolean_t *
                          apr_pool_t *pool);
 
 
-/** Read the contents of @a stream into memory, returning the data in
- * @a result. The stream will be closed when it has been successfully and
- * completely read.
+/** Read the contents of @a stream into memory, from its current position
+ * to its end, returning the data in @a *result. The stream will be closed
+ * when it has been successfully and completely read.
+ *
+ * @a len_hint gives a hint about the expected length, in bytes, of the
+ * actual data that will be read from the stream. It may be 0, meaning no
+ * hint is being provided. Efficiency in time and/or in space may be
+ * better (and in general will not be worse) when the actual data length
+ * is equal or approximately equal to the length hint.
  *
  * The returned memory is allocated in @a result_pool, and any temporary
- * allocations are performed in @a scratch_pool.
+ * allocations may be performed in @a scratch_pool.
  *
- * @note due to memory pseudo-reallocation behavior (due to pools), this
- *   can be a memory-intensive operation for large files.
+ * @note The present implementation is efficient when @a len_hint is big
+ * enough (but not vastly bigger than necessary), and also for actual
+ * lengths up to 64 bytes when @a len_hint is 0. Otherwise it can incur
+ * significant time and space overheads. See source code for details.
  *
- * @since New in 1.6
+ * @since New in 1.10
  */
 svn_error_t *
+svn_string_from_stream2(svn_string_t **result,
+                        svn_stream_t *stream,
+                        apr_size_t len_hint,
+                        apr_pool_t *result_pool);
+
+/** Similar to svn_string_from_stream2(), but always passes 0 for
+ * @a len_hint.
+ *
+ * @deprecated Provided for backwards compatibility with the 1.9 API.
+ */
+SVN_DEPRECATED
+svn_error_t *
 svn_string_from_stream(svn_string_t **result,
                        svn_stream_t *stream,
                        apr_pool_t *result_pool,
                        apr_pool_t *scratch_pool);
 
-
 /** A function type provided for use as a callback from
  * @c svn_stream_lazyopen_create().
  *

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs/fs-loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs/fs-loader.c?rev=1710531&r1=1710530&r2=1710531&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs/fs-loader.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs/fs-loader.c Mon Oct 26 08:43:06 2015
@@ -510,22 +510,25 @@ svn_fs_create(svn_fs_t **fs_p, const cha
               apr_pool_t *pool)
 {
   fs_library_vtable_t *vtable;
+  apr_pool_t *scratch_pool = svn_pool_create(pool);
 
   const char *fs_type = svn_hash__get_cstring(fs_config,
                                               SVN_FS_CONFIG_FS_TYPE,
                                               DEFAULT_FS_TYPE);
-  SVN_ERR(get_library_vtable(&vtable, fs_type, pool));
+  SVN_ERR(get_library_vtable(&vtable, fs_type, scratch_pool));
 
   /* Create the FS directory and write out the fsap-name file. */
-  SVN_ERR(svn_io_dir_make_sgid(path, APR_OS_DEFAULT, pool));
-  SVN_ERR(write_fs_type(path, fs_type, pool));
+  SVN_ERR(svn_io_dir_make_sgid(path, APR_OS_DEFAULT, scratch_pool));
+  SVN_ERR(write_fs_type(path, fs_type, scratch_pool));
 
   /* Perform the actual creation. */
   *fs_p = fs_new(fs_config, pool);
 
-  SVN_ERR(vtable->create(*fs_p, path, common_pool_lock, pool, common_pool));
+  SVN_ERR(vtable->create(*fs_p, path, common_pool_lock, scratch_pool,
+                         common_pool));
   SVN_ERR(vtable->set_svn_fs_open(*fs_p, svn_fs_open2));
 
+  svn_pool_destroy(scratch_pool);
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs/fs-loader.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs/fs-loader.h?rev=1710531&r1=1710530&r2=1710531&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs/fs-loader.h (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs/fs-loader.h Mon Oct 26 08:43:06 2015
@@ -79,11 +79,11 @@ typedef struct fs_library_vtable_t
      parameter for allocating fs-global objects such as an env cache. */
   svn_error_t *(*create)(svn_fs_t *fs, const char *path,
                          svn_mutex__t *common_pool_lock,
-                         apr_pool_t *pool,
+                         apr_pool_t *scratch_pool,
                          apr_pool_t *common_pool);
   svn_error_t *(*open_fs)(svn_fs_t *fs, const char *path,
                           svn_mutex__t *common_pool_lock,
-                          apr_pool_t *pool,
+                          apr_pool_t *scratch_pool,
                           apr_pool_t *common_pool);
   /* open_for_recovery() is like open(), but used to fill in an fs pointer
      that will be passed to recover().  We assume that the open() method

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_base/fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_base/fs.c?rev=1710531&r1=1710530&r2=1710531&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_base/fs.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_base/fs.c Mon Oct 26 08:43:06 2015
@@ -580,13 +580,12 @@ static fs_vtable_t fs_vtable = {
 #define FORMAT_FILE   "format"
 
 /* Depending on CREATE, create or open the environment and databases
-   for filesystem FS in PATH. Use POOL for temporary allocations. */
+   for filesystem FS in PATH. */
 static svn_error_t *
 open_databases(svn_fs_t *fs,
                svn_boolean_t create,
                int format,
-               const char *path,
-               apr_pool_t *pool)
+               const char *path)
 {
   base_fs_data_t *bfd;
 
@@ -740,7 +739,7 @@ static svn_error_t *
 base_create(svn_fs_t *fs,
             const char *path,
             svn_mutex__t *common_pool_lock,
-            apr_pool_t *pool,
+            apr_pool_t *scratch_pool,
             apr_pool_t *common_pool)
 {
   int format = SVN_FS_BASE__FORMAT_NUMBER;
@@ -751,7 +750,7 @@ base_create(svn_fs_t *fs,
     {
       svn_version_t *compatible_version;
       SVN_ERR(svn_fs__compatible_version(&compatible_version, fs->config,
-                                         pool));
+                                         scratch_pool));
 
       /* select format number */
       switch(compatible_version->minor)
@@ -773,7 +772,7 @@ base_create(svn_fs_t *fs,
     }
 
   /* Create the environment and databases. */
-  svn_err = open_databases(fs, TRUE, format, path, pool);
+  svn_err = open_databases(fs, TRUE, format, path);
   if (svn_err) goto error;
 
   /* Initialize the DAG subsystem. */
@@ -781,13 +780,14 @@ base_create(svn_fs_t *fs,
   if (svn_err) goto error;
 
   /* This filesystem is ready.  Stamp it with a format number. */
-  svn_err = svn_io_write_version_file(
-   svn_dirent_join(fs->path, FORMAT_FILE, pool), format, pool);
+  svn_err = svn_io_write_version_file(svn_dirent_join(fs->path, FORMAT_FILE,
+                                                      scratch_pool),
+                                      format, scratch_pool);
   if (svn_err) goto error;
 
   ((base_fs_data_t *) fs->fsap_data)->format = format;
 
-  SVN_ERR(populate_opened_fs(fs, pool));
+  SVN_ERR(populate_opened_fs(fs, scratch_pool));
   return SVN_NO_ERROR;
 
 error:
@@ -834,7 +834,7 @@ static svn_error_t *
 base_open(svn_fs_t *fs,
           const char *path,
           svn_mutex__t *common_pool_lock,
-          apr_pool_t *pool,
+          apr_pool_t *scratch_pool,
           apr_pool_t *common_pool)
 {
   int format;
@@ -843,8 +843,9 @@ base_open(svn_fs_t *fs,
 
   /* Read the FS format number. */
   svn_err = svn_io_read_version_file(&format,
-                                     svn_dirent_join(path, FORMAT_FILE, pool),
-                                     pool);
+                                     svn_dirent_join(path, FORMAT_FILE,
+                                                     scratch_pool),
+                                     scratch_pool);
   if (svn_err && APR_STATUS_IS_ENOENT(svn_err->apr_err))
     {
       /* Pre-1.2 filesystems did not have a format file (you could say
@@ -860,7 +861,7 @@ base_open(svn_fs_t *fs,
     goto error;
 
   /* Create the environment and databases. */
-  svn_err = open_databases(fs, FALSE, format, path, pool);
+  svn_err = open_databases(fs, FALSE, format, path);
   if (svn_err) goto error;
 
   ((base_fs_data_t *) fs->fsap_data)->format = format;
@@ -870,12 +871,12 @@ base_open(svn_fs_t *fs,
   if (write_format_file)
     {
       svn_err = svn_io_write_version_file(svn_dirent_join(path, FORMAT_FILE,
-                                                        pool),
-                                          format, pool);
+                                                        scratch_pool),
+                                          format, scratch_pool);
       if (svn_err) goto error;
     }
 
-  SVN_ERR(populate_opened_fs(fs, pool));
+  SVN_ERR(populate_opened_fs(fs, scratch_pool));
   return SVN_NO_ERROR;
 
  error:

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/caching.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/caching.c?rev=1710531&r1=1710530&r2=1710531&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/caching.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/caching.c Mon Oct 26 08:43:06 2015
@@ -513,7 +513,7 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
                        0, 0, /* Do not use inprocess cache */
                        svn_fs_fs__serialize_revprops,
                        svn_fs_fs__deserialize_revprops,
-                       APR_HASH_KEY_STRING,
+                       sizeof(pair_cache_key_t),
                        apr_pstrcat(pool, prefix, "REVPROP", SVN_VA_NULL),
                        SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
                        TRUE, /* contents is short-lived */

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.c?rev=1710531&r1=1710530&r2=1710531&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.c Mon Oct 26 08:43:06 2015
@@ -291,7 +291,7 @@ initialize_fs_struct(svn_fs_t *fs)
 {
   fs_fs_data_t *ffd = apr_pcalloc(fs->pool, sizeof(*ffd));
   ffd->use_log_addressing = FALSE;
-  ffd->revprop_prefix = svn_stringbuf_create_empty(fs->pool);
+  ffd->revprop_prefix = 0;
 
   fs->vtable = &fs_vtable;
   fs->fsap_data = ffd;
@@ -315,18 +315,18 @@ static svn_error_t *
 fs_create(svn_fs_t *fs,
           const char *path,
           svn_mutex__t *common_pool_lock,
-          apr_pool_t *pool,
+          apr_pool_t *scratch_pool,
           apr_pool_t *common_pool)
 {
   SVN_ERR(svn_fs__check_fs(fs, FALSE));
 
   SVN_ERR(initialize_fs_struct(fs));
 
-  SVN_ERR(svn_fs_fs__create(fs, path, pool));
+  SVN_ERR(svn_fs_fs__create(fs, path, scratch_pool));
 
-  SVN_ERR(svn_fs_fs__initialize_caches(fs, pool));
+  SVN_ERR(svn_fs_fs__initialize_caches(fs, scratch_pool));
   SVN_MUTEX__WITH_LOCK(common_pool_lock,
-                       fs_serialized_init(fs, common_pool, pool));
+                       fs_serialized_init(fs, common_pool, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -344,10 +344,10 @@ static svn_error_t *
 fs_open(svn_fs_t *fs,
         const char *path,
         svn_mutex__t *common_pool_lock,
-        apr_pool_t *pool,
+        apr_pool_t *scratch_pool,
         apr_pool_t *common_pool)
 {
-  apr_pool_t *subpool = svn_pool_create(pool);
+  apr_pool_t *subpool = svn_pool_create(scratch_pool);
 
   SVN_ERR(svn_fs__check_fs(fs, FALSE));
 

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.h?rev=1710531&r1=1710530&r2=1710531&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.h (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.h Mon Oct 26 08:43:06 2015
@@ -352,8 +352,8 @@ typedef struct fs_fs_data_t
   svn_cache__t *fulltext_cache;
 
   /* The current prefix to be used for revprop cache entries.
-     If this string is empty, a new unique prefix must be chosen. */
-  svn_stringbuf_t *revprop_prefix;
+     If this is 0, a new unique prefix must be chosen. */
+  apr_uint64_t revprop_prefix;
 
   /* Revision property cache.  Maps from (rev,prefix) to apr_hash_t.
      Unparsed svn_string_t representations of the serialized hash

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs_fs.c?rev=1710531&r1=1710530&r2=1710531&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs_fs.c Mon Oct 26 08:43:06 2015
@@ -754,8 +754,8 @@ read_config(fs_fs_data_t *ffd,
                                    CONFIG_SECTION_PACKED_REVPROPS,
                                    CONFIG_OPTION_REVPROP_PACK_SIZE,
                                    ffd->compress_packed_revprops
-                                       ? 0x10
-                                       : 0x4));
+                                       ? 0x40
+                                       : 0x10));
 
       ffd->revprop_pack_size *= 1024;
     }
@@ -962,9 +962,9 @@ write_config(svn_fs_t *fs,
 "### latency and CPU usage reading and changing individual revprops."        NL
 "### Values smaller than 4 kByte will not improve latency any further and "  NL
 "### quickly render revprop packing ineffective."                            NL
-"### revprop-pack-size is 4 kBytes by default for non-compressed revprop"    NL
-"### pack files and 16 kBytes when compression has been enabled."            NL
-"# " CONFIG_OPTION_REVPROP_PACK_SIZE " = 4"                                  NL
+"### revprop-pack-size is 16 kBytes by default for non-compressed revprop"   NL
+"### pack files and 64 kBytes when compression has been enabled."            NL
+"# " CONFIG_OPTION_REVPROP_PACK_SIZE " = 16"                                 NL
 "###"                                                                        NL
 "### To save disk space, packed revprop files may be compressed.  Standard"  NL
 "### revprops tend to allow for very effective compression.  Reading and"    NL

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/revprops.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/revprops.c?rev=1710531&r1=1710530&r2=1710531&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/revprops.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/revprops.c Mon Oct 26 08:43:06 2015
@@ -209,19 +209,21 @@ void
 svn_fs_fs__reset_revprop_cache(svn_fs_t *fs)
 {
   fs_fs_data_t *ffd = fs->fsap_data;
-  svn_stringbuf_setempty(ffd->revprop_prefix);
+  ffd->revprop_prefix = 0;
 }
 
 /* If FS has not a revprop cache prefix set, generate one.
  * Always call this before accessing the revprop cache.
  */
-static void
+static svn_error_t *
 prepare_revprop_cache(svn_fs_t *fs,
                       apr_pool_t *scratch_pool)
 {
   fs_fs_data_t *ffd = fs->fsap_data;
-  if (svn_stringbuf_isempty(ffd->revprop_prefix))
-    svn_stringbuf_set(ffd->revprop_prefix, svn_uuid_generate(scratch_pool));
+  if (!ffd->revprop_prefix)
+    SVN_ERR(svn_atomic__unique_counter(&ffd->revprop_prefix));
+
+  return SVN_NO_ERROR;
 }
 
 /* Store the unparsed revprop hash CONTENT for REVISION in FS's revprop
@@ -233,15 +235,14 @@ cache_revprops(svn_fs_t *fs,
                apr_pool_t *scratch_pool)
 {
   fs_fs_data_t *ffd = fs->fsap_data;
-  const char *key;
+  pair_cache_key_t key;
 
   /* Make sure prepare_revprop_cache() has been called. */
-  SVN_ERR_ASSERT(!svn_stringbuf_isempty(ffd->revprop_prefix));
-  key = svn_fs_fs__combine_number_and_string(revision,
-                                             ffd->revprop_prefix->data,
-                                             scratch_pool);
+  SVN_ERR_ASSERT(ffd->revprop_prefix);
+  key.revision = revision;
+  key.second = ffd->revprop_prefix;
 
-  SVN_ERR(svn_cache__set(ffd->revprop_cache, key, content, scratch_pool));
+  SVN_ERR(svn_cache__set(ffd->revprop_cache, &key, content, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -666,17 +667,16 @@ svn_fs_fs__get_revision_proplist(apr_has
     {
       /* Try cache lookup first. */
       svn_boolean_t is_cached;
-      const char *key;
+      pair_cache_key_t key;
 
       /* Auto-alloc prefix and construct the key. */
-      prepare_revprop_cache(fs, scratch_pool);
-      key = svn_fs_fs__combine_number_and_string(rev,
-                                                 ffd->revprop_prefix->data,
-                                                 scratch_pool);
+      SVN_ERR(prepare_revprop_cache(fs, scratch_pool));
+      key.revision = rev;
+      key.second = ffd->revprop_prefix;
 
       /* The only way that this might error out is due to parser error. */
       SVN_ERR_W(svn_cache__get((void **) proplist_p, &is_cached,
-                               ffd->revprop_cache, key, result_pool),
+                               ffd->revprop_cache, &key, result_pool),
                 apr_psprintf(scratch_pool,
                              "Failed to parse revprops for r%ld.",
                              rev));

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/tree.c?rev=1710531&r1=1710530&r2=1710531&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/tree.c Mon Oct 26 08:43:06 2015
@@ -209,17 +209,15 @@ auto_clear_dag_cache(fs_fs_dag_cache_t*
     }
 }
 
-/* For the given REVISION and PATH, return the respective entry in CACHE.
-   If the entry is empty, its NODE member will be NULL and the caller
-   may then set it to the corresponding DAG node allocated in CACHE->POOL.
+/* Returns a 32 bit hash value for the given REVISION and PATH of exactly
+ * PATH_LEN chars.
  */
-static cache_entry_t *
-cache_lookup( fs_fs_dag_cache_t *cache
-            , svn_revnum_t revision
-            , const char *path)
+static apr_uint32_t
+hash_func(svn_revnum_t revision,
+          const char *path,
+          apr_size_t path_len)
 {
-  apr_size_t i, bucket_index;
-  apr_size_t path_len = strlen(path);
+  apr_size_t i;
   apr_uint32_t hash_value = (apr_uint32_t)revision;
 
 #if SVN_UNALIGNED_ACCESS_IS_OK
@@ -227,20 +225,7 @@ cache_lookup( fs_fs_dag_cache_t *cache
   const apr_uint32_t factor = 0xd1f3da69;
 #endif
 
-  /* optimistic lookup: hit the same bucket again? */
-  cache_entry_t *result = &cache->buckets[cache->last_hit];
-  if (   (result->revision == revision)
-      && (result->path_len == path_len)
-      && !memcmp(result->path, path, path_len))
-    {
-      /* Remember the position of the last node we found in this cache. */
-      if (result->node)
-        cache->last_non_empty = cache->last_hit;
-
-      return result;
-    }
-
-  /* need to do a full lookup.  Calculate the hash value
+  /* Calculate the hash value
      (HASH_VALUE has been initialized to REVISION).
 
      Note that the actual hash function is arbitrary as long as its result
@@ -283,6 +268,37 @@ cache_lookup( fs_fs_dag_cache_t *cache
      */
     hash_value = hash_value * 32 + (hash_value + (unsigned char)path[i]);
 
+  return hash_value;
+}
+
+/* For the given REVISION and PATH, return the respective node found in
+ * CACHE.  If there is none, return NULL.
+ */
+static dag_node_t *
+cache_lookup( fs_fs_dag_cache_t *cache
+            , svn_revnum_t revision
+            , const char *path)
+{
+  apr_size_t bucket_index;
+  apr_size_t path_len = strlen(path);
+  apr_uint32_t hash_value;
+
+  /* optimistic lookup: hit the same bucket again? */
+  cache_entry_t *result = &cache->buckets[cache->last_hit];
+  if (   (result->revision == revision)
+      && (result->path_len == path_len)
+      && !memcmp(result->path, path, path_len))
+    {
+      /* Remember the position of the last node we found in this cache. */
+      if (result->node)
+        cache->last_non_empty = cache->last_hit;
+
+      return result->node;
+    }
+
+  /* need to do a full lookup. */
+  hash_value = hash_func(revision, path, path_len);
+
   bucket_index = hash_value + (hash_value >> 16);
   bucket_index = (bucket_index + (bucket_index >> 8)) % BUCKET_COUNT;
 
@@ -297,16 +313,7 @@ cache_lookup( fs_fs_dag_cache_t *cache
       || (result->path_len != path_len)
       || memcmp(result->path, path, path_len))
     {
-      result->hash_value = hash_value;
-      result->revision = revision;
-      if (result->path_len < path_len)
-        result->path = apr_palloc(cache->pool, path_len + 1);
-      result->path_len = path_len;
-      memcpy(result->path, path, path_len + 1);
-
-      result->node = NULL;
-
-      cache->insertions++;
+      return NULL;
     }
   else if (result->node)
     {
@@ -315,7 +322,46 @@ cache_lookup( fs_fs_dag_cache_t *cache
       cache->last_non_empty = bucket_index;
     }
 
-  return result;
+  return result->node;
+}
+
+/* Store a copy of NODE in CACHE, taking  REVISION and PATH as key.
+ * This function will clean the cache at regular intervals.
+ */
+static void
+cache_insert(fs_fs_dag_cache_t *cache,
+             svn_revnum_t revision,
+             const char *path,
+             dag_node_t *node)
+{
+  apr_size_t bucket_index;
+  apr_size_t path_len = strlen(path);
+  apr_uint32_t hash_value;
+  cache_entry_t *entry;
+
+  auto_clear_dag_cache(cache);
+
+  /* calculate the bucket index to use */
+  hash_value = hash_func(revision, path, path_len);
+
+  bucket_index = hash_value + (hash_value >> 16);
+  bucket_index = (bucket_index + (bucket_index >> 8)) % BUCKET_COUNT;
+
+  /* access the corresponding bucket and remember its location */
+  entry = &cache->buckets[bucket_index];
+  cache->last_hit = bucket_index;
+
+  /* if it is *NOT* a match,  clear the bucket, expect the caller to fill
+     in the node and count it as an insertion */
+  entry->hash_value = hash_value;
+  entry->revision = revision;
+  if (entry->path_len < path_len)
+    entry->path = apr_palloc(cache->pool, path_len + 1);
+  entry->path_len = path_len;
+  memcpy(entry->path, path, path_len + 1);
+
+  entry->node = svn_fs_fs__dag_dup(node, cache->pool);
+  cache->insertions++;
 }
 
 /* Optimistic lookup using the last seen non-empty location in CACHE.
@@ -393,11 +439,9 @@ dag_node_cache_get(dag_node_t **node_p,
       /* immutable DAG node. use the global caches for it */
 
       fs_fs_data_t *ffd = root->fs->fsap_data;
-      cache_entry_t *bucket;
 
-      auto_clear_dag_cache(ffd->dag_node_cache);
-      bucket = cache_lookup(ffd->dag_node_cache, root->rev, path);
-      if (bucket->node == NULL)
+      node = cache_lookup(ffd->dag_node_cache, root->rev, path);
+      if (node == NULL)
         {
           locate_cache(&cache, &key, root, path, pool);
           SVN_ERR(svn_cache__get((void **)&node, &found, cache, key, pool));
@@ -408,14 +452,13 @@ dag_node_cache_get(dag_node_t **node_p,
               svn_fs_fs__dag_set_fs(node, root->fs);
 
               /* Retain the DAG node in L1 cache. */
-              bucket->node = svn_fs_fs__dag_dup(node,
-                                                ffd->dag_node_cache->pool);
+              cache_insert(ffd->dag_node_cache, root->rev, path, node);
             }
         }
       else
         {
           /* Copy the node from L1 cache into the passed-in POOL. */
-          node = svn_fs_fs__dag_dup(bucket->node, pool);
+          node = svn_fs_fs__dag_dup(node, pool);
         }
     }
   else
@@ -1232,11 +1275,15 @@ get_dag(dag_node_t **dag_node_p,
     {
       /* Canonicalize the input PATH.  As it turns out, >95% of all paths
        * seen here during e.g. svnadmin verify are non-canonical, i.e.
-       * miss the leading '/'.  Unconditional canonicalization has a net
-       * performance benefit over previously checking path for being
-       * canonical. */
-      path = svn_fs__canonicalize_abspath(path, pool);
-      SVN_ERR(dag_node_cache_get(&node, root, path, pool));
+       * miss the leading '/'.  Check for those quickly.
+       *
+       * For normalized paths, it is much faster to check the path than
+       * to attempt a second cache lookup (which would fail). */
+      if (*path != '/' || !svn_fs__is_canonical_abspath(path))
+        {
+          path = svn_fs__canonicalize_abspath(path, pool);
+          SVN_ERR(dag_node_cache_get(&node, root, path, pool));
+        }
 
       if (! node)
         {

Propchange: subversion/branches/move-tracking-2/subversion/libsvn_fs_x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Oct 26 08:43:06 2015
@@ -93,5 +93,5 @@
 /subversion/branches/verify-at-commit/subversion/libsvn_fs_x:1462039-1462408
 /subversion/branches/verify-keep-going/subversion/libsvn_fs_x:1439280-1492639,1546002-1546110
 /subversion/branches/wc-collate-path/subversion/libsvn_fs_x:1402685-1480384
-/subversion/trunk/subversion/libsvn_fs_fs:1415133-1596500,1596567,1597414,1597989,1598273,1599140,1600872,1601633,1603485-1603487,1603499,1603605,1604128,1604188,1604413-1604414,1604416-1604417,1604421,1604442,1604700,1604717,1604720,1604726,1604755,1604794,1604802,1604824,1604836,1604844,1604902-1604903,1604911,1604925,1604933,1604947,1605059-1605060,1605064-1605065,1605068,1605071-1605073,1605075,1605123,1605188-1605189,1605191,1605197,1605444,1605633,1606132,1606142,1606144,1606514,1606526,1606528,1606551,1606554,1606564,1606598-1606599,1606656,1606658,1606662,1606744,1606840,1607085,1607572,1612407,1612810,1613339,1613872,1614611,1615348,1615351-1615352,1615356,1616338-1616339,1616613,1617586,1617688,1618138,1618151,1618153,1618226,1618641,1618653,1618662,1619068,1619358,1619413,1619769,1619774,1620602,1620909,1620912,1620928,1620930,1621275,1621635,1622931,1622937,1622942,1622946,1622959-1622960,1622963,1622987,1623007,1623368,1623373,1623377,1623379,1623381,1623398,1623402,162
 4011,1624265,1624512,1626246,1626871,1626873,1626886,1627497-1627498,1627502,1627947-1627949,1627966,1628083,1628093,1628158-1628159,1628161,1628392-1628393,1628415,1628427,1628676,1628738,1628762,1628764,1629854-1629855,1629857,1629865,1629873,1629875,1629879,1630067,1630070,1631049-1631051,1631075,1631115,1631171,1631180,1631185-1631186,1631196-1631197,1631239-1631240,1631548,1631550,1631563,1631567,1631588,1631598,1632646,1632776,1632849,1632851-1632853,1632856-1632857,1632868,1632908,1632926,1633232,1633617-1633618,1634872,1634875,1634879-1634880,1634920,1636478,1636483,1636629,1636644,1637184,1637186,1637330,1637358,1637363,1637393,1639319,1639322,1639335,1639348,1639352,1639355,1639358,1639414,1639419,1639426,1639430,1639436,1639440,1639549,1640061-1640062,1640197,1640915,1640966,1641013,1643139,1643233,1645567,1646021,1646712,1646716,1647537,1647540-1647541,1647820,1647905,1648230,1648238,1648241-1648243,1648253,1648272,1648532,1648537-1648539,1648542,1648591,1648612,1653608,
 1658482
-/subversion/trunk/subversion/libsvn_fs_x:1414756-1509914,1606692-1709537
+/subversion/trunk/subversion/libsvn_fs_fs:1415133-1596500,1596567,1597414,1597989,1598273,1599140,1600872,1601633,1603485-1603487,1603499,1603605,1604128,1604188,1604413-1604414,1604416-1604417,1604421,1604442,1604700,1604717,1604720,1604726,1604755,1604794,1604802,1604824,1604836,1604844,1604902-1604903,1604911,1604925,1604933,1604947,1605059-1605060,1605064-1605065,1605068,1605071-1605073,1605075,1605123,1605188-1605189,1605191,1605197,1605444,1605633,1606132,1606142,1606144,1606514,1606526,1606528,1606551,1606554,1606564,1606598-1606599,1606656,1606658,1606662,1606744,1606840,1607085,1607572,1612407,1612810,1613339,1613872,1614611,1615348,1615351-1615352,1615356,1616338-1616339,1616613,1617586,1617688,1618138,1618151,1618153,1618226,1618641,1618653,1618662,1619068,1619358,1619413,1619769,1619774,1620602,1620909,1620912,1620928,1620930,1621275,1621635,1622931,1622937,1622942,1622946,1622959-1622960,1622963,1622987,1623007,1623368,1623373,1623377,1623379,1623381,1623398,1623402,162
 4011,1624265,1624512,1626246,1626871,1626873,1626886,1627497-1627498,1627502,1627947-1627949,1627966,1628083,1628093,1628158-1628159,1628161,1628392-1628393,1628415,1628427,1628676,1628738,1628762,1628764,1629854-1629855,1629857,1629865,1629873,1629875,1629879,1630067,1630070,1631049-1631051,1631075,1631115,1631171,1631180,1631185-1631186,1631196-1631197,1631239-1631240,1631548,1631550,1631563,1631567,1631588,1631598,1632646,1632776,1632849,1632851-1632853,1632856-1632857,1632868,1632908,1632926,1633232,1633617-1633618,1634872,1634875,1634879-1634880,1634920,1636478,1636483,1636629,1636644,1637184,1637186,1637330,1637358,1637363,1637393,1639319,1639322,1639335,1639348,1639352,1639355,1639358,1639414,1639419,1639426,1639430,1639436,1639440,1639549,1640061-1640062,1640197,1640915,1640966,1641013,1643139,1643233,1645567,1646021,1646712,1646716,1647537,1647540-1647541,1647820,1647905,1648230,1648238,1648241-1648243,1648253,1648272,1648532,1648537-1648539,1648542,1648591,1648612,1649590,
 1651567,1652068,1652076,1652441,1652451,1653608,1654932,1654934,1654937,1655635,1655649,1655651,1655664,1656176,1657525,1657972,1657978,1658482,1659212,1659217,1659314,1659509,1662668,1665318,1665854,1665894,1667090,1667101,1667538,1669743,1669746,1669749,1669945,1670139,1670953,1673170,1673197,1673202,1673204,1673445,1673454,1673685,1673689,1673875,1674165,1674341,1674400,1674404,1674631,1674669,1674673,1675396,1676667,1677431,1678149,1678151,1678718,1678725,1679169,1679907,1679920-1679924,1679926,1680347,1680460,1680464,1680476,1680819,1681949,1681966,1681974,1681994,1682008,1682076,1682086,1682093,1682259,1682265,1682739,1682864,1683311,1683330,1683378,1683544,1683553,1684047,1686232,1686542,1686546,1686554,1686557,1687061,1687064,1687070-1687071,1687074,1687078-1687079,1688270,1688425,1692650,1693886,1694489,1694848,1696171,1696185,1696627-1696628,1696630,1696758,1697372,1697381,1697387,1697393,1697403,1697405,1701017,1701053,1702600,1702922,1703069,1703142,1703237,1703240,17052
 66,1705638,1705643,1705646,1705724,1705730,1705739,1706612,1706615,1706617,1706619,1706675-1706676,1706679,1706979-1706980,1707308,1707971-1707973,1707986,1707988-1707989,1708004
+/subversion/trunk/subversion/libsvn_fs_x:1414756-1509914,1606692-1710529

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_x/cached_data.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_x/cached_data.c?rev=1710531&r1=1710530&r2=1710531&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_x/cached_data.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_x/cached_data.c Mon Oct 26 08:43:06 2015
@@ -1510,7 +1510,7 @@ get_combined_window(svn_stringbuf_t **re
 }
 
 /* Returns whether or not the expanded fulltext of the file is cachable
- * based on its size SIZE.  The decision depends on the cache used by RB.
+ * based on its size SIZE.  The decision depends on the cache used by FFD.
  */
 static svn_boolean_t
 fulltext_size_is_cachable(svn_fs_x__data_t *ffd,
@@ -2472,11 +2472,42 @@ read_dir_entries(apr_array_header_t *ent
   return SVN_NO_ERROR;
 }
 
-/* Fetch the contents of a directory into ENTRIES.  Values are stored
+/* For directory NODEREV in FS, return the *FILESIZE of its in-txn
+ * representation.  If the directory representation is comitted data,
+ * set *FILESIZE to SVN_INVALID_FILESIZE. Use SCRATCH_POOL for temporaries.
+ */
+static svn_error_t *
+get_txn_dir_info(svn_filesize_t *filesize,
+                 svn_fs_t *fs,
+                 svn_fs_x__noderev_t *noderev,
+                 apr_pool_t *scratch_pool)
+{
+  if (noderev->data_rep
+      && ! svn_fs_x__is_revision(noderev->data_rep->id.change_set))
+    {
+      const svn_io_dirent2_t *dirent;
+      const char *filename;
+
+      filename = svn_fs_x__path_txn_node_children(fs, &noderev->noderev_id,
+                                                  scratch_pool, scratch_pool);
+
+      SVN_ERR(svn_io_stat_dirent2(&dirent, filename, FALSE, FALSE,
+                                  scratch_pool, scratch_pool));
+      *filesize = dirent->filesize;
+    }
+  else
+    {
+      *filesize = SVN_INVALID_FILESIZE;
+    }
+
+  return SVN_NO_ERROR;
+}
+
+/* Fetch the contents of a directory into DIR.  Values are stored
    as filename to string mappings; further conversion is necessary to
    convert them into svn_fs_x__dirent_t values. */
 static svn_error_t *
-get_dir_contents(apr_array_header_t **entries,
+get_dir_contents(svn_fs_x__dir_data_t *dir,
                  svn_fs_t *fs,
                  svn_fs_x__noderev_t *noderev,
                  apr_pool_t *result_pool,
@@ -2485,20 +2516,32 @@ get_dir_contents(apr_array_header_t **en
   svn_stream_t *contents;
   const svn_fs_x__id_t *id = &noderev->noderev_id;
 
-  *entries = apr_array_make(result_pool, 16, sizeof(svn_fs_x__dirent_t *));
+  /* Initialize the result. */
+  dir->entries = apr_array_make(result_pool, 16, sizeof(svn_fs_x__dirent_t *));
+  dir->txn_filesize = SVN_INVALID_FILESIZE;
+
+  /* Read dir contents - unless there is none in which case we are done. */
   if (noderev->data_rep
       && ! svn_fs_x__is_revision(noderev->data_rep->id.change_set))
     {
-      const char *filename
-        = svn_fs_x__path_txn_node_children(fs, id, scratch_pool,
-                                           scratch_pool);
+      /* Get location & current size of the directory representation. */
+      const char *filename;
+      apr_file_t *file;
+
+      filename = svn_fs_x__path_txn_node_children(fs, id, scratch_pool,
+                                                  scratch_pool);
 
       /* The representation is mutable.  Read the old directory
          contents from the mutable children file, followed by the
          changes we've made in this transaction. */
-      SVN_ERR(svn_stream_open_readonly(&contents, filename, scratch_pool,
-                                       scratch_pool));
-      SVN_ERR(read_dir_entries(*entries, contents, TRUE,  id,
+      SVN_ERR(svn_io_file_open(&file, filename, APR_READ | APR_BUFFERED,
+                               APR_OS_DEFAULT, scratch_pool));
+
+      /* Obtain txn children file size. */
+      SVN_ERR(svn_io_file_size_get(&dir->txn_filesize, file, scratch_pool));
+
+      contents = svn_stream_from_aprfile2(file, FALSE, scratch_pool);
+      SVN_ERR(read_dir_entries(dir->entries, contents, TRUE, id,
                                result_pool, scratch_pool));
       SVN_ERR(svn_stream_close(contents));
     }
@@ -2518,7 +2561,7 @@ get_dir_contents(apr_array_header_t **en
 
       /* de-serialize hash */
       contents = svn_stream_from_stringbuf(text, scratch_pool);
-      SVN_ERR(read_dir_entries(*entries, contents, FALSE,  id,
+      SVN_ERR(read_dir_entries(dir->entries, contents, FALSE, id,
                                result_pool, scratch_pool));
     }
 
@@ -2535,26 +2578,24 @@ locate_dir_cache(svn_fs_t *fs,
                  svn_fs_x__noderev_t *noderev)
 {
   svn_fs_x__data_t *ffd = fs->fsap_data;
-  if (svn_fs_x__is_txn(noderev->noderev_id.change_set))
+
+  if (!noderev->data_rep)
+    {
+      /* no data rep -> empty directory.
+         Use a key that does definitely not clash with non-NULL reps. */
+      key->change_set = SVN_FS_X__INVALID_CHANGE_SET;
+      key->number = SVN_FS_X__ITEM_INDEX_UNUSED;
+    }
+  else if (svn_fs_x__is_txn(noderev->noderev_id.change_set))
     {
-      /* data in txns must be addressed by ID since the representation has
-         not been created, yet. */
+      /* data in txns must be addressed by noderev ID since the
+         representation has not been created, yet. */
       *key = noderev->noderev_id;
     }
   else
     {
       /* committed data can use simple rev,item pairs */
-      if (noderev->data_rep)
-        {
-          *key = noderev->data_rep->id;
-        }
-      else
-        {
-          /* no data rep -> empty directory.
-             Use a key that does definitely not clash with non-NULL reps. */
-          key->change_set = SVN_FS_X__INVALID_CHANGE_SET;
-          key->number = SVN_FS_X__ITEM_INDEX_UNUSED;
-        }
+      *key = noderev->data_rep->id;
     }
 
   return ffd->dir_cache;
@@ -2568,22 +2609,35 @@ svn_fs_x__rep_contents_dir(apr_array_hea
                            apr_pool_t *scratch_pool)
 {
   svn_fs_x__id_t key;
+  svn_fs_x__dir_data_t *dir;
 
   /* find the cache we may use */
   svn_cache__t *cache = locate_dir_cache(fs, &key, noderev);
   svn_boolean_t found;
 
-  SVN_ERR(svn_cache__get((void **)entries_p, &found, cache, &key,
-                         result_pool));
+  SVN_ERR(svn_cache__get((void **)&dir, &found, cache, &key, result_pool));
   if (found)
-    return SVN_NO_ERROR;
+    {
+      /* Verify that the cached dir info is not stale
+       * (no-op for committed data). */
+      svn_filesize_t filesize;
+      SVN_ERR(get_txn_dir_info(&filesize, fs, noderev, scratch_pool));
+
+      if (filesize == dir->txn_filesize)
+        {
+          /* Still valid. Done. */
+          *entries_p = dir->entries;
+          return SVN_NO_ERROR;
+        }
+    }
 
   /* Read in the directory contents. */
-  SVN_ERR(get_dir_contents(entries_p, fs, noderev, result_pool,
-                           scratch_pool));
+  dir = apr_pcalloc(scratch_pool, sizeof(*dir));
+  SVN_ERR(get_dir_contents(dir, fs, noderev, result_pool, scratch_pool));
+  *entries_p = dir->entries;
 
   /* Update the cache, if we are to use one. */
-  SVN_ERR(svn_cache__set(cache, &key, *entries_p, scratch_pool));
+  SVN_ERR(svn_cache__set(cache, &key, dir, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -2613,10 +2667,15 @@ svn_fs_x__rep_contents_dir_entry(svn_fs_
   svn_fs_x__id_t key;
   svn_cache__t *cache = locate_dir_cache(fs, &key, noderev);
   svn_fs_x__ede_baton_t baton;
+
+  svn_filesize_t filesize;
+  SVN_ERR(get_txn_dir_info(&filesize, fs, noderev, scratch_pool));
+
+   /* Cache lookup. */
   baton.hint = *hint;
   baton.name = name;
+  baton.txn_filesize = filesize;
 
-  /* Cache lookup. */
   SVN_ERR(svn_cache__get_partial((void **)dirent,
                                  &found,
                                  cache,
@@ -2632,17 +2691,20 @@ svn_fs_x__rep_contents_dir_entry(svn_fs_
   /* fetch data from disk if we did not find it in the cache */
   if (! found)
     {
-      apr_array_header_t *entries;
       svn_fs_x__dirent_t *entry;
       svn_fs_x__dirent_t *entry_copy = NULL;
+      svn_fs_x__dir_data_t dir;
 
-      /* read the dir from the file system. It will probably be put it
-         into the cache for faster lookup in future calls. */
-      SVN_ERR(svn_fs_x__rep_contents_dir(&entries, fs, noderev,
-                                         scratch_pool, scratch_pool));
+      /* Read in the directory contents. */
+      SVN_ERR(get_dir_contents(&dir, fs, noderev, scratch_pool,
+                               scratch_pool));
+
+      /* Update the cache, if we are to use one. */
+      if (cache)
+        SVN_ERR(svn_cache__set(cache, &key, &dir, scratch_pool));
 
       /* find desired entry and return a copy in POOL, if found */
-      entry = svn_fs_x__find_dir_entry(entries, name, NULL);
+      entry = svn_fs_x__find_dir_entry(dir.entries, name, NULL);
       if (entry)
         {
           entry_copy = apr_pmemdup(result_pool, entry, sizeof(*entry_copy));
@@ -2665,6 +2727,7 @@ svn_fs_x__get_proplist(apr_hash_t **prop
   apr_hash_t *proplist;
   svn_stream_t *stream;
   const svn_fs_x__id_t *noderev_id = &noderev->noderev_id;
+  svn_error_t *err;
 
   if (noderev->prop_rep
       && !svn_fs_x__is_revision(noderev->prop_rep->id.change_set))
@@ -2676,8 +2739,19 @@ svn_fs_x__get_proplist(apr_hash_t **prop
 
       SVN_ERR(svn_stream_open_readonly(&stream, filename, scratch_pool,
                                        scratch_pool));
-      SVN_ERR(svn_hash_read2(proplist, stream, SVN_HASH_TERMINATOR,
-                             result_pool));
+      err = svn_hash_read2(proplist, stream, SVN_HASH_TERMINATOR,
+                          result_pool);
+      if (err)
+        {
+          svn_string_t *id_str = svn_fs_x__id_unparse(&noderev->noderev_id,
+                                                      scratch_pool);
+
+          err = svn_error_compose_create(err, svn_stream_close(stream));
+          return svn_error_quick_wrapf(err,
+                   _("malformed property list for node-revision '%s' in '%s'"),
+                   id_str->data, filename);
+        }
+
       SVN_ERR(svn_stream_close(stream));
     }
   else if (noderev->prop_rep)
@@ -2700,8 +2774,19 @@ svn_fs_x__get_proplist(apr_hash_t **prop
       proplist = apr_hash_make(result_pool);
       SVN_ERR(svn_fs_x__get_contents(&stream, fs, noderev->prop_rep, FALSE,
                                      scratch_pool));
-      SVN_ERR(svn_hash_read2(proplist, stream, SVN_HASH_TERMINATOR,
-                             result_pool));
+      err = svn_hash_read2(proplist, stream, SVN_HASH_TERMINATOR,
+                           result_pool);
+      if (err)
+        {
+          svn_string_t *id_str = svn_fs_x__id_unparse(&noderev->noderev_id,
+                                                      scratch_pool);
+
+          err = svn_error_compose_create(err, svn_stream_close(stream));
+          return svn_error_quick_wrapf(err,
+                   _("malformed property list for node-revision '%s'"),
+                   id_str->data);
+        }
+
       SVN_ERR(svn_stream_close(stream));
 
       if (SVN_IS_VALID_REVNUM(rep->id.change_set))

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs.c?rev=1710531&r1=1710530&r2=1710531&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs.c Mon Oct 26 08:43:06 2015
@@ -137,6 +137,18 @@ x_serialized_init(svn_fs_t *fs,
   return SVN_NO_ERROR;
 }
 
+svn_error_t *
+svn_fs_x__initialize_shared_data(svn_fs_t *fs,
+                                 svn_mutex__t *common_pool_lock,
+                                 apr_pool_t *scratch_pool,
+                                 apr_pool_t *common_pool)
+{
+  SVN_MUTEX__WITH_LOCK(common_pool_lock,
+                       x_serialized_init(fs, common_pool, scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
 
 
 /* This function is provided for Subversion 1.0.x compatibility.  It
@@ -530,24 +542,17 @@ x_hotcopy(svn_fs_t *src_fs,
   if (cancel_func)
     SVN_ERR(cancel_func(cancel_baton));
 
-  /* Test target repo when in INCREMENTAL mode, initialize it when not.
-   * For this, we need our FS internal data structures to be temporarily
-   * available. */
+  SVN_ERR(svn_fs__check_fs(dst_fs, FALSE));
   SVN_ERR(initialize_fs_struct(dst_fs));
-  SVN_ERR(svn_fs_x__hotcopy_prepare_target(src_fs, dst_fs, dst_path,
-                                           incremental, scratch_pool));
-  uninitialize_fs_struct(dst_fs);
-
-  /* Now, the destination repo should open just fine. */
-  SVN_ERR(x_open(dst_fs, dst_path, common_pool_lock, scratch_pool,
-                 common_pool));
-  if (cancel_func)
-    SVN_ERR(cancel_func(cancel_baton));
 
-  /* Now, we may copy data as needed ... */
-  return svn_fs_x__hotcopy(src_fs, dst_fs, incremental,
-                           notify_func, notify_baton,
-                           cancel_func, cancel_baton, scratch_pool);
+  /* In INCREMENTAL mode, svn_fs_x__hotcopy() will open DST_FS.
+     Otherwise, it's not an FS yet --- possibly just an empty dir --- so
+     can't be opened.
+   */
+  return svn_fs_x__hotcopy(src_fs, dst_fs, src_path, dst_path,
+                            incremental, notify_func, notify_baton,
+                            cancel_func, cancel_baton, common_pool_lock,
+                            scratch_pool, common_pool);
 }
 
 

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs.h?rev=1710531&r1=1710530&r2=1710531&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs.h (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs.h Mon Oct 26 08:43:06 2015
@@ -552,6 +552,18 @@ typedef struct svn_fs_x__change_t
   svn_tristate_t mergeinfo_mod;
 } svn_fs_x__change_t;
 
+
+/*** Directory (only used at the cache interface) ***/
+typedef struct svn_fs_x__dir_data_t
+{
+  /* Contents, i.e. all directory entries, sorted by name. */
+  apr_array_header_t *entries;
+
+  /* SVN_INVALID_FILESIZE for committed data, otherwise the length of the
+   * in-txn on-disk representation of that directory. */
+  svn_filesize_t txn_filesize;
+} svn_fs_x__dir_data_t;
+
 
 #ifdef __cplusplus
 }

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs_x.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs_x.c?rev=1710531&r1=1710530&r2=1710531&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs_x.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs_x.c Mon Oct 26 08:43:06 2015
@@ -602,8 +602,9 @@ svn_fs_x__open(svn_fs_t *fs,
   /* Read the configuration file. */
   SVN_ERR(read_config(ffd, fs->path, fs->pool, scratch_pool));
 
-  return svn_error_trace(svn_fs_x__read_current(&ffd->youngest_rev_cache,
-                                                fs, scratch_pool));
+  ffd->youngest_rev_cache = 0;
+
+  return SVN_NO_ERROR;
 }
 
 /* Baton type bridging svn_fs_x__upgrade and upgrade_body carrying

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs_x.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs_x.h?rev=1710531&r1=1710530&r2=1710531&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs_x.h (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs_x.h Mon Oct 26 08:43:06 2015
@@ -41,6 +41,16 @@ svn_fs_x__open(svn_fs_t *fs,
                const char *path,
                apr_pool_t *scratch_pool);
 
+/* Initialize parts of the FS data that are being shared across multiple
+   filesystem objects.  Use COMMON_POOL for process-wide and SCRATCH_POOL
+   for temporary allocations.  Use COMMON_POOL_LOCK to ensure that the
+   initialization is serialized. */
+svn_error_t *
+svn_fs_x__initialize_shared_data(svn_fs_t *fs,
+                                 svn_mutex__t *common_pool_lock,
+                                 apr_pool_t *scratch_pool,
+                                 apr_pool_t *common_pool);
+
 /* Upgrade the fsx filesystem FS.  Indicate progress via the optional
  * NOTIFY_FUNC callback using NOTIFY_BATON.  The optional CANCEL_FUNC
  * will periodically be called with CANCEL_BATON to allow for preemption.

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_x/hotcopy.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_x/hotcopy.c?rev=1710531&r1=1710530&r2=1710531&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_x/hotcopy.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_x/hotcopy.c Mon Oct 26 08:43:06 2015
@@ -326,6 +326,19 @@ hotcopy_copy_packed_shard(svn_boolean_t
   return SVN_NO_ERROR;
 }
 
+/* Remove file PATH, if it exists - even if it is read-only.
+ * Use SCRATCH_POOL for temporary allocations. */
+static svn_error_t *
+hotcopy_remove_file(const char *path,
+                    apr_pool_t *scratch_pool)
+{
+  /* Make the rev file writable and remove it. */
+  SVN_ERR(svn_io_set_file_read_write(path, TRUE, scratch_pool));
+  SVN_ERR(svn_io_remove_file2(path, TRUE, scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
 /* Verify that DST_FS is a suitable destination for an incremental
  * hotcopy from SRC_FS. */
 static svn_error_t *
@@ -651,6 +664,10 @@ hotcopy_body(void *baton,
       /* Copy the rep cache and then remove entries for revisions
        * that did not make it into the destination. */
       SVN_ERR(svn_sqlite__hotcopy(src_subdir, dst_subdir, scratch_pool));
+
+      /* The source might have r/o flags set on it - which would be
+         carried over to the copy. */
+      SVN_ERR(svn_io_set_file_read_write(dst_subdir, FALSE, scratch_pool));
       SVN_ERR(svn_fs_x__del_rep_reference(dst_fs, src_youngest,
                                           scratch_pool));
     }
@@ -665,64 +682,33 @@ hotcopy_body(void *baton,
    * used for the named atomics implementation. */
   SVN_ERR(svn_fs_x__reset_revprop_generation_file(dst_fs, scratch_pool));
 
-  return SVN_NO_ERROR;
-}
-
-/* Wrapper around hotcopy_body taking out all necessary source repository
- * locks.
- */
-static svn_error_t *
-hotcopy_locking_src_body(void *baton,
-                         apr_pool_t *scratch_pool)
-{
-  hotcopy_body_baton_t *hbb = baton;
+  /* Hotcopied FS is complete. Stamp it with a format file. */
+  SVN_ERR(svn_fs_x__write_format(dst_fs, TRUE, scratch_pool));
 
-  return svn_error_trace(svn_fs_x__with_pack_lock(hbb->src_fs, hotcopy_body,
-                                                  baton, scratch_pool));
+  return SVN_NO_ERROR;
 }
 
-/* Create an empty filesystem at DST_FS at DST_PATH with the same
- * configuration as SRC_FS (uuid, format, and other parameters).
- * After creation DST_FS has no revisions, not even revision zero. */
-static svn_error_t *
-hotcopy_create_empty_dest(svn_fs_t *src_fs,
-                          svn_fs_t *dst_fs,
-                          const char *dst_path,
-                          apr_pool_t *scratch_pool)
+svn_error_t *
+svn_fs_x__hotcopy(svn_fs_t *src_fs,
+                  svn_fs_t *dst_fs,
+                  const char *src_path,
+                  const char *dst_path,
+                  svn_boolean_t incremental,
+                  svn_fs_hotcopy_notify_t notify_func,
+                  void *notify_baton,
+                  svn_cancel_func_t cancel_func,
+                  void *cancel_baton,
+                  svn_mutex__t *common_pool_lock,
+                  apr_pool_t *scratch_pool,
+                  apr_pool_t *common_pool)
 {
-  svn_fs_x__data_t *src_ffd = src_fs->fsap_data;
-
-  /* Create the DST_FS repository with the same layout as SRC_FS. */
-  SVN_ERR(svn_fs_x__create_file_tree(dst_fs, dst_path, src_ffd->format,
-                                     src_ffd->max_files_per_dir,
-                                     scratch_pool));
+  hotcopy_body_baton_t hbb;
 
-  /* Copy the UUID.  Hotcopy destination receives a new instance ID, but
-   * has the same filesystem UUID as the source. */
-  SVN_ERR(svn_fs_x__set_uuid(dst_fs, src_fs->uuid, NULL, scratch_pool));
-
-  /* Remove revision 0 contents.  Otherwise, it may not get overwritten
-   * due to having a newer timestamp. */
-  SVN_ERR(svn_io_remove_file2(svn_fs_x__path_rev(dst_fs, 0, scratch_pool),
-                              FALSE, scratch_pool));
-  SVN_ERR(svn_io_remove_file2(svn_fs_x__path_revprops(dst_fs, 0,
-                                                      scratch_pool),
-                              FALSE, scratch_pool));
-
-  /* This filesystem is ready.  Stamp it with a format number.  Fail if
-   * the 'format' file should already exist. */
-  SVN_ERR(svn_fs_x__write_format(dst_fs, FALSE, scratch_pool));
+  if (cancel_func)
+    SVN_ERR(cancel_func(cancel_baton));
 
-  return SVN_NO_ERROR;
-}
+  SVN_ERR(svn_fs_x__open(src_fs, src_path, scratch_pool));
 
-svn_error_t *
-svn_fs_x__hotcopy_prepare_target(svn_fs_t *src_fs,
-                                 svn_fs_t *dst_fs,
-                                 const char *dst_path,
-                                 svn_boolean_t incremental,
-                                 apr_pool_t *scratch_pool)
-{
   if (incremental)
     {
       const char *dst_format_abspath;
@@ -736,40 +722,52 @@ svn_fs_x__hotcopy_prepare_target(svn_fs_
                                 scratch_pool));
       if (dst_format_kind == svn_node_none)
         {
-          /* Destination doesn't exist yet. Perform a normal hotcopy to a
-           * empty destination using the same configuration as the source. */
-          SVN_ERR(hotcopy_create_empty_dest(src_fs, dst_fs, dst_path,
-                                            scratch_pool));
-        }
-      else
-        {
-          /* Check the existing repository. */
-          SVN_ERR(svn_fs_x__open(dst_fs, dst_path, scratch_pool));
-          SVN_ERR(hotcopy_incremental_check_preconditions(src_fs, dst_fs));
+          /* No destination?  Fallback to a non-incremental hotcopy. */
+          incremental = FALSE;
         }
     }
+
+  if (incremental)
+    {
+      /* Check the existing repository. */
+      SVN_ERR(svn_fs_x__open(dst_fs, dst_path, scratch_pool));
+      SVN_ERR(hotcopy_incremental_check_preconditions(src_fs, dst_fs));
+
+      SVN_ERR(svn_fs_x__initialize_shared_data(dst_fs, common_pool_lock,
+                                               scratch_pool, common_pool));
+      SVN_ERR(svn_fs_x__initialize_caches(dst_fs, scratch_pool));
+    }
   else
     {
       /* Start out with an empty destination using the same configuration
        * as the source. */
-      SVN_ERR(hotcopy_create_empty_dest(src_fs, dst_fs, dst_path,
-                                        scratch_pool));
-    }
+      svn_fs_x__data_t *src_ffd = src_fs->fsap_data;
 
-  return SVN_NO_ERROR;
-}
+      /* Create the DST_FS repository with the same layout as SRC_FS. */
+      SVN_ERR(svn_fs_x__create_file_tree(dst_fs, dst_path, src_ffd->format,
+                                         src_ffd->max_files_per_dir,
+                                         scratch_pool));
+
+      /* Copy the UUID.  Hotcopy destination receives a new instance ID, but
+       * has the same filesystem UUID as the source. */
+      SVN_ERR(svn_fs_x__set_uuid(dst_fs, src_fs->uuid, NULL, scratch_pool));
+
+      /* Remove revision 0 contents.  Otherwise, it may not get overwritten
+       * due to having a newer timestamp. */
+      SVN_ERR(hotcopy_remove_file(svn_fs_x__path_rev(dst_fs, 0,
+                                                     scratch_pool),
+                                  scratch_pool));
+      SVN_ERR(hotcopy_remove_file(svn_fs_x__path_revprops(dst_fs, 0,
+                                                          scratch_pool),
+                                  scratch_pool));
+
+      SVN_ERR(svn_fs_x__initialize_shared_data(dst_fs, common_pool_lock,
+                                               scratch_pool, common_pool));
+      SVN_ERR(svn_fs_x__initialize_caches(dst_fs, scratch_pool));
+    }
 
-svn_error_t *
-svn_fs_x__hotcopy(svn_fs_t *src_fs,
-                  svn_fs_t *dst_fs,
-                  svn_boolean_t incremental,
-                  svn_fs_hotcopy_notify_t notify_func,
-                  void *notify_baton,
-                  svn_cancel_func_t cancel_func,
-                  void *cancel_baton,
-                  apr_pool_t *scratch_pool)
-{
-  hotcopy_body_baton_t hbb;
+  if (cancel_func)
+    SVN_ERR(cancel_func(cancel_baton));
 
   hbb.src_fs = src_fs;
   hbb.dst_fs = dst_fs;
@@ -778,8 +776,16 @@ svn_fs_x__hotcopy(svn_fs_t *src_fs,
   hbb.notify_baton = notify_baton;
   hbb.cancel_func = cancel_func;
   hbb.cancel_baton = cancel_baton;
-  SVN_ERR(svn_fs_x__with_all_locks(dst_fs, hotcopy_locking_src_body, &hbb,
-                                   scratch_pool));
+
+  /* Lock the destination in the incremental mode.  For a non-incremental
+   * hotcopy, don't take any locks.  In that case the destination cannot be
+   * opened until the hotcopy finishes, and we don't have to worry about
+   * concurrency. */
+  if (incremental)
+    SVN_ERR(svn_fs_x__with_all_locks(dst_fs, hotcopy_body, &hbb,
+                                     scratch_pool));
+  else
+    SVN_ERR(hotcopy_body(&hbb, scratch_pool));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_x/hotcopy.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_x/hotcopy.h?rev=1710531&r1=1710530&r2=1710531&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_x/hotcopy.h (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_x/hotcopy.h Mon Oct 26 08:43:06 2015
@@ -25,29 +25,24 @@
 
 #include "fs.h"
 
-/* Create an empty copy of the fsfs filesystem SRC_FS into a new DST_FS at
- * DST_PATH.  If INCREMENTAL is TRUE, perform a few pre-checks only if
- * a repo already exists at DST_PATH.
- * Use SCRATCH_POOL for temporary allocations. */
-svn_error_t *
-svn_fs_x__hotcopy_prepare_target(svn_fs_t *src_fs,
-                                 svn_fs_t *dst_fs,
-                                 const char *dst_path,
-                                 svn_boolean_t incremental,
-                                 apr_pool_t *scratch_pool);
-
-/* Copy the fsfs filesystem SRC_FS into DST_FS. If INCREMENTAL is TRUE, do
- * not re-copy data which already exists in DST_FS.  Indicate progress via
- * the optional NOTIFY_FUNC callback using NOTIFY_BATON.
- * Use SCRATCH_POOL for temporary allocations. */
+/* Copy the fsfs filesystem SRC_FS at SRC_PATH into a new copy DST_FS at
+ * DST_PATH.  If INCREMENTAL is TRUE, do not re-copy data which already
+ * exists in DST_FS.  Indicate progress via the optional NOTIFY_FUNC
+ * callback using NOTIFY_BATON.  Use COMMON_POOL for process-wide and
+ * SCRATCH_POOL for temporary allocations.  Use COMMON_POOL_LOCK to ensure
+ * that the initialization of the shared data is serialized. */
 svn_error_t *
 svn_fs_x__hotcopy(svn_fs_t *src_fs,
                   svn_fs_t *dst_fs,
+                  const char *src_path,
+                  const char *dst_path,
                   svn_boolean_t incremental,
                   svn_fs_hotcopy_notify_t notify_func,
                   void *notify_baton,
                   svn_cancel_func_t cancel_func,
                   void *cancel_baton,
-                  apr_pool_t *scratch_pool);
+                  svn_mutex__t *common_pool_lock,
+                  apr_pool_t *scratch_pool,
+                  apr_pool_t *common_pool);
 
 #endif

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_x/index.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_x/index.c?rev=1710531&r1=1710530&r2=1710531&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_x/index.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_x/index.c Mon Oct 26 08:43:06 2015
@@ -963,8 +963,8 @@ svn_fs_x__l2p_index_append(svn_checksum_
               /* 1 page with up to L2P_PAGE_SIZE entries.
                * fsfs.conf settings validation guarantees this to fit into
                * our address space. */
-              apr_size_t last_buffer_size
-                = (apr_size_t)svn_spillbuf__get_size(buffer);
+              apr_uint64_t last_buffer_size
+                = (apr_uint64_t)svn_spillbuf__get_size(buffer);
 
               svn_pool_clear(iterpool);
 
@@ -2182,8 +2182,8 @@ svn_fs_x__p2l_index_append(svn_checksum_
 
   apr_uint64_t last_entry_end = 0;
   apr_uint64_t last_page_end = 0;
-  apr_size_t last_buffer_size = 0;  /* byte offset in the spill buffer at
-                                       the begin of the current revision */
+  apr_uint64_t last_buffer_size = 0;  /* byte offset in the spill buffer at
+                                         the begin of the current revision */
   apr_uint64_t file_size = 0;
 
   /* temporary data structures that collect the data which will be moved

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_x/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_x/lock.c?rev=1710531&r1=1710530&r2=1710531&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_x/lock.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_x/lock.c Mon Oct 26 08:43:06 2015
@@ -235,7 +235,7 @@ write_digest_file(apr_hash_t *children,
   if ((err = svn_hash_write2(hash, stream, SVN_HASH_TERMINATOR,
                              scratch_pool)))
     {
-      svn_error_clear(svn_stream_close(stream));
+      err = svn_error_compose_create(err, svn_stream_close(stream));
       return svn_error_createf(err->apr_err,
                                err,
                                _("Cannot write lock/entries hashfile '%s'"),
@@ -287,7 +287,7 @@ read_digest_file(apr_hash_t **children_p
   hash = apr_hash_make(pool);
   if ((err = svn_hash_read2(hash, stream, SVN_HASH_TERMINATOR, pool)))
     {
-      svn_error_clear(svn_stream_close(stream));
+      err = svn_error_compose_create(err, svn_stream_close(stream));
       return svn_error_createf(err->apr_err,
                                err,
                                _("Can't parse lock/entries hashfile '%s'"),
@@ -951,6 +951,7 @@ lock_body(void *baton,
         }
     }
 
+  svn_pool_destroy(iterpool);
   return SVN_NO_ERROR;
 }
 
@@ -1163,7 +1164,7 @@ svn_fs_x__lock(svn_fs_t *fs,
 
   lb.fs = fs;
   lb.targets = sorted_targets;
-  lb.infos = apr_array_make(scratch_pool, sorted_targets->nelts,
+  lb.infos = apr_array_make(result_pool, sorted_targets->nelts,
                             sizeof(struct lock_info_t));
   lb.comment = comment;
   lb.is_dav_comment = is_dav_comment;
@@ -1259,7 +1260,7 @@ svn_fs_x__unlock(svn_fs_t *fs,
 
   ub.fs = fs;
   ub.targets = sorted_targets;
-  ub.infos = apr_array_make(scratch_pool, sorted_targets->nelts,
+  ub.infos = apr_array_make(result_pool, sorted_targets->nelts,
                             sizeof(struct unlock_info_t));
   ub.skip_check = FALSE;
   ub.break_lock = break_lock;

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_x/low_level.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_x/low_level.c?rev=1710531&r1=1710530&r2=1710531&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_x/low_level.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_x/low_level.c Mon Oct 26 08:43:06 2015
@@ -102,6 +102,19 @@ parse_revnum(svn_revnum_t *rev,
   return SVN_NO_ERROR;
 }
 
+/* If ERR is not NULL, wrap it MESSAGE.  The latter must have an %ld
+ * format parameter that will be filled with REV. */
+static svn_error_t *
+wrap_footer_error(svn_error_t *err,
+                  const char *message,
+                  svn_revnum_t rev)
+{
+  if (err)
+    return svn_error_quick_wrapf(err, message, rev);
+
+  return SVN_NO_ERROR;
+}
+
 svn_error_t *
 svn_fs_x__parse_footer(apr_off_t *l2p_offset,
                        svn_checksum_t **l2p_checksum,
@@ -109,6 +122,7 @@ svn_fs_x__parse_footer(apr_off_t *l2p_of
                        svn_checksum_t **p2l_checksum,
                        svn_stringbuf_t *footer,
                        svn_revnum_t rev,
+                       apr_off_t footer_offset,
                        apr_pool_t *result_pool)
 {
   apr_int64_t val;
@@ -117,17 +131,20 @@ svn_fs_x__parse_footer(apr_off_t *l2p_of
   /* Get the L2P offset. */
   const char *str = svn_cstring_tokenize(" ", &last_str);
   if (str == NULL)
-    return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
-                            _("Invalid revision footer"));
+    return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
+                             "Invalid r%ld footer", rev);
 
-  SVN_ERR(svn_cstring_atoi64(&val, str));
+  SVN_ERR(wrap_footer_error(svn_cstring_strtoi64(&val, str, 0,
+                                                 footer_offset - 1, 10),
+                            "Invalid L2P offset in r%ld footer",
+                            rev));
   *l2p_offset = (apr_off_t)val;
 
   /* Get the L2P checksum. */
   str = svn_cstring_tokenize(" ", &last_str);
   if (str == NULL)
-    return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
-                            _("Invalid revision footer"));
+    return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
+                             "Invalid r%ld footer", rev);
 
   SVN_ERR(svn_checksum_parse_hex(l2p_checksum, svn_checksum_md5, str,
                                  result_pool));
@@ -135,17 +152,33 @@ svn_fs_x__parse_footer(apr_off_t *l2p_of
   /* Get the P2L offset. */
   str = svn_cstring_tokenize(" ", &last_str);
   if (str == NULL)
-    return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
-                            _("Invalid revision footer"));
+    return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
+                             "Invalid r%ld footer", rev);
 
-  SVN_ERR(svn_cstring_atoi64(&val, str));
+  SVN_ERR(wrap_footer_error(svn_cstring_strtoi64(&val, str, 0,
+                                                 footer_offset - 1, 10),
+                            "Invalid P2L offset in r%ld footer",
+                            rev));
   *p2l_offset = (apr_off_t)val;
 
+  /* The P2L indes follows the L2P index */
+  if (*p2l_offset <= *l2p_offset)
+    return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
+                             "P2L offset %s must be larger than L2P offset %s"
+                             " in r%ld footer",
+                             apr_psprintf(result_pool,
+                                          "%" APR_UINT64_T_HEX_FMT,
+                                          (apr_uint64_t)*p2l_offset),
+                             apr_psprintf(result_pool,
+                                          "%" APR_UINT64_T_HEX_FMT,
+                                          (apr_uint64_t)*l2p_offset),
+                             rev);
+
   /* Get the P2L checksum. */
   str = svn_cstring_tokenize(" ", &last_str);
   if (str == NULL)
-    return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
-                            _("Invalid revision footer"));
+    return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
+                             "Invalid r%ld footer", rev);
 
   SVN_ERR(svn_checksum_parse_hex(p2l_checksum, svn_checksum_md5, str,
                                  result_pool));

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_x/low_level.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_x/low_level.h?rev=1710531&r1=1710530&r2=1710531&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_x/low_level.h (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_x/low_level.h Mon Oct 26 08:43:06 2015
@@ -50,6 +50,8 @@ extern "C" {
  * *P2L_OFFSET, respectively.  Also, return the expected checksums in
  * in *L2P_CHECKSUM and *P2L_CHECKSUM.
  *
+ * FOOTER_OFFSET is used for validation.
+ *
  * Note that REV is only used to construct nicer error objects that
  * mention this revision.  Allocate the checksums in RESULT_POOL.
  */
@@ -60,6 +62,7 @@ svn_fs_x__parse_footer(apr_off_t *l2p_of
                        svn_checksum_t **p2l_checksum,
                        svn_stringbuf_t *footer,
                        svn_revnum_t rev,
+                       apr_off_t footer_offset,
                        apr_pool_t *result_pool);
 
 /* Given the offset of the L2P index data in L2P_OFFSET, the content