Author: stefan2
Date: Sun Apr 15 11:20:58 2012
New Revision: 1326307
URL: http://svn.apache.org/viewvc?rev=1326307&view=rev
Log:
Merge all changes (-r1298521-1326293) from branches/revprop-cache to trunk
and resolve minor conflicts.
Added:
subversion/trunk/subversion/include/private/svn_named_atomic.h
- copied unchanged from r1326293,
subversion/branches/revprop-cache/subversion/include/private/svn_named_atomic.h
subversion/trunk/subversion/libsvn_subr/svn_named_atomic.c
- copied unchanged from r1326293,
subversion/branches/revprop-cache/subversion/libsvn_subr/svn_named_atomic.c
subversion/trunk/subversion/tests/libsvn_subr/named_atomic-test-common.h
- copied unchanged from r1326293,
subversion/branches/revprop-cache/subversion/tests/libsvn_subr/named_atomic-test-common.h
subversion/trunk/subversion/tests/libsvn_subr/named_atomic-test-proc.c
- copied unchanged from r1326293,
subversion/branches/revprop-cache/subversion/tests/libsvn_subr/named_atomic-test-proc.c
subversion/trunk/subversion/tests/libsvn_subr/named_atomic-test.c
- copied, changed from r1326293,
subversion/branches/revprop-cache/subversion/tests/libsvn_subr/named_atomic-test.c
Modified:
subversion/trunk/ (props changed)
subversion/trunk/build.conf
subversion/trunk/build/ac-macros/svn-macros.m4
subversion/trunk/configure.ac
subversion/trunk/subversion/include/svn_error_codes.h
subversion/trunk/subversion/include/svn_fs.h
subversion/trunk/subversion/include/svn_io.h
subversion/trunk/subversion/libsvn_fs_fs/caching.c
subversion/trunk/subversion/libsvn_fs_fs/fs.h
subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c
subversion/trunk/subversion/libsvn_subr/io.c
subversion/trunk/subversion/mod_dav_svn/dav_svn.h
subversion/trunk/subversion/mod_dav_svn/mod_dav_svn.c
subversion/trunk/subversion/mod_dav_svn/repos.c
subversion/trunk/subversion/svnadmin/main.c
subversion/trunk/subversion/svnserve/main.c
subversion/trunk/subversion/svnserve/serve.c
subversion/trunk/subversion/svnserve/server.h
subversion/trunk/subversion/tests/libsvn_repos/repos-test.c
subversion/trunk/subversion/tests/libsvn_subr/ (props changed)
subversion/trunk/subversion/tests/svn_test.h
Propchange: subversion/trunk/
------------------------------------------------------------------------------
Merged /subversion/branches/revprop-cache:r1298521-1326293
Modified: subversion/trunk/build.conf
URL:
http://svn.apache.org/viewvc/subversion/trunk/build.conf?rev=1326307&r1=1326306&r2=1326307&view=diff
==============================================================================
--- subversion/trunk/build.conf (original)
+++ subversion/trunk/build.conf Sun Apr 15 11:20:58 2012
@@ -331,7 +331,7 @@ msvc-export =
private\svn_token.h private\svn_adler32.h
private\svn_temp_serializer.h private\svn_io_private.h
private\svn_string_private.h private\svn_magic.h
- private\svn_subr_private.h private\svn_mutex.h
+ private\svn_subr_private.h private\svn_mutex.h
private\svn_named_atomic.h
# Working copy management lib
[libsvn_wc]
@@ -792,6 +792,22 @@ sources = mergeinfo-test.c
install = test
libs = libsvn_test libsvn_subr apr
+[named_atomic-test]
+description = Test named atomics
+type = exe
+path = subversion/tests/libsvn_subr
+sources = named_atomic-test.c
+install = test
+libs = libsvn_test libsvn_subr apr
+
+[named_atomic-test-proc]
+description = Sub-process for named atomics
+type = exe
+path = subversion/tests/libsvn_subr
+sources = named_atomic-test-proc.c
+install = sub-test
+libs = libsvn_subr apr
+
[path-test]
description = Test path library
type = exe
@@ -1142,7 +1158,7 @@ libs = __ALL__
checksum-test compat-test config-test hashdump-test mergeinfo-test
opt-test path-test stream-test string-test time-test utf-test
target-test error-test cache-test spillbuf-test crypto-test
- revision-test
+ named-atomics-test-proc revision-test
subst_translate-test
translate-test
random-test window-test
Modified: subversion/trunk/build/ac-macros/svn-macros.m4
URL:
http://svn.apache.org/viewvc/subversion/trunk/build/ac-macros/svn-macros.m4?rev=1326307&r1=1326306&r2=1326307&view=diff
==============================================================================
--- subversion/trunk/build/ac-macros/svn-macros.m4 (original)
+++ subversion/trunk/build/ac-macros/svn-macros.m4 Sun Apr 15 11:20:58 2012
@@ -202,3 +202,44 @@ AC_DEFUN([SVN_REMOVE_STANDARD_LIB_DIRS],
printf "%s" "${output_flags# }"
fi
])
+
+AC_DEFUN([SVN_CHECK_FOR_ATOMIC_BUILTINS],
+[
+ AC_CACHE_CHECK([whether the compiler provides atomic builtins],
[svn_cv_atomic_builtins],
+ [AC_TRY_RUN([
+ int main()
+ {
+ unsigned long long val = 1010, tmp, *mem = &val;
+
+ if (__sync_fetch_and_add(&val, 1010) != 1010 || val != 2020)
+ return 1;
+
+ tmp = val;
+
+ if (__sync_fetch_and_sub(mem, 1010) != tmp || val != 1010)
+ return 1;
+
+ if (__sync_sub_and_fetch(&val, 1010) != 0 || val != 0)
+ return 1;
+
+ tmp = 3030;
+
+ if (__sync_val_compare_and_swap(mem, 0, tmp) != 0 || val != tmp)
+ return 1;
+
+ if (__sync_lock_test_and_set(&val, 4040) != 3030)
+ return 1;
+
+ mem = &tmp;
+
+ if (__sync_val_compare_and_swap(&mem, &tmp, &val) != &tmp)
+ return 1;
+
+ __sync_synchronize();
+
+ if (mem != &val)
+ return 1;
+
+ return 0;
+ }], [svn_cv_atomic_builtins=yes], [svn_cv_atomic_builtins=no],
[svn_cv_atomic_builtins=no])])
+])
Modified: subversion/trunk/configure.ac
URL:
http://svn.apache.org/viewvc/subversion/trunk/configure.ac?rev=1326307&r1=1326306&r2=1326307&view=diff
==============================================================================
--- subversion/trunk/configure.ac (original)
+++ subversion/trunk/configure.ac Sun Apr 15 11:20:58 2012
@@ -184,6 +184,12 @@ if test -n "$sqlite_compat_ver" && test
CFLAGS="-DSVN_SQLITE_MIN_VERSION_NUMBER=$sqlite_compat_ver_num $CFLAGS"
fi
+SVN_CHECK_FOR_ATOMIC_BUILTINS
+
+if test "$svn_cv_atomic_builtins" = "yes"; then
+ AC_DEFINE(SVN_HAS_ATOMIC_BUILTINS, 1, [Define if compiler provides atomic
builtins])
+fi
+
dnl Set up a number of directories ---------------------
dnl Create SVN_BINDIR for proper substitution
@@ -825,7 +831,7 @@ dnl Build and install rules ------------
INSTALL_STATIC_RULES="install-bin install-docs"
INSTALL_RULES="install-fsmod-lib install-ramod-lib install-lib install-include
install-static"
INSTALL_RULES="$INSTALL_RULES $INSTALL_APACHE_RULE"
-BUILD_RULES="fsmod-lib ramod-lib lib bin test $BUILD_APACHE_RULE tools"
+BUILD_RULES="fsmod-lib ramod-lib lib bin test sub-test $BUILD_APACHE_RULE
tools"
if test "$svn_lib_berkeley_db" = "yes"; then
BUILD_RULES="$BUILD_RULES bdb-lib bdb-test"
Modified: subversion/trunk/subversion/include/svn_error_codes.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_error_codes.h?rev=1326307&r1=1326306&r2=1326307&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_error_codes.h (original)
+++ subversion/trunk/subversion/include/svn_error_codes.h Sun Apr 15 11:20:58
2012
@@ -224,6 +224,11 @@ SVN_ERROR_START
SVN_ERR_BAD_CATEGORY_START + 14,
"Invalid changelist name")
+ /** @since New in 1.8. */
+ SVN_ERRDEF(SVN_ERR_BAD_ATOMIC,
+ SVN_ERR_BAD_CATEGORY_START + 15,
+ "Invalid atomic")
+
/* xml errors */
SVN_ERRDEF(SVN_ERR_XML_ATTRIB_NOT_FOUND,
Modified: subversion/trunk/subversion/include/svn_fs.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_fs.h?rev=1326307&r1=1326306&r2=1326307&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_fs.h (original)
+++ subversion/trunk/subversion/include/svn_fs.h Sun Apr 15 11:20:58 2012
@@ -85,6 +85,12 @@ typedef struct svn_fs_t svn_fs_t;
*/
#define SVN_FS_CONFIG_FSFS_CACHE_FULLTEXTS "fsfs-cache-fulltexts"
+/** Enable / disable revprop caching for a FSFS repository.
+ *
+ * @since New in 1.8.
+ */
+#define SVN_FS_CONFIG_FSFS_CACHE_REVPROPS "fsfs-cache-revprops"
+
/* See also svn_fs_type(). */
/** @since New in 1.1. */
#define SVN_FS_CONFIG_FS_TYPE "fs-type"
Modified: subversion/trunk/subversion/include/svn_io.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_io.h?rev=1326307&r1=1326306&r2=1326307&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_io.h (original)
+++ subversion/trunk/subversion/include/svn_io.h Sun Apr 15 11:20:58 2012
@@ -682,6 +682,39 @@ svn_io_file_lock2(const char *lock_file,
svn_boolean_t exclusive,
svn_boolean_t nonblocking,
apr_pool_t *pool);
+
+/**
+ * Lock the file @a lockfile_handle. If @a exclusive is TRUE,
+ * obtain exclusive lock, otherwise obtain shared lock.
+ *
+ * If @a nonblocking is TRUE, do not wait for the lock if it
+ * is not available: throw an error instead.
+ *
+ * Lock will be automatically released when @a pool is cleared or destroyed.
+ * You may also explicitly call @ref svn_io_unlock_open_file.
+ * Use @a pool for memory allocations. @a pool must be the pool that
+ * @a lockfile_handle has been created in or one of its sub-pools.
+ *
+ * @since New in 1.8.
+ */
+svn_error_t *
+svn_io_lock_open_file(apr_file_t *lockfile_handle,
+ svn_boolean_t exclusive,
+ svn_boolean_t nonblocking,
+ apr_pool_t *pool);
+
+/**
+ * Unlock the file @a lockfile_handle.
+ *
+ * Use @a pool for memory allocations. @a pool must be the pool that
+ * @a lockfile_handle has been created in or one of its sub-pools.
+ *
+ * @since New in 1.8.
+ */
+svn_error_t *
+svn_io_unlock_open_file(apr_file_t *lockfile_handle,
+ apr_pool_t *pool);
+
/**
* Flush any unwritten data from @a file to disk. Use @a pool for
* memory allocations.
Modified: subversion/trunk/subversion/libsvn_fs_fs/caching.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/caching.c?rev=1326307&r1=1326306&r2=1326307&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_fs/caching.c (original)
+++ subversion/trunk/subversion/libsvn_fs_fs/caching.c Sun Apr 15 11:20:58 2012
@@ -44,6 +44,7 @@ read_config(svn_memcache_t **memcache_p,
svn_boolean_t *fail_stop,
svn_boolean_t *cache_txdeltas,
svn_boolean_t *cache_fulltexts,
+ svn_boolean_t *cache_revprops,
svn_fs_t *fs,
apr_pool_t *pool)
{
@@ -74,6 +75,16 @@ read_config(svn_memcache_t **memcache_p,
SVN_FS_CONFIG_FSFS_CACHE_FULLTEXTS,
TRUE);
+ /* don't cache revprops by default.
+ * Revprop caching significantly speeds up operations like
+ * svn ls -v. However, it requires synchronization that may
+ * not be available or efficient in the current server setup.
+ */
+ *cache_revprops
+ = svn_hash__get_bool(fs->config,
+ SVN_FS_CONFIG_FSFS_CACHE_REVPROPS,
+ FALSE);
+
return svn_config_get_bool(ffd->config, fail_stop,
CONFIG_SECTION_CACHES, CONFIG_OPTION_FAIL_STOP,
FALSE);
@@ -249,12 +260,14 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
svn_boolean_t no_handler;
svn_boolean_t cache_txdeltas;
svn_boolean_t cache_fulltexts;
+ svn_boolean_t cache_revprops;
/* Evaluating the cache configuration. */
SVN_ERR(read_config(&memcache,
&no_handler,
&cache_txdeltas,
&cache_fulltexts,
+ &cache_revprops,
fs,
pool));
@@ -339,6 +352,27 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
SVN_ERR(init_callbacks(ffd->fulltext_cache, fs, no_handler, pool));
+ /* initialize revprop cache, if full-text caching has been enabled */
+ if (cache_revprops)
+ {
+ SVN_ERR(create_cache(&(ffd->revprop_cache),
+ NULL,
+ membuffer,
+ 0, 0, /* Do not use inprocess cache */
+ svn_fs_fs__serialize_properties,
+ svn_fs_fs__deserialize_properties,
+ APR_HASH_KEY_STRING,
+ apr_pstrcat(pool, prefix, "REVPROP",
+ (char *)NULL),
+ fs->pool));
+ }
+ else
+ {
+ ffd->revprop_cache = NULL;
+ }
+
+ SVN_ERR(init_callbacks(ffd->revprop_cache, fs, no_handler, pool));
+
/* initialize txdelta window cache, if that has been enabled */
if (cache_txdeltas)
{
Modified: subversion/trunk/subversion/libsvn_fs_fs/fs.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/fs.h?rev=1326307&r1=1326306&r2=1326307&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_fs/fs.h (original)
+++ subversion/trunk/subversion/libsvn_fs_fs/fs.h Sun Apr 15 11:20:58 2012
@@ -34,6 +34,7 @@
#include "private/svn_fs_private.h"
#include "private/svn_sqlite.h"
#include "private/svn_mutex.h"
+#include "private/svn_named_atomic.h"
#ifdef __cplusplus
extern "C" {
@@ -207,7 +208,8 @@ typedef struct fs_fs_shared_data_t
apr_pool_t *common_pool;
} fs_fs_shared_data_t;
-/* Private (non-shared) FSFS-specific data for each svn_fs_t object. */
+/* Private (non-shared) FSFS-specific data for each svn_fs_t object.
+ Any caches in here may be NULL. */
typedef struct fs_fs_data_t
{
/* The format number of this FS. */
@@ -246,6 +248,17 @@ typedef struct fs_fs_data_t
rep key (revision/offset) to svn_string_t. */
svn_cache__t *fulltext_cache;
+ /* Access object to the revprop "generation". Will be NULL until
+ the first access. */
+ svn_named_atomic__t *revprop_generation;
+
+ /* Access object to the revprop update timeout. Will be NULL until
+ the first access. */
+ svn_named_atomic__t *revprop_timeout;
+
+ /* Revision property cache. Maps from (rev,generation) to apr_hash_t. */
+ svn_cache__t *revprop_cache;
+
/* Pack manifest cache; a cache mapping (svn_revnum_t) shard number to
a manifest; and a manifest is a mapping from (svn_revnum_t) revision
number offset within a shard to (apr_off_t) byte-offset in the
Modified: subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c?rev=1326307&r1=1326306&r2=1326307&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c Sun Apr 15 11:20:58 2012
@@ -92,6 +92,16 @@
Values < 1 disable deltification. */
#define SVN_FS_FS_MAX_DELTIFICATION_WALK 1023
+/* Give writing processes 10 seconds to replace an existing revprop
+ file with a new one. After that time, we assume that the writing
+ process got aborted and that we have re-read revprops. */
+#define REVPROP_CHANGE_TIMEOUT 10 * 1000000
+
+/* The following are names of atomics that will be used to communicate
+ * revprop updates across all processes on this machine. */
+#define ATOMIC_REVPROP_GENERATION "RevPropGeneration"
+#define ATOMIC_REVPROP_TIMEOUT "RevPropTimeout"
+
/* Following are defines that specify the textual elements of the
native filesystem directories and revision files. */
@@ -870,25 +880,39 @@ get_file_offset(apr_off_t *offset_p, apr
}
-/* Check that BUF, a nul-terminated buffer of text from format file PATH,
+/* Check that BUF, a nul-terminated buffer of text from file PATH,
contains only digits at OFFSET and beyond, raising an error if not.
+ TITLE contains a user-visible description of the file, usually the
+ short file name.
Uses POOL for temporary allocation. */
static svn_error_t *
-check_format_file_buffer_numeric(const char *buf, apr_off_t offset,
- const char *path, apr_pool_t *pool)
+check_file_buffer_numeric(const char *buf, apr_off_t offset,
+ const char *path, const char *title,
+ apr_pool_t *pool)
{
const char *p;
for (p = buf + offset; *p; p++)
if (!svn_ctype_isdigit(*p))
return svn_error_createf(SVN_ERR_BAD_VERSION_FILE_FORMAT, NULL,
- _("Format file '%s' contains unexpected non-digit '%c' within '%s'"),
- svn_dirent_local_style(path, pool), *p, buf);
+ _("%s file '%s' contains unexpected non-digit '%c' within '%s'"),
+ title, svn_dirent_local_style(path, pool), *p, buf);
return SVN_NO_ERROR;
}
+/* Check that BUF, a nul-terminated buffer of text from format file PATH,
+ contains only digits at OFFSET and beyond, raising an error if not.
+
+ Uses POOL for temporary allocation. */
+static svn_error_t *
+check_format_file_buffer_numeric(const char *buf, apr_off_t offset,
+ const char *path, apr_pool_t *pool)
+{
+ return check_file_buffer_numeric(buf, offset, path, "Format", pool);
+}
+
/* Read the format number and maximum number of files per directory
from PATH and return them in *PFORMAT and *MAX_FILES_PER_DIR
respectively.
@@ -2775,6 +2799,160 @@ svn_fs_fs__rev_get_root(svn_fs_id_t **ro
return SVN_NO_ERROR;
}
+/* Make sure the revprop_generation member in FS is set. */
+static svn_error_t *
+ensure_revprop_generation(svn_fs_t *fs)
+{
+ fs_fs_data_t *ffd = fs->fsap_data;
+
+ return ffd->revprop_generation == NULL
+ ? svn_named_atomic__get(&ffd->revprop_generation,
+ NULL,
+ ATOMIC_REVPROP_GENERATION,
+ TRUE)
+ : SVN_NO_ERROR;
+}
+
+/* Make sure the revprop_timeout member in FS is set. */
+static svn_error_t *
+ensure_revprop_timeout(svn_fs_t *fs)
+{
+ fs_fs_data_t *ffd = fs->fsap_data;
+
+ return ffd->revprop_timeout == NULL
+ ? svn_named_atomic__get(&ffd->revprop_timeout,
+ NULL,
+ ATOMIC_REVPROP_TIMEOUT,
+ TRUE)
+ : SVN_NO_ERROR;
+}
+
+/* Test whether revprop cache and necessary infrastructure are
+ available in FS. */
+static svn_boolean_t
+has_revprop_cache(svn_fs_t *fs)
+{
+ fs_fs_data_t *ffd = fs->fsap_data;
+ svn_error_t *error;
+
+ /* is the cache (still) enabled? */
+ if (ffd->revprop_cache == NULL)
+ return FALSE;
+
+ /* try to access our SHM-backed infrastructure */
+ error = ensure_revprop_generation(fs);
+ if (error)
+ {
+ /* failure -> disable revprop cache for good */
+
+ svn_error_clear(error);
+ ffd->revprop_cache = NULL;
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Read the current revprop generation and return it in *GENERATION.
+ Also, detect aborted / crashed writers and recover from that.
+ Use the access object in FS to set the shared mem values. */
+static svn_error_t *
+read_revprop_generation(svn_fs_t *fs,
+ apr_int64_t *generation)
+{
+ apr_int64_t current = 0;
+ fs_fs_data_t *ffd = fs->fsap_data;
+
+ /* read the current revprop generation number */
+ SVN_ERR(ensure_revprop_generation(fs));
+ SVN_ERR(svn_named_atomic__read(¤t, ffd->revprop_generation));
+
+ /* is an unfinished revprop write under the way? */
+ if (current % 2)
+ {
+ apr_int64_t timeout = 0;
+
+ /* read timeout for the write operation */
+ SVN_ERR(ensure_revprop_timeout(fs));
+ SVN_ERR(svn_named_atomic__read(&timeout, ffd->revprop_timeout));
+
+ /* has the writer process been aborted,
+ * i.e. has the timeout been reached?
+ */
+ if (apr_time_now() > timeout)
+ {
+ /* Cause everyone to re-read revprops upon their next access.
+ * Keep in mind that we may not be the only one trying to do it.
+ */
+ while (current % 2)
+ SVN_ERR(svn_named_atomic__add(¤t,
+ 1,
+ ffd->revprop_generation));
+ }
+ }
+
+ /* return the value we just got */
+ *generation = current;
+ return SVN_NO_ERROR;
+}
+
+/* Set the revprop generation to the next odd number to indicate that
+ there is a revprop write process under way. If that times out,
+ readers shall recover from that state & re-read revprops.
+ Use the access object in FS to set the shared mem value. */
+static svn_error_t *
+begin_revprop_change(svn_fs_t *fs)
+{
+ apr_int64_t current;
+ fs_fs_data_t *ffd = fs->fsap_data;
+
+ /* set the timeout for the write operation */
+ SVN_ERR(ensure_revprop_timeout(fs));
+ SVN_ERR(svn_named_atomic__write(NULL,
+ apr_time_now() + REVPROP_CHANGE_TIMEOUT,
+ ffd->revprop_timeout));
+
+ /* set the revprop generation to an odd value to indicate
+ * that a write is in progress
+ */
+ SVN_ERR(ensure_revprop_generation(fs));
+ do
+ {
+ SVN_ERR(svn_named_atomic__add(¤t,
+ 1,
+ ffd->revprop_generation));
+ }
+ while (current % 2 == 0);
+
+ return SVN_NO_ERROR;
+}
+
+/* Set the revprop generation to the next even number to indicate that
+ a) readers shall re-read revprops, and
+ b) the write process has been completed (no recovery required)
+ Use the access object in FS to set the shared mem value. */
+static svn_error_t *
+end_revprop_change(svn_fs_t *fs)
+{
+ apr_int64_t current = 1;
+ fs_fs_data_t *ffd = fs->fsap_data;
+
+ /* set the revprop generation to an even value to indicate
+ * that a write has been completed
+ */
+ SVN_ERR(ensure_revprop_generation(fs));
+ do
+ {
+ SVN_ERR(svn_named_atomic__add(¤t,
+ 1,
+ ffd->revprop_generation));
+ }
+ while (current % 2);
+
+ return SVN_NO_ERROR;
+}
+
/* Set the revision property list of revision REV in filesystem FS to
PROPLIST. Use POOL for temporary allocations. */
static svn_error_t *
@@ -2791,6 +2969,11 @@ set_revision_proplist(svn_fs_t *fs,
const char *tmp_path;
const char *perms_reference;
svn_stream_t *stream;
+ svn_node_kind_t kind = svn_node_none;
+
+ /* test whether revprops already exist for this revision */
+ if (has_revprop_cache(fs))
+ SVN_ERR(svn_io_check_path(final_path, &kind, pool));
/* ### do we have a directory sitting around already? we really shouldn't
### have to get the dirname here. */
@@ -2805,7 +2988,17 @@ set_revision_proplist(svn_fs_t *fs,
file won't exist and therefore can't serve as its own reference.
(Whereas the rev file should already exist at this point.) */
SVN_ERR(svn_fs_fs__path_rev_absolute(&perms_reference, fs, rev, pool));
+
+ /* Now, we may actually be replacing revprops. Make sure that all other
+ threads and processes will know about this. */
+ if (kind != svn_node_none)
+ SVN_ERR(begin_revprop_change(fs));
+
SVN_ERR(move_into_place(tmp_path, final_path, perms_reference, pool));
+
+ /* Indicate that the update (if relevant) has been completed. */
+ if (kind != svn_node_none)
+ SVN_ERR(end_revprop_change(fs));
}
return SVN_NO_ERROR;
@@ -2818,9 +3011,26 @@ revision_proplist(apr_hash_t **proplist_
apr_pool_t *pool)
{
apr_hash_t *proplist;
+ fs_fs_data_t *ffd = fs->fsap_data;
+ const char *key;
SVN_ERR(ensure_revision_exists(fs, rev, pool));
+ /* Try cache lookup first. */
+ if (has_revprop_cache(fs))
+ {
+ apr_int64_t generation;
+ svn_boolean_t is_cached;
+
+ SVN_ERR(read_revprop_generation(fs, &generation));
+
+ key = svn_fs_fs__combine_two_numbers(rev, generation, pool);
+ SVN_ERR(svn_cache__get((void **) proplist_p, &is_cached,
+ ffd->revprop_cache, key, pool));
+ if (is_cached)
+ return SVN_NO_ERROR;
+ }
+
/* if (1); null condition for easier merging to revprop-packing */
{
apr_file_t *revprop_file = NULL;
@@ -2875,6 +3085,10 @@ revision_proplist(apr_hash_t **proplist_
svn_pool_destroy(iterpool);
}
+ /* Cache the result, if caching has been activated. */
+ if (has_revprop_cache(fs))
+ SVN_ERR(svn_cache__set(ffd->revprop_cache, key, proplist, pool));
+
*proplist_p = proplist;
return SVN_NO_ERROR;
Modified: subversion/trunk/subversion/libsvn_subr/io.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/io.c?rev=1326307&r1=1326306&r2=1326307&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/io.c (original)
+++ subversion/trunk/subversion/libsvn_subr/io.c Sun Apr 15 11:20:58 2012
@@ -1866,29 +1866,23 @@ file_clear_locks(void *arg)
#endif
svn_error_t *
-svn_io_file_lock2(const char *lock_file,
- svn_boolean_t exclusive,
- svn_boolean_t nonblocking,
- apr_pool_t *pool)
+svn_io_lock_open_file(apr_file_t *lockfile_handle,
+ svn_boolean_t exclusive,
+ svn_boolean_t nonblocking,
+ apr_pool_t *pool)
{
int locktype = APR_FLOCK_SHARED;
- apr_file_t *lockfile_handle;
- apr_int32_t flags;
apr_status_t apr_err;
+ const char *fname;
if (exclusive)
locktype = APR_FLOCK_EXCLUSIVE;
-
- flags = APR_READ;
- if (locktype == APR_FLOCK_EXCLUSIVE)
- flags |= APR_WRITE;
-
if (nonblocking)
locktype |= APR_FLOCK_NONBLOCK;
- SVN_ERR(svn_io_file_open(&lockfile_handle, lock_file, flags,
- APR_OS_DEFAULT,
- pool));
+ /* We need this only in case of an error but this is cheap to get -
+ * so we do it here for clarity. */
+ apr_err = apr_file_name_get(&fname, lockfile_handle);
/* Get lock on the filehandle. */
apr_err = apr_file_lock(lockfile_handle, locktype);
@@ -1915,11 +1909,11 @@ svn_io_file_lock2(const char *lock_file,
case APR_FLOCK_SHARED:
return svn_error_wrap_apr(apr_err,
_("Can't get shared lock on file '%s'"),
- svn_dirent_local_style(lock_file, pool));
+ svn_dirent_local_style(fname, pool));
case APR_FLOCK_EXCLUSIVE:
return svn_error_wrap_apr(apr_err,
_("Can't get exclusive lock on file '%s'"),
- svn_dirent_local_style(lock_file, pool));
+ svn_dirent_local_style(fname, pool));
default:
SVN_ERR_MALFUNCTION();
}
@@ -1936,6 +1930,58 @@ svn_io_file_lock2(const char *lock_file,
return SVN_NO_ERROR;
}
+svn_error_t *
+svn_io_unlock_open_file(apr_file_t *lockfile_handle,
+ apr_pool_t *pool)
+{
+ const char *fname;
+ apr_status_t apr_err = apr_file_unlock(lockfile_handle);
+
+ /* We need this only in case of an error but this is cheap to get -
+ * so we do it here for clarity. */
+ apr_err = apr_file_name_get(&fname, lockfile_handle);
+
+/* On Windows and OS/2 file locks are automatically released when
+ the file handle closes */
+#if !defined(WIN32) && !defined(__OS2__)
+ apr_pool_cleanup_kill(pool, lockfile_handle, file_clear_locks);
+#endif
+
+ return apr_err
+ ? svn_error_wrap_apr(apr_err, _("Can't unlock file '%s'"),
+ svn_dirent_local_style(fname, pool))
+ : SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_io_file_lock2(const char *lock_file,
+ svn_boolean_t exclusive,
+ svn_boolean_t nonblocking,
+ apr_pool_t *pool)
+{
+ int locktype = APR_FLOCK_SHARED;
+ apr_file_t *lockfile_handle;
+ apr_int32_t flags;
+ apr_status_t apr_err;
+
+ if (exclusive)
+ locktype = APR_FLOCK_EXCLUSIVE;
+
+ flags = APR_READ;
+ if (locktype == APR_FLOCK_EXCLUSIVE)
+ flags |= APR_WRITE;
+
+ if (nonblocking)
+ locktype |= APR_FLOCK_NONBLOCK;
+
+ SVN_ERR(svn_io_file_open(&lockfile_handle, lock_file, flags,
+ APR_OS_DEFAULT,
+ pool));
+
+ /* Get lock on the filehandle. */
+ return svn_io_lock_open_file(lockfile_handle, exclusive, nonblocking, pool);
+}
+
/* Data consistency/coherency operations. */
Modified: subversion/trunk/subversion/mod_dav_svn/dav_svn.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/mod_dav_svn/dav_svn.h?rev=1326307&r1=1326306&r2=1326307&view=diff
==============================================================================
--- subversion/trunk/subversion/mod_dav_svn/dav_svn.h (original)
+++ subversion/trunk/subversion/mod_dav_svn/dav_svn.h Sun Apr 15 11:20:58 2012
@@ -316,6 +316,9 @@ svn_boolean_t dav_svn__get_txdelta_cache
/* for the repository referred to by this request, is fulltext caching active?
*/
svn_boolean_t dav_svn__get_fulltext_cache_flag(request_rec *r);
+/* for the repository referred to by this request, is revprop caching active?
*/
+svn_boolean_t dav_svn__get_revprop_cache_flag(request_rec *r);
+
/* for the repository referred to by this request, are subrequests bypassed?
* A function pointer if yes, NULL if not.
*/
Modified: subversion/trunk/subversion/mod_dav_svn/mod_dav_svn.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/mod_dav_svn/mod_dav_svn.c?rev=1326307&r1=1326306&r2=1326307&view=diff
==============================================================================
--- subversion/trunk/subversion/mod_dav_svn/mod_dav_svn.c (original)
+++ subversion/trunk/subversion/mod_dav_svn/mod_dav_svn.c Sun Apr 15 11:20:58
2012
@@ -95,6 +95,7 @@ typedef struct dir_conf_t {
const char *activities_db; /* path to activities database(s) */
enum conf_flag txdelta_cache; /* whether to enable txdelta caching */
enum conf_flag fulltext_cache; /* whether to enable fulltext caching */
+ enum conf_flag revprop_cache; /* whether to enable revprop caching */
apr_hash_t *hooks_env; /* environment for hook scripts */
} dir_conf_t;
@@ -224,6 +225,7 @@ merge_dir_config(apr_pool_t *p, void *ba
newconf->list_parentpath = INHERIT_VALUE(parent, child, list_parentpath);
newconf->txdelta_cache = INHERIT_VALUE(parent, child, txdelta_cache);
newconf->fulltext_cache = INHERIT_VALUE(parent, child, fulltext_cache);
+ newconf->revprop_cache = INHERIT_VALUE(parent, child, revprop_cache);
newconf->root_dir = INHERIT_VALUE(parent, child, root_dir);
newconf->hooks_env = INHERIT_VALUE(parent, child, hooks_env);
@@ -476,6 +478,19 @@ SVNCacheFullTexts_cmd(cmd_parms *cmd, vo
}
static const char *
+SVNCacheRevProps_cmd(cmd_parms *cmd, void *config, int arg)
+{
+ dir_conf_t *conf = config;
+
+ if (arg)
+ conf->revprop_cache = CONF_FLAG_ON;
+ else
+ conf->revprop_cache = CONF_FLAG_OFF;
+
+ return NULL;
+}
+
+static const char *
SVNInMemoryCacheSize_cmd(cmd_parms *cmd, void *config, const char *arg1)
{
svn_cache_config_t settings = *svn_cache_config_get();
@@ -847,6 +862,16 @@ dav_svn__get_fulltext_cache_flag(request
}
+svn_boolean_t
+dav_svn__get_revprop_cache_flag(request_rec *r)
+{
+ dir_conf_t *conf;
+
+ conf = ap_get_module_config(r->per_dir_config, &dav_svn_module);
+ return conf->revprop_cache == CONF_FLAG_ON;
+}
+
+
int
dav_svn__get_compression_level(void)
{
@@ -1083,6 +1108,14 @@ static const command_rec cmds[] =
"if sufficient in-memory cache is available "
"(default is Off)."),
+ /* per directory/location */
+ AP_INIT_FLAG("SVNCacheRevProps", SVNCacheRevProps_cmd, NULL,
+ ACCESS_CONF|RSRC_CONF,
+ "speeds up 'svn ls -v', export and checkout operations"
+ "but should only be enabled under the conditions described"
+ "in the documentation"
+ "(default is Off)."),
+
/* per server */
AP_INIT_TAKE1("SVNInMemoryCacheSize", SVNInMemoryCacheSize_cmd, NULL,
RSRC_CONF,
Modified: subversion/trunk/subversion/mod_dav_svn/repos.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/mod_dav_svn/repos.c?rev=1326307&r1=1326306&r2=1326307&view=diff
==============================================================================
--- subversion/trunk/subversion/mod_dav_svn/repos.c (original)
+++ subversion/trunk/subversion/mod_dav_svn/repos.c Sun Apr 15 11:20:58 2012
@@ -2154,6 +2154,10 @@ get_resource(request_rec *r,
SVN_FS_CONFIG_FSFS_CACHE_FULLTEXTS,
APR_HASH_KEY_STRING,
dav_svn__get_fulltext_cache_flag(r) ? "1" : "0");
+ apr_hash_set(fs_config,
+ SVN_FS_CONFIG_FSFS_CACHE_REVPROPS,
+ APR_HASH_KEY_STRING,
+ dav_svn__get_revprop_cache_flag(r) ? "1" : "0");
/* open the FS */
serr = svn_repos_open2(&(repos->repos), fs_path, fs_config,
Modified: subversion/trunk/subversion/svnadmin/main.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/svnadmin/main.c?rev=1326307&r1=1326306&r2=1326307&view=diff
==============================================================================
--- subversion/trunk/subversion/svnadmin/main.c (original)
+++ subversion/trunk/subversion/svnadmin/main.c Sun Apr 15 11:20:58 2012
@@ -108,12 +108,14 @@ open_repos(svn_repos_t **repos,
const char *path,
apr_pool_t *pool)
{
- /* construct FS configuration parameters: enable all available caches */
+ /* construct FS configuration parameters: enable caches for r/o data */
apr_hash_t *fs_config = apr_hash_make(pool);
apr_hash_set(fs_config, SVN_FS_CONFIG_FSFS_CACHE_DELTAS,
APR_HASH_KEY_STRING, "1");
apr_hash_set(fs_config, SVN_FS_CONFIG_FSFS_CACHE_FULLTEXTS,
APR_HASH_KEY_STRING, "1");
+ apr_hash_set(fs_config, SVN_FS_CONFIG_FSFS_CACHE_REVPROPS,
+ APR_HASH_KEY_STRING, "0");
/* now, open the requested repository */
SVN_ERR(svn_repos_open2(repos, path, fs_config, pool));
Modified: subversion/trunk/subversion/svnserve/main.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/svnserve/main.c?rev=1326307&r1=1326306&r2=1326307&view=diff
==============================================================================
--- subversion/trunk/subversion/svnserve/main.c (original)
+++ subversion/trunk/subversion/svnserve/main.c Sun Apr 15 11:20:58 2012
@@ -147,7 +147,8 @@ void winservice_notify_stop(void)
#define SVNSERVE_OPT_LOG_FILE 264
#define SVNSERVE_OPT_CACHE_TXDELTAS 265
#define SVNSERVE_OPT_CACHE_FULLTEXTS 266
-#define SVNSERVE_OPT_SINGLE_CONN 267
+#define SVNSERVE_OPT_CACHE_REVPROPS 267
+#define SVNSERVE_OPT_SINGLE_CONN 268
static const apr_getopt_option_t svnserve__options[] =
{
@@ -222,6 +223,14 @@ static const apr_getopt_option_t svnserv
"Default is yes.\n"
" "
"[used for FSFS repositories only]")},
+ {"cache-revprops", SVNSERVE_OPT_CACHE_REVPROPS, 1,
+ N_("enable or disable caching of revision properties.\n"
+ " "
+ "Consult the documentation before activating this.\n"
+ " "
+ "Default is no.\n"
+ " "
+ "[used for FSFS repositories only]")},
#ifdef CONNECTION_HAVE_THREAD_OPTION
/* ### Making the assumption here that WIN32 never has fork and so
* ### this option never exists when --service exists. */
@@ -482,6 +491,7 @@ int main(int argc, const char *argv[])
params.memory_cache_size = (apr_uint64_t)-1;
params.cache_fulltexts = TRUE;
params.cache_txdeltas = FALSE;
+ params.cache_revprops = FALSE;
while (1)
{
@@ -625,6 +635,11 @@ int main(int argc, const char *argv[])
= svn_tristate__from_word(arg) == svn_tristate_true;
break;
+ case SVNSERVE_OPT_CACHE_REVPROPS:
+ params.cache_revprops
+ = svn_tristate__from_word(arg) == svn_tristate_true;
+ break;
+
#ifdef WIN32
case SVNSERVE_OPT_SERVICE:
if (run_mode != run_mode_service)
Modified: subversion/trunk/subversion/svnserve/serve.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/svnserve/serve.c?rev=1326307&r1=1326306&r2=1326307&view=diff
==============================================================================
--- subversion/trunk/subversion/svnserve/serve.c (original)
+++ subversion/trunk/subversion/svnserve/serve.c Sun Apr 15 11:20:58 2012
@@ -3249,6 +3249,8 @@ svn_error_t *serve(svn_ra_svn_conn_t *co
APR_HASH_KEY_STRING, params->cache_txdeltas ? "1" : "0");
apr_hash_set(b.fs_config, SVN_FS_CONFIG_FSFS_CACHE_FULLTEXTS,
APR_HASH_KEY_STRING, params->cache_fulltexts ? "1" : "0");
+ apr_hash_set(b.fs_config, SVN_FS_CONFIG_FSFS_CACHE_REVPROPS,
+ APR_HASH_KEY_STRING, params->cache_revprops ? "1" : "0");
/* Send greeting. We don't support version 1 any more, so we can
* send an empty mechlist. */
Modified: subversion/trunk/subversion/svnserve/server.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/svnserve/server.h?rev=1326307&r1=1326306&r2=1326307&view=diff
==============================================================================
--- subversion/trunk/subversion/svnserve/server.h (original)
+++ subversion/trunk/subversion/svnserve/server.h Sun Apr 15 11:20:58 2012
@@ -116,6 +116,9 @@ typedef struct serve_params_t {
/* Enable full-text caching for all FSFS repositories. */
svn_boolean_t cache_fulltexts;
+ /* Enable revprop caching for all FSFS repositories. */
+ svn_boolean_t cache_revprops;
+
/* Size of the in-memory cache (used by FSFS only). */
apr_uint64_t memory_cache_size;
Modified: subversion/trunk/subversion/tests/libsvn_repos/repos-test.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_repos/repos-test.c?rev=1326307&r1=1326306&r2=1326307&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_repos/repos-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_repos/repos-test.c Sun Apr 15
11:20:58 2012
@@ -1318,9 +1318,8 @@ authz(apr_pool_t *pool)
contents =
"[greek:/dir2//secret]" NL
"* ="
NL;
- err = authz_get_handle(&authz_cfg, contents, subpool);
- SVN_TEST_ASSERT_ERROR(err, SVN_ERR_AUTHZ_INVALID_CONFIG);
- svn_error_clear(err);
+ SVN_TEST_ASSERT_ERROR(authz_get_handle(&authz_cfg, contents, subpool),
+ SVN_ERR_AUTHZ_INVALID_CONFIG);
/* That's a wrap! */
svn_pool_destroy(subpool);
@@ -1480,10 +1479,7 @@ test_path_authz(svn_repos_t *repos,
/* Check for potential errors. */
if (path_action->authz_error_expected)
- {
- SVN_TEST_ASSERT_ERROR(err, SVN_ERR_AUTHZ_UNWRITABLE);
- svn_error_clear(err);
- }
+ SVN_TEST_ASSERT_ERROR(err, SVN_ERR_AUTHZ_UNWRITABLE);
else
SVN_ERR(err);
Propchange: subversion/trunk/subversion/tests/libsvn_subr/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Sun Apr 15 11:20:58 2012
@@ -36,3 +36,5 @@ auth-test
eol-test
subst_translate-test
spillbuf-test
+named_atomic-test
+named_atomic-test-proc
Copied: subversion/trunk/subversion/tests/libsvn_subr/named_atomic-test.c (from
r1326293,
subversion/branches/revprop-cache/subversion/tests/libsvn_subr/named_atomic-test.c)
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_subr/named_atomic-test.c?p2=subversion/trunk/subversion/tests/libsvn_subr/named_atomic-test.c&p1=subversion/branches/revprop-cache/subversion/tests/libsvn_subr/named_atomic-test.c&r1=1326293&r2=1326307&rev=1326307&view=diff
==============================================================================
---
subversion/branches/revprop-cache/subversion/tests/libsvn_subr/named_atomic-test.c
(original)
+++ subversion/trunk/subversion/tests/libsvn_subr/named_atomic-test.c Sun Apr
15 11:20:58 2012
@@ -289,6 +289,13 @@ calibrate_concurrency(apr_pool_t *pool)
{
if (hw_thread_count == 0)
{
+ int i = 0;
+ for (i = 0; i < 100000; ++i)
+ {
+ printf("%8d", i);
+ SVN_ERR(init_concurrency_test_shm(pool, 2));
+ SVN_ERR(run_procs(pool, TEST_PROC, 2, 100000));
+ }
SVN_ERR(calibrate_iterations(pool, 2));
for (hw_thread_count = 2; hw_thread_count < 32; hw_thread_count *= 2)
{
Modified: subversion/trunk/subversion/tests/svn_test.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/svn_test.h?rev=1326307&r1=1326306&r2=1326307&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/svn_test.h (original)
+++ subversion/trunk/subversion/tests/svn_test.h Sun Apr 15 11:20:58 2012
@@ -54,7 +54,9 @@ extern "C" {
} while (0)
/** Handy macro for testing an expected svn_error_t return value.
- * EXPECTED must be a real error (neither SVN_NO_ERROR nor APR_SUCCESS). */
+ * EXPECTED must be a real error (neither SVN_NO_ERROR nor APR_SUCCESS).
+ * The error returned by EXPR will be cleared.
+ */
#define SVN_TEST_ASSERT_ERROR(expr, expected) \
do { \
svn_error_t *err__ = (expr); \
@@ -68,6 +70,7 @@ extern "C" {
"Expected error %d but got %s", \
(expected), \
"SVN_NO_ERROR"); \
+ svn_error_clear(err__); \
} while (0)
/** Handy macro for testing string equality.