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