subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From stef...@apache.org
Subject svn commit: r1532250 [13/37] - in /subversion/branches/cache-server: ./ build/ build/ac-macros/ build/generator/ build/generator/swig/ build/generator/templates/ contrib/client-side/emacs/ contrib/hook-scripts/ contrib/server-side/fsfsfixer/ contrib/se...
Date Tue, 15 Oct 2013 08:52:18 GMT
Modified: subversion/branches/cache-server/subversion/libsvn_diff/parse-diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_diff/parse-diff.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_diff/parse-diff.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_diff/parse-diff.c Tue Oct 15 08:52:06 2013
@@ -25,6 +25,7 @@
 #include <stddef.h>
 #include <string.h>
 
+#include "svn_private_config.h"
 #include "svn_hash.h"
 #include "svn_types.h"
 #include "svn_error.h"
@@ -1146,8 +1147,9 @@ svn_diff_open_patch_file(svn_patch_file_
   svn_patch_file_t *p;
 
   p = apr_palloc(result_pool, sizeof(*p));
-  SVN_ERR(svn_io_file_open(&p->apr_file, local_abspath, APR_READ,
-                           APR_OS_DEFAULT, result_pool));
+  SVN_ERR(svn_io_file_open(&p->apr_file, local_abspath,
+                           APR_READ | APR_BUFFERED, APR_OS_DEFAULT,
+                           result_pool));
   p->next_patch_offset = 0;
   *patch_file = p;
 

Modified: subversion/branches/cache-server/subversion/libsvn_diff/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_diff/util.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_diff/util.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_diff/util.c Tue Oct 15 08:52:06 2013
@@ -25,6 +25,7 @@
 #include <apr.h>
 #include <apr_general.h>
 
+#include "svn_private_config.h"
 #include "svn_hash.h"
 #include "svn_pools.h"
 #include "svn_dirent_uri.h"
@@ -40,8 +41,6 @@
 #include "private/svn_diff_private.h"
 #include "diff.h"
 
-#include "svn_private_config.h"
-
 
 svn_boolean_t
 svn_diff_contains_conflicts(svn_diff_t *diff)

Modified: subversion/branches/cache-server/subversion/libsvn_fs/access.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_fs/access.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_fs/access.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_fs/access.c Tue Oct 15 08:52:06 2013
@@ -24,6 +24,7 @@
 
 #include <apr_hash.h>
 
+#include "svn_private_config.h"
 #include "svn_hash.h"
 #include "svn_types.h"
 #include "svn_pools.h"
@@ -33,7 +34,6 @@
 #include "fs-loader.h"
 
 
-
 svn_error_t *
 svn_fs_create_access(svn_fs_access_t **access_ctx,
                      const char *username,

Modified: subversion/branches/cache-server/subversion/libsvn_fs/editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_fs/editor.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_fs/editor.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_fs/editor.c Tue Oct 15 08:52:06 2013
@@ -177,7 +177,7 @@ can_modify(svn_fs_root_t *txn_root,
   SVN_ERR(svn_fs_node_created_rev(&created_rev, txn_root, fspath,
                                   scratch_pool));
 
-  /* Uncommitted nodes (eg. a descendent of a copy/move/rotate destination)
+  /* Uncommitted nodes (eg. a descendent of a copy/move destination)
      have no (committed) revision number. Let the caller go ahead and
      modify these nodes.
 
@@ -195,7 +195,7 @@ can_modify(svn_fs_root_t *txn_root,
      have supplied a valid revision number [that they expect to change].
      The checks further below will determine the out-of-dateness of the
      specified revision.  */
-  /* ### ugh. descendents of copy/move/rotate destinations carry along
+  /* ### ugh. descendents of copy/move destinations carry along
      ### their original immutable state and (thus) a valid CREATED_REV.
      ### but they are logically uncommitted, so the caller will pass
      ### SVN_INVALID_REVNUM. (technically, the caller could provide
@@ -205,7 +205,7 @@ can_modify(svn_fs_root_t *txn_root,
      ### for now, we will assume the caller knows what they are doing
      ### and an invalid revision implies such a descendent. in the
      ### future, we could examine the ancestor chain looking for a
-     ### copy/move/rotate-here node and allow the modification (and the
+     ### copy/move-here node and allow the modification (and the
      ### converse: if no such ancestor, the caller must specify the
      ### correct/intended revision to modify).
   */
@@ -299,7 +299,7 @@ can_create(svn_fs_root_t *txn_root,
      ### test the ancestor to determine if it has been *-here in this
      ### txn, or just a simple modification.  */
 
-  /* Are any of the parents copied/moved/rotated-here?  */
+  /* Are any of the parents copied/moved-here?  */
   for (cur_fspath = fspath;
        strlen(cur_fspath) > 1;  /* not the root  */
        cur_fspath = svn_fspath__dirname(cur_fspath, scratch_pool))
@@ -488,9 +488,9 @@ static svn_error_t *
 alter_file_cb(void *baton,
               const char *relpath,
               svn_revnum_t revision,
-              apr_hash_t *props,
               const svn_checksum_t *checksum,
               svn_stream_t *contents,
+              apr_hash_t *props,
               apr_pool_t *scratch_pool)
 {
   struct edit_baton *eb = baton;
@@ -521,8 +521,8 @@ static svn_error_t *
 alter_symlink_cb(void *baton,
                  const char *relpath,
                  svn_revnum_t revision,
-                 apr_hash_t *props,
                  const char *target,
+                 apr_hash_t *props,
                  apr_pool_t *scratch_pool)
 {
   struct edit_baton *eb = baton;
@@ -633,19 +633,6 @@ move_cb(void *baton,
 }
 
 
-/* This implements svn_editor_cb_rotate_t */
-static svn_error_t *
-rotate_cb(void *baton,
-          const apr_array_header_t *relpaths,
-          const apr_array_header_t *revisions,
-          apr_pool_t *scratch_pool)
-{
-  struct edit_baton *eb = baton;
-
-  UNUSED(eb); SVN__NOT_IMPLEMENTED();
-}
-
-
 /* This implements svn_editor_cb_complete_t */
 static svn_error_t *
 complete_cb(void *baton,
@@ -714,7 +701,6 @@ make_editor(svn_editor_t **editor,
     delete_cb,
     copy_cb,
     move_cb,
-    rotate_cb,
     complete_cb,
     abort_cb
   };

Modified: subversion/branches/cache-server/subversion/libsvn_fs/fs-loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_fs/fs-loader.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_fs/fs-loader.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_fs/fs-loader.c Tue Oct 15 08:52:06 2013
@@ -24,12 +24,14 @@
 
 #include <string.h>
 #include <apr.h>
+#include <apr_atomic.h>
 #include <apr_hash.h>
 #include <apr_md5.h>
 #include <apr_thread_mutex.h>
 #include <apr_uuid.h>
 #include <apr_strings.h>
 
+#include "svn_private_config.h"
 #include "svn_hash.h"
 #include "svn_ctype.h"
 #include "svn_types.h"
@@ -40,7 +42,7 @@
 #include "svn_xml.h"
 #include "svn_pools.h"
 #include "svn_string.h"
-#include "svn_private_config.h"
+#include "svn_sorts.h"
 
 #include "private/svn_fs_private.h"
 #include "private/svn_fs_util.h"
@@ -70,6 +72,7 @@ struct fs_type_defn {
   const char *fs_type;
   const char *fsap_name;
   fs_init_func_t initfunc;
+  fs_library_vtable_t *vtable;
   struct fs_type_defn *next;
 };
 
@@ -81,7 +84,21 @@ static struct fs_type_defn base_defn =
 #else
     NULL,
 #endif
-    NULL
+    NULL,
+    NULL /* End of static list: this needs to be reset to NULL if the
+            common_pool used when setting it has been cleared. */
+  };
+
+static struct fs_type_defn fsx_defn =
+  {
+    SVN_FS_TYPE_FSX, "x",
+#ifdef SVN_LIBSVN_FS_LINKS_FS_X
+    svn_fs_x__init,
+#else
+    NULL,
+#endif
+    NULL,
+    &base_defn
   };
 
 static struct fs_type_defn fsfs_defn =
@@ -92,7 +109,8 @@ static struct fs_type_defn fsfs_defn =
 #else
     NULL,
 #endif
-    &base_defn
+    NULL,
+    &fsx_defn
   };
 
 static struct fs_type_defn *fs_modules = &fsfs_defn;
@@ -147,13 +165,20 @@ load_module(fs_init_func_t *initfunc, co
 /* Fetch a library vtable by a pointer into the library definitions array. */
 static svn_error_t *
 get_library_vtable_direct(fs_library_vtable_t **vtable,
-                          const struct fs_type_defn *fst,
+                          struct fs_type_defn *fst,
                           apr_pool_t *pool)
 {
   fs_init_func_t initfunc = NULL;
   const svn_version_t *my_version = svn_fs_version();
   const svn_version_t *fs_version;
 
+  /* most times, we get lucky */
+  *vtable = apr_atomic_casptr((volatile void **)&fst->vtable, NULL, NULL);
+  if (*vtable)
+    return SVN_NO_ERROR;
+
+  /* o.k. the first access needs to actually load the module, find the
+     vtable and check for version compatibility. */
   initfunc = fst->initfunc;
   if (! initfunc)
     SVN_ERR(load_module(&initfunc, fst->fsap_name, pool));
@@ -190,6 +215,10 @@ get_library_vtable_direct(fs_library_vta
                              my_version->patch, my_version->tag,
                              fs_version->major, fs_version->minor,
                              fs_version->patch, fs_version->tag);
+
+  /* the vtable will not change.  Remember it */
+  apr_atomic_casptr((volatile void **)&fst->vtable, *vtable, NULL);
+
   return SVN_NO_ERROR;
 }
 
@@ -221,21 +250,19 @@ static svn_error_t *
 get_library_vtable(fs_library_vtable_t **vtable, const char *fs_type,
                    apr_pool_t *pool)
 {
-  struct fs_type_defn **fst = &fs_modules;
+  struct fs_type_defn **fst;
   svn_boolean_t known = FALSE;
 
   /* There are two FS module definitions known at compile time.  We
      want to check these without any locking overhead even when
      dynamic third party modules are enabled.  The third party modules
      cannot be checked until the lock is held.  */
-  if (strcmp(fs_type, (*fst)->fs_type) == 0)
-    known = TRUE;
-  else
-    {
-      fst = &(*fst)->next;
-      if (strcmp(fs_type, (*fst)->fs_type) == 0)
+  for (fst = &fs_modules; *fst; fst = &(*fst)->next)
+    if (strcmp(fs_type, (*fst)->fs_type) == 0)
+      {
         known = TRUE;
-    }
+        break;
+      }
 
 #if defined(SVN_USE_DSO) && APR_HAS_DSO
   /* Third party FS modules that are unknown at compile time.
@@ -355,6 +382,7 @@ svn_fs_initialize(apr_pool_t *pool)
     return SVN_NO_ERROR;
 
   common_pool = svn_pool_create(pool);
+  base_defn.next = NULL;
   SVN_ERR(svn_mutex__init(&common_pool_lock, TRUE, common_pool));
 
   /* ### This won't work if POOL is NULL and libsvn_fs is loaded as a DSO
@@ -373,7 +401,16 @@ default_warning_func(void *baton, svn_er
 {
   /* The one unforgiveable sin is to fail silently.  Dumping to stderr
      or /dev/tty is not acceptable default behavior for server
-     processes, since those may both be equivalent to /dev/null.  */
+     processes, since those may both be equivalent to /dev/null.
+
+     That said, be a good citizen and print something anyway, in case it goes
+     somewhere, and our caller hasn't overridden the abort() call.
+   */
+  if (svn_error_get_malfunction_handler()
+      == svn_error_abort_on_malfunction)
+    /* ### TODO: extend the malfunction API such that non-abort()ing consumers
+       ### also get the information on ERR. */
+    svn_handle_error2(err, stderr, FALSE /* fatal */, "svn: fs-loader: ");
   SVN_ERR_MALFUNCTION_NO_RETURN();
 }
 
@@ -449,8 +486,7 @@ svn_fs_create(svn_fs_t **fs_p, const cha
   /* Perform the actual creation. */
   *fs_p = fs_new(fs_config, pool);
 
-  SVN_MUTEX__WITH_LOCK(common_pool_lock,
-                       vtable->create(*fs_p, path, pool, common_pool));
+  SVN_ERR(vtable->create(*fs_p, path, common_pool_lock, pool, common_pool));
   SVN_ERR(vtable->set_svn_fs_open(*fs_p, svn_fs_open));
 
   return SVN_NO_ERROR;
@@ -464,15 +500,19 @@ svn_fs_open(svn_fs_t **fs_p, const char 
 
   SVN_ERR(fs_library_vtable(&vtable, path, pool));
   *fs_p = fs_new(fs_config, pool);
-  SVN_MUTEX__WITH_LOCK(common_pool_lock,
-                       vtable->open_fs(*fs_p, path, pool, common_pool));
+  SVN_ERR(vtable->open_fs(*fs_p, path, common_pool_lock, pool, common_pool));
   SVN_ERR(vtable->set_svn_fs_open(*fs_p, svn_fs_open));
 
   return SVN_NO_ERROR;
 }
 
 svn_error_t *
-svn_fs_upgrade(const char *path, apr_pool_t *pool)
+svn_fs_upgrade2(const char *path,
+                svn_fs_upgrade_notify_t notify_func,
+                void *notify_baton,
+                svn_cancel_func_t cancel_func,
+                void *cancel_baton,
+                apr_pool_t *pool)
 {
   fs_library_vtable_t *vtable;
   svn_fs_t *fs;
@@ -480,12 +520,21 @@ svn_fs_upgrade(const char *path, apr_poo
   SVN_ERR(fs_library_vtable(&vtable, path, pool));
   fs = fs_new(NULL, pool);
 
-  SVN_MUTEX__WITH_LOCK(common_pool_lock,
-                       vtable->upgrade_fs(fs, path, pool, common_pool));
+  SVN_ERR(vtable->upgrade_fs(fs, path,
+                             notify_func, notify_baton,
+                             cancel_func, cancel_baton,
+                             common_pool_lock,
+                             pool, common_pool));
   return SVN_NO_ERROR;
 }
 
 svn_error_t *
+svn_fs_upgrade(const char *path, apr_pool_t *pool)
+{
+  return svn_error_trace(svn_fs_upgrade2(path, NULL, NULL, NULL, NULL, pool));
+}
+
+svn_error_t *
 svn_fs_verify(const char *path,
               apr_hash_t *fs_config,
               svn_revnum_t start,
@@ -502,11 +551,11 @@ svn_fs_verify(const char *path,
   SVN_ERR(fs_library_vtable(&vtable, path, pool));
   fs = fs_new(fs_config, pool);
 
-  SVN_MUTEX__WITH_LOCK(common_pool_lock,
-                       vtable->verify_fs(fs, path, start, end,
-                                         notify_func, notify_baton,
-                                         cancel_func, cancel_baton,
-                                         pool, common_pool));
+  SVN_ERR(vtable->verify_fs(fs, path, start, end,
+                            notify_func, notify_baton,
+                            cancel_func, cancel_baton,
+                            common_pool_lock,
+                            pool, common_pool));
   return SVN_NO_ERROR;
 }
 
@@ -617,10 +666,9 @@ svn_fs_pack(const char *path,
   SVN_ERR(fs_library_vtable(&vtable, path, pool));
   fs = fs_new(NULL, pool);
 
-  SVN_MUTEX__WITH_LOCK(common_pool_lock,
-                       vtable->pack_fs(fs, path, notify_func, notify_baton,
-                                       cancel_func, cancel_baton, pool,
-                                       common_pool));
+  SVN_ERR(vtable->pack_fs(fs, path, notify_func, notify_baton,
+                          cancel_func, cancel_baton, common_pool_lock,
+                          pool, common_pool));
   return SVN_NO_ERROR;
 }
 
@@ -635,9 +683,8 @@ svn_fs_recover(const char *path,
   SVN_ERR(fs_library_vtable(&vtable, path, pool));
   fs = fs_new(NULL, pool);
 
-  SVN_MUTEX__WITH_LOCK(common_pool_lock,
-                       vtable->open_fs_for_recovery(fs, path, pool,
-                                                    common_pool));
+  SVN_ERR(vtable->open_fs_for_recovery(fs, path, common_pool_lock,
+                                       pool, common_pool));
   return svn_error_trace(vtable->recover(fs, cancel_func, cancel_baton,
                                          pool));
 }
@@ -678,8 +725,7 @@ svn_fs_create_berkeley(svn_fs_t *fs, con
   SVN_ERR(write_fs_type(path, SVN_FS_TYPE_BDB, fs->pool));
 
   /* Perform the actual creation. */
-  SVN_MUTEX__WITH_LOCK(common_pool_lock,
-                       vtable->create(fs, path, fs->pool, common_pool));
+  SVN_ERR(vtable->create(fs, path, common_pool_lock, fs->pool, common_pool));
   SVN_ERR(vtable->set_svn_fs_open(fs, svn_fs_open));
 
   return SVN_NO_ERROR;
@@ -691,8 +737,7 @@ svn_fs_open_berkeley(svn_fs_t *fs, const
   fs_library_vtable_t *vtable;
 
   SVN_ERR(fs_library_vtable(&vtable, path, fs->pool));
-  SVN_MUTEX__WITH_LOCK(common_pool_lock,
-                       vtable->open_fs(fs, path, fs->pool, common_pool));
+  SVN_ERR(vtable->open_fs(fs, path, common_pool_lock, fs->pool, common_pool));
   SVN_ERR(vtable->set_svn_fs_open(fs, svn_fs_open));
 
   return SVN_NO_ERROR;
@@ -764,8 +809,9 @@ svn_fs_begin_txn(svn_fs_txn_t **txn_p, s
 
 
 svn_error_t *
-svn_fs_commit_txn(const char **conflict_p, svn_revnum_t *new_rev,
-                  svn_fs_txn_t *txn, apr_pool_t *pool)
+svn_fs_commit_txn2(const char **conflict_p, svn_revnum_t *new_rev,
+                   svn_fs_txn_t *txn, svn_boolean_t set_timestamp,
+                   apr_pool_t *pool)
 {
   svn_error_t *err;
 
@@ -773,7 +819,7 @@ svn_fs_commit_txn(const char **conflict_
   if (conflict_p)
     *conflict_p = NULL;
 
-  err = txn->vtable->commit(conflict_p, new_rev, txn, pool);
+  err = txn->vtable->commit(conflict_p, new_rev, txn, set_timestamp, pool);
 
 #ifdef SVN_DEBUG
   /* Check postconditions. */
@@ -806,6 +852,12 @@ svn_fs_commit_txn(const char **conflict_
   return SVN_NO_ERROR;
 }
 
+svn_error_t *
+svn_fs_commit_txn(const char **conflict_p, svn_revnum_t *new_rev,
+                  svn_fs_txn_t *txn, apr_pool_t *pool)
+{
+  return svn_fs_commit_txn2(conflict_p, new_rev, txn, TRUE, pool);
+}
 
 svn_error_t *
 svn_fs_abort_txn(svn_fs_txn_t *txn, apr_pool_t *pool)
@@ -937,11 +989,177 @@ svn_fs_revision_root_revision(svn_fs_roo
   return root->is_txn_root ? SVN_INVALID_REVNUM : root->rev;
 }
 
+/* Return TRUE, if CHANGE deleted the node previously found at its target
+   path. */
+static svn_boolean_t
+is_deletion(svn_fs_path_change2_t *change)
+{
+  return change->change_kind == svn_fs_path_change_movereplace
+      || change->change_kind == svn_fs_path_change_replace
+      || change->change_kind == svn_fs_path_change_delete;
+}
+
+/* Change all moves in CHANGES to ADD.  Use POOL for temporary allocations.
+ */
+static void
+turn_moves_into_copies(apr_hash_t *changes,
+                       apr_pool_t *pool)
+{
+  apr_hash_index_t *hi;
+  for (hi = apr_hash_first(pool, changes); hi; hi = apr_hash_next(hi))
+    {
+      const char *key;
+      apr_ssize_t klen;
+      svn_fs_path_change2_t *change;
+      apr_hash_this(hi, (const void **)&key, &klen, (void**)&change);
+
+      switch (change->change_kind)
+        {
+          case svn_fs_path_change_move:
+            change->change_kind = svn_fs_path_change_add;
+            break;
+
+          case svn_fs_path_change_movereplace:
+            change->change_kind = svn_fs_path_change_replace;
+            break;
+
+          default:
+            break;
+        }
+    }
+}
+
+/* Replace ADDs with MOVes, if they are unique, have a matching deletion
+ * and if the copy-from revision is REVISION-1.  Use POOL for temporary
+ * allocations.
+ */
+static void
+turn_unique_copies_into_moves(apr_hash_t *changes,
+                              svn_revnum_t revision,
+                              apr_pool_t *pool)
+{
+  apr_hash_index_t *hi;
+  apr_hash_t *unique_copy_sources;
+  const char **sources;
+  int i;
+
+  /* find all copy-from paths (ADD and MOV alike) */
+
+  svn_boolean_t any_deletion = FALSE;
+  apr_array_header_t *copy_sources
+    = apr_array_make(pool, apr_hash_count(changes), sizeof(const char*));
+
+  for (hi = apr_hash_first(pool, changes); hi; hi = apr_hash_next(hi))
+    {
+      svn_fs_path_change2_t *change;
+      apr_hash_this(hi, NULL, NULL, (void**)&change);
+
+      if (change->copyfrom_path && change->copyfrom_rev == revision-1)
+        APR_ARRAY_PUSH(copy_sources, const char *)
+          = change->copyfrom_path;
+
+      any_deletion |= is_deletion(change);
+    }
+
+  /* no suitable copy-from or no deletion -> no moves */
+
+  if (!copy_sources->nelts || !any_deletion)
+    return;
+
+  /* identify copy-from paths that have been mentioned exactly once */
+
+  sources = (const char **)copy_sources->elts;
+  qsort(sources, copy_sources->nelts, copy_sources->elt_size,
+        (int (*)(const void *, const void *))svn_sort_compare_paths);
+
+  unique_copy_sources = apr_hash_make(pool);
+  for (i = 0; i < copy_sources->nelts; ++i)
+    if (   (i == 0 || strcmp(sources[i-1], sources[i]))
+        && (i == copy_sources->nelts-1 || strcmp(sources[i+1], sources[i])))
+      {
+        apr_hash_set(unique_copy_sources, sources[i],
+                     APR_HASH_KEY_STRING, sources[i]);
+      }
+
+  /* no unique copy-from paths -> no moves */
+
+  if (!apr_hash_count(unique_copy_sources))
+    return;
+
+  /* Replace all additions, replacements with a unique copy-from path,
+     the correct copy-from rev and a matching deletion in this revision,
+     with moves and move-replacements, respectively. */
+
+  for (hi = apr_hash_first(pool, changes); hi; hi = apr_hash_next(hi))
+    {
+      const char *key;
+      apr_ssize_t klen;
+      svn_fs_path_change2_t *change, *copy_from_change;
+
+      apr_hash_this(hi, (const void **)&key, &klen, (void**)&change);
+      if (   change->copyfrom_rev != revision-1
+          || !change->copyfrom_path
+          || !apr_hash_get(unique_copy_sources, change->copyfrom_path,
+                           APR_HASH_KEY_STRING))
+        continue;
+
+      copy_from_change = apr_hash_get(changes, change->copyfrom_path,
+                                      APR_HASH_KEY_STRING);
+      if (!copy_from_change || !is_deletion(copy_from_change))
+        continue;
+
+      /* There is a deletion of the ADD's copy-from path in *REVISION*.
+         This can either be the same as in REVISION-1 (o.k.) or must have
+         been replaced by some other node.  However, that would imply that
+         it still got deleted as part of the replacement, i.e. both cases
+         are o.k. */
+
+      switch (change->change_kind)
+        {
+          case svn_fs_path_change_add:
+            change->change_kind = svn_fs_path_change_move;
+            break;
+
+          case svn_fs_path_change_replace:
+            change->change_kind = svn_fs_path_change_movereplace;
+            break;
+
+          default:
+            break;
+        }
+    }
+}
+
+svn_error_t *
+svn_fs_paths_changed3(apr_hash_t **changed_paths_p,
+                      svn_fs_root_t *root,
+                      svn_move_behavior_t move_behavior,
+                      apr_pool_t *pool)
+{
+  SVN_ERR(root->vtable->paths_changed(changed_paths_p, root, pool));
+  switch(move_behavior)
+    {
+      case svn_move_behavior_no_moves:
+        turn_moves_into_copies(*changed_paths_p, pool);
+        break;
+
+      case svn_move_behavior_auto_moves:
+        turn_unique_copies_into_moves(*changed_paths_p, root->rev, pool);
+        break;
+
+      default:
+        break;
+    }
+
+  return SVN_NO_ERROR;
+}
+
 svn_error_t *
 svn_fs_paths_changed2(apr_hash_t **changed_paths_p, svn_fs_root_t *root,
                       apr_pool_t *pool)
 {
-  return root->vtable->paths_changed(changed_paths_p, root, pool);
+  return svn_fs_paths_changed3(changed_paths_p, root,
+                               svn_move_behavior_no_moves, pool);
 }
 
 svn_error_t *
@@ -951,7 +1169,8 @@ svn_fs_paths_changed(apr_hash_t **change
   apr_hash_t *changed_paths_new_structs;
   apr_hash_index_t *hi;
 
-  SVN_ERR(svn_fs_paths_changed2(&changed_paths_new_structs, root, pool));
+  SVN_ERR(svn_fs_paths_changed3(&changed_paths_new_structs, root,
+                                svn_move_behavior_no_moves, pool));
   *changed_paths_p = apr_hash_make(pool);
   for (hi = apr_hash_first(pool, changed_paths_new_structs);
        hi;
@@ -1145,6 +1364,16 @@ svn_fs_dir_entries(apr_hash_t **entries_
 }
 
 svn_error_t *
+svn_fs_dir_optimal_order(apr_array_header_t **ordered_p,
+                         svn_fs_root_t *root,
+                         apr_hash_t *entries,
+                         apr_pool_t *pool)
+{
+  return svn_error_trace(root->vtable->dir_optimal_order(ordered_p, root,
+                                                         entries, pool));
+}
+
+svn_error_t *
 svn_fs_make_dir(svn_fs_root_t *root, const char *path, apr_pool_t *pool)
 {
   SVN_ERR(svn_fs__path_valid(path, pool));
@@ -1175,6 +1404,15 @@ svn_fs_revision_link(svn_fs_root_t *from
 }
 
 svn_error_t *
+svn_fs_move(svn_fs_root_t *from_root, const char *from_path,
+            svn_fs_root_t *to_root, const char *to_path, apr_pool_t *pool)
+{
+  SVN_ERR(svn_fs__path_valid(to_path, pool));
+  return svn_error_trace(to_root->vtable->move(from_root, from_path,
+                                               to_root, to_path, pool));
+}
+
+svn_error_t *
 svn_fs_file_length(svn_filesize_t *length_p, svn_fs_root_t *root,
                    const char *path, apr_pool_t *pool)
 {
@@ -1574,7 +1812,7 @@ svn_error_t *
 svn_fs_print_modules(svn_stringbuf_t *output,
                      apr_pool_t *pool)
 {
-  const struct fs_type_defn *defn = fs_modules;
+  struct fs_type_defn *defn = fs_modules;
   fs_library_vtable_t *vtable;
   apr_pool_t *iterpool = svn_pool_create(pool);
 

Modified: subversion/branches/cache-server/subversion/libsvn_fs/fs-loader.h
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_fs/fs-loader.h?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_fs/fs-loader.h (original)
+++ subversion/branches/cache-server/subversion/libsvn_fs/fs-loader.h Tue Oct 15 08:52:06 2013
@@ -27,6 +27,7 @@
 
 #include "svn_types.h"
 #include "svn_fs.h"
+#include "private/svn_mutex.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -72,20 +73,32 @@ typedef struct fs_library_vtable_t
      this statement, now that the minor version has increased. */
   const svn_version_t *(*get_version)(void);
 
-  /* The open_fs/create/open_fs_for_recovery/upgrade_fs functions are
-     serialized so that they may use the common_pool parameter to
-     allocate fs-global objects such as the bdb env cache. */
-  svn_error_t *(*create)(svn_fs_t *fs, const char *path, apr_pool_t *pool,
+  /* The open_fs/create/open_fs_for_recovery/upgrade_fs functions must
+     use the common_pool_lock to serialize the access to the common_pool
+     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 *common_pool);
-  svn_error_t *(*open_fs)(svn_fs_t *fs, const char *path, apr_pool_t *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 *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
      might not be immediately appropriate for recovery. */
   svn_error_t *(*open_fs_for_recovery)(svn_fs_t *fs, const char *path,
+                                       svn_mutex__t *common_pool_lock,
                                        apr_pool_t *pool,
                                        apr_pool_t *common_pool);
-  svn_error_t *(*upgrade_fs)(svn_fs_t *fs, const char *path, apr_pool_t *pool,
+  svn_error_t *(*upgrade_fs)(svn_fs_t *fs,
+                             const char *path,
+                             svn_fs_upgrade_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 *pool,
                              apr_pool_t *common_pool);
   svn_error_t *(*verify_fs)(svn_fs_t *fs, const char *path,
                             svn_revnum_t start,
@@ -94,6 +107,7 @@ typedef struct fs_library_vtable_t
                             void *notify_baton,
                             svn_cancel_func_t cancel_func,
                             void *cancel_baton,
+                            svn_mutex__t *common_pool_lock,
                             apr_pool_t *pool,
                             apr_pool_t *common_pool);
   svn_error_t *(*delete_fs)(const char *path, apr_pool_t *pool);
@@ -109,6 +123,7 @@ typedef struct fs_library_vtable_t
   svn_error_t *(*pack_fs)(svn_fs_t *fs, const char *path,
                           svn_fs_pack_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 *pool, apr_pool_t *common_pool);
 
   /* Provider-specific functions should go here, even if they could go
@@ -165,6 +180,9 @@ svn_error_t *svn_fs_base__init(const svn
 svn_error_t *svn_fs_fs__init(const svn_version_t *loader_version,
                              fs_library_vtable_t **vtable,
                              apr_pool_t* common_pool);
+svn_error_t *svn_fs_x__init(const svn_version_t *loader_version,
+                            fs_library_vtable_t **vtable,
+                            apr_pool_t* common_pool);
 
 
 
@@ -242,7 +260,8 @@ typedef struct fs_vtable_t
 typedef struct txn_vtable_t
 {
   svn_error_t *(*commit)(const char **conflict_p, svn_revnum_t *new_rev,
-                         svn_fs_txn_t *txn, apr_pool_t *pool);
+                         svn_fs_txn_t *txn, svn_boolean_t set_timestamp,
+                         apr_pool_t *pool);
   svn_error_t *(*abort)(svn_fs_txn_t *txn, apr_pool_t *pool);
   svn_error_t *(*get_prop)(svn_string_t **value_p, svn_fs_txn_t *txn,
                            const char *propname, apr_pool_t *pool);
@@ -291,6 +310,16 @@ typedef struct root_vtable_t
                                     apr_pool_t *pool);
   svn_error_t *(*delete_node)(svn_fs_root_t *root, const char *path,
                               apr_pool_t *pool);
+  svn_error_t *(*copy)(svn_fs_root_t *from_root, const char *from_path,
+                       svn_fs_root_t *to_root, const char *to_path,
+                       apr_pool_t *pool);
+  svn_error_t *(*revision_link)(svn_fs_root_t *from_root,
+                                svn_fs_root_t *to_root,
+                                const char *path,
+                                apr_pool_t *pool);
+  svn_error_t *(*move)(svn_fs_root_t *from_root, const char *from_path,
+                       svn_fs_root_t *to_root, const char *to_path,
+                       apr_pool_t *pool);
   svn_error_t *(*copied_from)(svn_revnum_t *rev_p, const char **path_p,
                               svn_fs_root_t *root, const char *path,
                               apr_pool_t *pool);
@@ -315,15 +344,12 @@ typedef struct root_vtable_t
   /* Directories */
   svn_error_t *(*dir_entries)(apr_hash_t **entries_p, svn_fs_root_t *root,
                               const char *path, apr_pool_t *pool);
+  svn_error_t *(*dir_optimal_order)(apr_array_header_t **ordered_p,
+                                    svn_fs_root_t *root,
+                                    apr_hash_t *entries,
+                                    apr_pool_t *pool);
   svn_error_t *(*make_dir)(svn_fs_root_t *root, const char *path,
                            apr_pool_t *pool);
-  svn_error_t *(*copy)(svn_fs_root_t *from_root, const char *from_path,
-                       svn_fs_root_t *to_root, const char *to_path,
-                       apr_pool_t *pool);
-  svn_error_t *(*revision_link)(svn_fs_root_t *from_root,
-                                svn_fs_root_t *to_root,
-                                const char *path,
-                                apr_pool_t *pool);
 
   /* Files */
   svn_error_t *(*file_length)(svn_filesize_t *length_p, svn_fs_root_t *root,

Modified: subversion/branches/cache-server/subversion/libsvn_fs_base/bdb/changes-table.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_fs_base/bdb/changes-table.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_fs_base/bdb/changes-table.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_fs_base/bdb/changes-table.c Tue Oct 15 08:52:06 2013
@@ -25,6 +25,7 @@
 #include <apr_hash.h>
 #include <apr_tables.h>
 
+#include "svn_private_config.h"
 #include "svn_hash.h"
 #include "svn_fs.h"
 #include "svn_pools.h"
@@ -41,7 +42,6 @@
 
 #include "private/svn_fs_util.h"
 #include "private/svn_fspath.h"
-#include "svn_private_config.h"
 
 
 /*** Creating and opening the changes table. ***/

Modified: subversion/branches/cache-server/subversion/libsvn_fs_base/bdb/env.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_fs_base/bdb/env.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_fs_base/bdb/env.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_fs_base/bdb/env.c Tue Oct 15 08:52:06 2013
@@ -31,6 +31,7 @@
 #include <apr_strings.h>
 #include <apr_hash.h>
 
+#include "svn_private_config.h"
 #include "svn_hash.h"
 #include "svn_path.h"
 #include "svn_pools.h"
@@ -227,7 +228,7 @@ bdb_error_gatherer(const DB_ENV *dbenv, 
 
   SVN_BDB_ERROR_GATHERER_IGNORE(dbenv);
 
-  new_err = svn_error_createf(APR_SUCCESS, NULL, "bdb: %s", msg);
+  new_err = svn_error_createf(SVN_ERR_FS_BERKELEY_DB, NULL, "bdb: %s", msg);
   if (error_info->pending_errors)
     svn_error_compose(error_info->pending_errors, new_err);
   else

Modified: subversion/branches/cache-server/subversion/libsvn_fs_base/dag.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_fs_base/dag.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_fs_base/dag.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_fs_base/dag.c Tue Oct 15 08:52:06 2013
@@ -22,6 +22,7 @@
 
 #include <string.h>
 
+#include "svn_private_config.h"
 #include "svn_path.h"
 #include "svn_time.h"
 #include "svn_error.h"
@@ -57,8 +58,6 @@
 #include "private/svn_fspath.h"
 #include "../libsvn_fs/fs-loader.h"
 
-#include "svn_private_config.h"
-
 
 /* Initializing a filesystem.  */
 
@@ -1576,10 +1575,10 @@ svn_error_t *
 svn_fs_base__dag_commit_txn(svn_revnum_t *new_rev,
                             svn_fs_txn_t *txn,
                             trail_t *trail,
+                            svn_boolean_t set_timestamp,
                             apr_pool_t *pool)
 {
   revision_t revision;
-  svn_string_t date;
   apr_hash_t *txnprops;
   svn_fs_t *fs = txn->fs;
   const char *txn_id = txn->id;
@@ -1605,12 +1604,18 @@ svn_fs_base__dag_commit_txn(svn_revnum_t
   SVN_ERR(svn_fs_base__txn_make_committed(fs, txn_id, *new_rev,
                                           trail, pool));
 
-  /* Set a date on the commit.  We wait until now to fetch the date,
-     so it's definitely newer than any previous revision's date. */
-  date.data = svn_time_to_cstring(apr_time_now(), pool);
-  date.len = strlen(date.data);
-  return svn_fs_base__set_rev_prop(fs, *new_rev, SVN_PROP_REVISION_DATE,
-                                   NULL, &date, trail, pool);
+  if (set_timestamp)
+    {
+      /* Set a date on the commit if requested.  We wait until now to fetch the
+         date, so it's definitely newer than any previous revision's date. */
+      svn_string_t date;
+      date.data = svn_time_to_cstring(apr_time_now(), pool);
+      date.len = strlen(date.data);
+      SVN_ERR(svn_fs_base__set_rev_prop(fs, *new_rev, SVN_PROP_REVISION_DATE,
+                                        NULL, &date, trail, pool));
+    }
+
+  return SVN_NO_ERROR;
 }
 
 

Modified: subversion/branches/cache-server/subversion/libsvn_fs_base/dag.h
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_fs_base/dag.h?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_fs_base/dag.h (original)
+++ subversion/branches/cache-server/subversion/libsvn_fs_base/dag.h Tue Oct 15 08:52:06 2013
@@ -273,12 +273,16 @@ svn_error_t *svn_fs_base__dag_clone_root
    latest revision in TXN->FS.  If the caller doesn't take care of this,
    you may lose people's work!
 
+   Update commit time to ensure that svn:date revprops remain ordered if
+   SET_TIMESTAMP is non-zero.
+
    Do any necessary temporary allocation in a subpool of POOL.
    Consume temporary space at most proportional to the maximum depth
    of SVN_TXN's tree of mutable nodes.  */
 svn_error_t *svn_fs_base__dag_commit_txn(svn_revnum_t *new_rev,
                                          svn_fs_txn_t *txn,
                                          trail_t *trail,
+                                         svn_boolean_t set_timestamp,
                                          apr_pool_t *pool);
 
 

Modified: subversion/branches/cache-server/subversion/libsvn_fs_base/fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_fs_base/fs.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_fs_base/fs.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_fs_base/fs.c Tue Oct 15 08:52:06 2013
@@ -28,6 +28,8 @@
 #include <apr_pools.h>
 #include <apr_file_io.h>
 
+#define SVN_WANT_BDB
+#include "svn_private_config.h"
 #include "svn_hash.h"
 #include "svn_pools.h"
 #include "svn_fs.h"
@@ -43,8 +45,6 @@
 #include "tree.h"
 #include "id.h"
 #include "lock.h"
-#define SVN_WANT_BDB
-#include "svn_private_config.h"
 
 #include "bdb/bdb-err.h"
 #include "bdb/bdb_compat.h"
@@ -729,7 +729,10 @@ populate_opened_fs(svn_fs_t *fs, apr_poo
 }
 
 static svn_error_t *
-base_create(svn_fs_t *fs, const char *path, apr_pool_t *pool,
+base_create(svn_fs_t *fs,
+            const char *path,
+            svn_mutex__t *common_pool_lock,
+            apr_pool_t *pool,
             apr_pool_t *common_pool)
 {
   int format = SVN_FS_BASE__FORMAT_NUMBER;
@@ -805,7 +808,10 @@ check_format(int format)
 }
 
 static svn_error_t *
-base_open(svn_fs_t *fs, const char *path, apr_pool_t *pool,
+base_open(svn_fs_t *fs,
+          const char *path,
+          svn_mutex__t *common_pool_lock,
+          apr_pool_t *pool,
           apr_pool_t *common_pool)
 {
   int format;
@@ -888,7 +894,10 @@ bdb_recover(const char *path, svn_boolea
 }
 
 static svn_error_t *
-base_open_for_recovery(svn_fs_t *fs, const char *path, apr_pool_t *pool,
+base_open_for_recovery(svn_fs_t *fs,
+                       const char *path,
+                       svn_mutex__t *common_pool_lock,
+                       apr_pool_t *pool,
                        apr_pool_t *common_pool)
 {
   /* Just stash the path in the fs pointer - it's all we really need. */
@@ -898,7 +907,14 @@ base_open_for_recovery(svn_fs_t *fs, con
 }
 
 static svn_error_t *
-base_upgrade(svn_fs_t *fs, const char *path, apr_pool_t *pool,
+base_upgrade(svn_fs_t *fs,
+             const char *path,
+             svn_fs_upgrade_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 *pool,
              apr_pool_t *common_pool)
 {
   const char *version_file_path;
@@ -921,6 +937,9 @@ base_upgrade(svn_fs_t *fs, const char *p
   /* Bump the format file's stored version number. */
   SVN_ERR(svn_io_write_version_file(version_file_path,
                                     SVN_FS_BASE__FORMAT_NUMBER, pool));
+  if (notify_func)
+    SVN_ERR(notify_func(notify_baton, SVN_FS_BASE__FORMAT_NUMBER,
+                        svn_fs_upgrade_format_bumped, pool));
 
   /* Check and see if we need to record the "bump" revision. */
   if (old_format_number < SVN_FS_BASE__MIN_FORWARD_DELTAS_FORMAT)
@@ -937,7 +956,7 @@ base_upgrade(svn_fs_t *fs, const char *p
          But it's better to use the existing encapsulation of "opening
          the filesystem" rather than duplicating (or worse, partially
          duplicating) that logic here.  */
-      SVN_ERR(base_open(fs, path, subpool, common_pool));
+      SVN_ERR(base_open(fs, path, common_pool_lock, subpool, common_pool));
 
       /* Fetch the youngest rev, and record it */
       SVN_ERR(svn_fs_base__youngest_rev(&youngest_rev, fs, subpool));
@@ -959,6 +978,7 @@ base_verify(svn_fs_t *fs, const char *pa
             void *notify_baton,
             svn_cancel_func_t cancel_func,
             void *cancel_baton,
+            svn_mutex__t *common_pool_lock,
             apr_pool_t *pool,
             apr_pool_t *common_pool)
 {
@@ -983,6 +1003,7 @@ base_bdb_pack(svn_fs_t *fs,
               void *notify_baton,
               svn_cancel_func_t cancel,
               void *cancel_baton,
+              svn_mutex__t *common_pool_lock,
               apr_pool_t *pool,
               apr_pool_t *common_pool)
 {
@@ -1484,7 +1505,7 @@ svn_fs_base__init(const svn_version_t *l
     return svn_error_createf(SVN_ERR_VERSION_MISMATCH, NULL,
                              _("Unsupported FS loader version (%d) for bdb"),
                              loader_version->major);
-  SVN_ERR(svn_ver_check_list(base_version(), checklist));
+  SVN_ERR(svn_ver_check_list2(base_version(), checklist, svn_ver_equal));
   SVN_ERR(check_bdb_version());
   SVN_ERR(svn_fs_bdb__init(common_pool));
 

Modified: subversion/branches/cache-server/subversion/libsvn_fs_base/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_fs_base/lock.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_fs_base/lock.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_fs_base/lock.c Tue Oct 15 08:52:06 2013
@@ -21,11 +21,11 @@
  */
 
 
+#include "svn_private_config.h"
 #include "svn_hash.h"
 #include "svn_pools.h"
 #include "svn_error.h"
 #include "svn_fs.h"
-#include "svn_private_config.h"
 
 #include <apr_uuid.h>
 
@@ -465,8 +465,9 @@ svn_fs_base__get_locks(svn_fs_t *fs,
   args.path = svn_fs__canonicalize_abspath(path, pool);
   args.depth = depth;
   /* Enough for 100+ locks if the comments are small. */
-  args.stream = svn_stream__from_spillbuf(4 * 1024  /* blocksize */,
-                                          64 * 1024 /* maxsize */,
+  args.stream = svn_stream__from_spillbuf(svn_spillbuf__create(4 * 1024  /* blocksize */,
+                                                               64 * 1024 /* maxsize */,
+                                                               pool),
                                           pool);
   SVN_ERR(svn_fs_base__retry_txn(fs, txn_body_get_locks, &args, FALSE, pool));
 

Modified: subversion/branches/cache-server/subversion/libsvn_fs_base/revs-txns.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_fs_base/revs-txns.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_fs_base/revs-txns.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_fs_base/revs-txns.c Tue Oct 15 08:52:06 2013
@@ -25,6 +25,7 @@
 #include <apr_tables.h>
 #include <apr_pools.h>
 
+#include "svn_private_config.h"
 #include "svn_pools.h"
 #include "svn_time.h"
 #include "svn_fs.h"
@@ -46,7 +47,6 @@
 #include "bdb/changes-table.h"
 #include "../libsvn_fs/fs-loader.h"
 
-#include "svn_private_config.h"
 #include "private/svn_fs_util.h"
 
 

Modified: subversion/branches/cache-server/subversion/libsvn_fs_base/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_fs_base/tree.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_fs_base/tree.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_fs_base/tree.c Tue Oct 15 08:52:06 2013
@@ -38,6 +38,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <assert.h>
+
 #include "svn_private_config.h"
 #include "svn_hash.h"
 #include "svn_pools.h"
@@ -1561,6 +1562,23 @@ base_dir_entries(apr_hash_t **table_p,
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+base_dir_optimal_order(apr_array_header_t **ordered_p,
+                       svn_fs_root_t *root,
+                       apr_hash_t *entries,
+                       apr_pool_t *pool)
+{
+  /* 1:1 copy of entries with no differnce in ordering */
+  apr_hash_index_t *hi;
+  apr_array_header_t *result = apr_array_make(pool, apr_hash_count(entries),
+                                              sizeof(svn_fs_dirent_t *));
+  for (hi = apr_hash_first(pool, entries); hi; hi = apr_hash_next(hi))
+    APR_ARRAY_PUSH(result, svn_fs_dirent_t *) = svn__apr_hash_index_val(hi);
+
+  *ordered_p = result;
+  return SVN_NO_ERROR;
+}
+
 
 
 /* Merges and commits. */
@@ -2560,6 +2578,7 @@ struct commit_args
 {
   svn_fs_txn_t *txn;
   svn_revnum_t new_rev;
+  svn_boolean_t set_timestamp;
 };
 
 
@@ -2619,7 +2638,7 @@ txn_body_commit(void *baton, trail_t *tr
 
   /* Else, commit the txn. */
   return svn_fs_base__dag_commit_txn(&(args->new_rev), txn, trail,
-                                     trail->pool);
+                                     args->set_timestamp, trail->pool);
 }
 
 
@@ -2629,6 +2648,7 @@ svn_error_t *
 svn_fs_base__commit_txn(const char **conflict_p,
                         svn_revnum_t *new_rev,
                         svn_fs_txn_t *txn,
+                        svn_boolean_t set_timestamp,
                         apr_pool_t *pool)
 {
   /* How do commits work in Subversion?
@@ -2732,6 +2752,7 @@ svn_fs_base__commit_txn(const char **con
 
       /* Try to commit. */
       commit_args.txn = txn;
+      commit_args.set_timestamp = set_timestamp;
       err = svn_fs_base__retry_txn(fs, txn_body_commit, &commit_args,
                                    FALSE, subpool);
       if (err && (err->apr_err == SVN_ERR_FS_TXN_OUT_OF_DATE))
@@ -3256,6 +3277,18 @@ base_revision_link(svn_fs_root_t *from_r
 }
 
 
+static svn_error_t *
+base_move(svn_fs_root_t *from_root,
+          const char *from_path,
+          svn_fs_root_t *to_root,
+          const char *to_path,
+          apr_pool_t *pool)
+{
+  /* BDB supports MOVes only as backward compatible ADD-with-history */
+  return base_copy(from_root, from_path, to_root, to_path, pool);
+}
+
+
 struct copied_from_args
 {
   svn_fs_root_t *root;      /* Root for the node whose ancestry we seek. */
@@ -4811,6 +4844,13 @@ base_node_origin_rev(svn_revnum_t *revis
      prev_location() does below will work. */
   path = svn_fs__canonicalize_abspath(path, pool);
 
+  /* Special-case the root node (for performance reasons) */
+  if (strcmp(path, "/") == 0)
+    {
+      *revision = 0;
+      return SVN_NO_ERROR;
+    }
+
   /* If we have support for the node-origins table, we'll try to use
      it. */
   if (bfd->format >= SVN_FS_BASE__MIN_NODE_ORIGINS_FORMAT)
@@ -5367,6 +5407,9 @@ static root_vtable_t root_vtable = {
   base_node_origin_rev,
   base_node_created_path,
   base_delete_node,
+  base_copy,
+  base_revision_link,
+  base_move,
   base_copied_from,
   base_closest_copy,
   base_node_prop,
@@ -5374,9 +5417,8 @@ static root_vtable_t root_vtable = {
   base_change_node_prop,
   base_props_changed,
   base_dir_entries,
+  base_dir_optimal_order,
   base_make_dir,
-  base_copy,
-  base_revision_link,
   base_file_length,
   base_file_checksum,
   base_file_contents,

Modified: subversion/branches/cache-server/subversion/libsvn_fs_base/tree.h
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_fs_base/tree.h?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_fs_base/tree.h (original)
+++ subversion/branches/cache-server/subversion/libsvn_fs_base/tree.h Tue Oct 15 08:52:06 2013
@@ -42,6 +42,7 @@ svn_error_t *svn_fs_base__deltify(svn_fs
 
 svn_error_t *svn_fs_base__commit_txn(const char **conflict_p,
                                      svn_revnum_t *new_rev, svn_fs_txn_t *txn,
+                                     svn_boolean_t set_timestamp,
                                      apr_pool_t *pool);
 
 svn_error_t *svn_fs_base__txn_root(svn_fs_root_t **root_p, svn_fs_txn_t *txn,

Modified: subversion/branches/cache-server/subversion/libsvn_fs_fs/caching.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_fs_fs/caching.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_fs_fs/caching.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_fs_fs/caching.c Tue Oct 15 08:52:06 2013
@@ -28,10 +28,10 @@
 #include "temp_serializer.h"
 #include "../libsvn_fs/fs-loader.h"
 
+#include "svn_private_config.h"
 #include "svn_config.h"
 #include "svn_cache_config.h"
 
-#include "svn_private_config.h"
 #include "svn_hash.h"
 #include "svn_pools.h"
 
@@ -116,7 +116,8 @@ read_config(svn_memcache_t **memcache_p,
   *cache_txdeltas
     = svn_hash__get_bool(fs->config,
                          SVN_FS_CONFIG_FSFS_CACHE_DELTAS,
-                         FALSE);
+                         TRUE);
+
   /* by default, cache fulltexts.
    * Most SVN tools care about reconstructed file content.
    * Thus, this is a reasonable default.
@@ -210,9 +211,10 @@ dump_cache_statistics(void *baton_void)
                                          TRUE,
                                          baton->pool);
 
-  if (! err)
+  /* skip unused caches */
+  if (! err && (info.gets > 0 || info.sets > 0))
     {
-      text_stats = svn_cache__format_info(&info, baton->pool);
+      text_stats = svn_cache__format_info(&info, TRUE, baton->pool);
       lines = svn_cstring_split(text_stats->data, "\n", FALSE, baton->pool);
 
       for (i = 0; i < lines->nelts; ++i)
@@ -233,6 +235,29 @@ dump_cache_statistics(void *baton_void)
 
   return result;
 }
+
+static apr_status_t
+dump_global_cache_statistics(void *baton_void)
+{
+  apr_pool_t *pool = baton_void;
+
+  svn_cache__info_t *info = svn_cache__membuffer_get_global_info(pool);
+  svn_string_t *text_stats = svn_cache__format_info(info, FALSE, pool);
+  apr_array_header_t *lines = svn_cstring_split(text_stats->data, "\n",
+                                                FALSE, pool);
+
+  int i;
+  for (i = 0; i < lines->nelts; ++i)
+    {
+      const char *line = APR_ARRAY_IDX(lines, i, const char *);
+#ifdef SVN_DEBUG
+      SVN_DBG(("%s\n", line));
+#endif
+    }
+
+  return APR_SUCCESS;
+}
+
 #endif /* SVN_DEBUG_CACHE_DUMP_STATS */
 
 /* This function sets / registers the required callbacks for a given
@@ -281,7 +306,8 @@ init_callbacks(svn_cache__t *cache,
  * Creates memcache if MEMCACHE is not NULL. Creates membuffer cache if
  * MEMBUFFER is not NULL. Fallbacks to inprocess cache if MEMCACHE and
  * MEMBUFFER are NULL and pages is non-zero.  Sets *CACHE_P to NULL
- * otherwise.
+ * otherwise.  Use the given PRIORITY class for the new cache.  If it
+ * is 0, then use the default priority class.
  *
  * Unless NO_HANDLER is true, register an error handler that reports errors
  * as warnings to the FS warning callback.
@@ -298,6 +324,7 @@ create_cache(svn_cache__t **cache_p,
              svn_cache__deserialize_func_t deserializer,
              apr_ssize_t klen,
              const char *prefix,
+             apr_uint32_t priority,
              svn_fs_t *fs,
              svn_boolean_t no_handler,
              apr_pool_t *pool)
@@ -305,6 +332,8 @@ create_cache(svn_cache__t **cache_p,
   svn_cache__error_handler_t error_handler = no_handler
                                            ? NULL
                                            : warn_and_fail_on_cache_errors;
+  if (priority == 0)
+    priority = SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY;
 
   if (memcache)
     {
@@ -319,7 +348,7 @@ create_cache(svn_cache__t **cache_p,
     {
       SVN_ERR(svn_cache__create_membuffer_cache(
                 cache_p, membuffer, serializer, deserializer,
-                klen, prefix, FALSE, pool));
+                klen, prefix, priority, FALSE, pool));
     }
   else if (pages)
     {
@@ -369,6 +398,27 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
 
   membuffer = svn_cache__get_global_membuffer_cache();
 
+  /* General rules for assigning cache priorities:
+   *
+   * - Data that can be reconstructed from other elements has low prio
+   *   (e.g. fulltexts, directories etc.)
+   * - Index data required to find any of the other data has high prio
+   *   (e.g. noderevs)
+   * - everthing else should use default prio
+   */
+
+#ifdef SVN_DEBUG_CACHE_DUMP_STATS
+
+  /* schedule printing the global access statistics upon pool cleanup,
+    * i.e. end of FSFS session.
+    */
+  if (membuffer)
+    apr_pool_cleanup_register(pool,
+                              pool,
+                              dump_global_cache_statistics,
+                              apr_pool_cleanup_null);
+#endif
+
   /* Make the cache for revision roots.  For the vast majority of
    * commands, this is only going to contain a few entries (svnadmin
    * dump/verify is an exception here), so to reduce overhead let's
@@ -385,6 +435,7 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
                        svn_fs_fs__deserialize_id,
                        sizeof(svn_revnum_t),
                        apr_pstrcat(pool, prefix, "RRI", (char *)NULL),
+                       0,
                        fs,
                        no_handler,
                        fs->pool));
@@ -399,6 +450,7 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
                        svn_fs_fs__dag_deserialize,
                        APR_HASH_KEY_STRING,
                        apr_pstrcat(pool, prefix, "DAG", (char *)NULL),
+                       SVN_CACHE__MEMBUFFER_LOW_PRIORITY,
                        fs,
                        no_handler,
                        fs->pool));
@@ -413,8 +465,9 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
                        1024, 8,
                        svn_fs_fs__serialize_dir_entries,
                        svn_fs_fs__deserialize_dir_entries,
-                       APR_HASH_KEY_STRING,
+                       sizeof(pair_cache_key_t),
                        apr_pstrcat(pool, prefix, "DIR", (char *)NULL),
+                       SVN_CACHE__MEMBUFFER_LOW_PRIORITY,
                        fs,
                        no_handler,
                        fs->pool));
@@ -430,6 +483,7 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
                        sizeof(svn_revnum_t),
                        apr_pstrcat(pool, prefix, "PACK-MANIFEST",
                                    (char *)NULL),
+                       SVN_CACHE__MEMBUFFER_HIGH_PRIORITY,
                        fs,
                        no_handler,
                        fs->pool));
@@ -443,6 +497,21 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
                        svn_fs_fs__deserialize_node_revision,
                        sizeof(pair_cache_key_t),
                        apr_pstrcat(pool, prefix, "NODEREVS", (char *)NULL),
+                       SVN_CACHE__MEMBUFFER_HIGH_PRIORITY,
+                       fs,
+                       no_handler,
+                       fs->pool));
+
+  /* initialize representation header cache, if caching has been enabled */
+  SVN_ERR(create_cache(&(ffd->rep_header_cache),
+                       NULL,
+                       membuffer,
+                       0, 0, /* Do not use inprocess cache */
+                       svn_fs_fs__serialize_rep_header,
+                       svn_fs_fs__deserialize_rep_header,
+                       sizeof(representation_cache_key_t),
+                       apr_pstrcat(pool, prefix, "REPHEADER", (char *)NULL),
+                       SVN_CACHE__MEMBUFFER_HIGH_PRIORITY,
                        fs,
                        no_handler,
                        fs->pool));
@@ -456,6 +525,7 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
                        svn_fs_fs__deserialize_changes,
                        sizeof(svn_revnum_t),
                        apr_pstrcat(pool, prefix, "CHANGES", (char *)NULL),
+                       0,
                        fs,
                        no_handler,
                        fs->pool));
@@ -471,6 +541,7 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
                            NULL, NULL,
                            sizeof(pair_cache_key_t),
                            apr_pstrcat(pool, prefix, "TEXT", (char *)NULL),
+                           SVN_CACHE__MEMBUFFER_LOW_PRIORITY,
                            fs,
                            no_handler,
                            fs->pool));
@@ -484,6 +555,7 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
                            sizeof(pair_cache_key_t),
                            apr_pstrcat(pool, prefix, "PROP",
                                        (char *)NULL),
+                           SVN_CACHE__MEMBUFFER_LOW_PRIORITY,
                            fs,
                            no_handler,
                            fs->pool));
@@ -497,6 +569,7 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
                            APR_HASH_KEY_STRING,
                            apr_pstrcat(pool, prefix, "MERGEINFO",
                                        (char *)NULL),
+                           0,
                            fs,
                            no_handler,
                            fs->pool));
@@ -510,6 +583,7 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
                            APR_HASH_KEY_STRING,
                            apr_pstrcat(pool, prefix, "HAS_MERGEINFO",
                                        (char *)NULL),
+                           0,
                            fs,
                            no_handler,
                            fs->pool));
@@ -534,6 +608,7 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
                            sizeof(pair_cache_key_t),
                            apr_pstrcat(pool, prefix, "REVPROP",
                                        (char *)NULL),
+                           SVN_CACHE__MEMBUFFER_HIGH_PRIORITY,
                            fs,
                            no_handler,
                            fs->pool));
@@ -552,9 +627,10 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
                            0, 0, /* Do not use inprocess cache */
                            svn_fs_fs__serialize_txdelta_window,
                            svn_fs_fs__deserialize_txdelta_window,
-                           APR_HASH_KEY_STRING,
+                           sizeof(window_cache_key_t),
                            apr_pstrcat(pool, prefix, "TXDELTA_WINDOW",
                                        (char *)NULL),
+                           0,
                            fs,
                            no_handler,
                            fs->pool));
@@ -565,9 +641,10 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
                            0, 0, /* Do not use inprocess cache */
                            /* Values are svn_stringbuf_t */
                            NULL, NULL,
-                           APR_HASH_KEY_STRING,
+                           sizeof(window_cache_key_t),
                            apr_pstrcat(pool, prefix, "COMBINED_WINDOW",
                                        (char *)NULL),
+                           SVN_CACHE__MEMBUFFER_LOW_PRIORITY,
                            fs,
                            no_handler,
                            fs->pool));
@@ -671,6 +748,7 @@ svn_fs_fs__initialize_txn_caches(svn_fs_
                        APR_HASH_KEY_STRING,
                        apr_pstrcat(pool, prefix, "TXNDIR",
                                    (char *)NULL),
+                       0,
                        fs,
                        TRUE,
                        pool));

Modified: subversion/branches/cache-server/subversion/libsvn_fs_fs/dag.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_fs_fs/dag.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_fs_fs/dag.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_fs_fs/dag.c Tue Oct 15 08:52:06 2013
@@ -28,11 +28,12 @@
 #include "svn_props.h"
 #include "svn_pools.h"
 
+#include "cached_data.h"
 #include "dag.h"
 #include "fs.h"
-#include "key-gen.h"
 #include "fs_fs.h"
 #include "id.h"
+#include "transaction.h"
 
 #include "../libsvn_fs/fs-loader.h"
 
@@ -173,7 +174,7 @@ get_node_revision(node_revision_t **node
 
 svn_boolean_t svn_fs_fs__dag_check_mutable(const dag_node_t *node)
 {
-  return (svn_fs_fs__id_txn_id(svn_fs_fs__dag_get_id(node)) != NULL);
+  return svn_fs_fs__id_is_txn(svn_fs_fs__dag_get_id(node));
 }
 
 
@@ -312,8 +313,9 @@ dir_entry_id_from_node(const svn_fs_id_t
 {
   svn_fs_dirent_t *dirent;
 
-  SVN_ERR(svn_fs_fs__dag_dir_entry(&dirent, parent, name, scratch_pool));
-  *id_p = dirent ? svn_fs_fs__id_copy(dirent->id, result_pool) : NULL;
+  SVN_ERR(svn_fs_fs__dag_dir_entry(&dirent, parent, name, result_pool,
+                                   scratch_pool));
+  *id_p = dirent ? dirent->id : NULL;
 
   return SVN_NO_ERROR;
 }
@@ -332,7 +334,7 @@ set_entry(dag_node_t *parent,
           const char *name,
           const svn_fs_id_t *id,
           svn_node_kind_t kind,
-          const char *txn_id,
+          const svn_fs_fs__id_part_t *txn_id,
           apr_pool_t *pool)
 {
   node_revision_t *parent_noderev;
@@ -359,7 +361,7 @@ make_entry(dag_node_t **child_p,
            const char *parent_path,
            const char *name,
            svn_boolean_t is_dir,
-           const char *txn_id,
+           const svn_fs_fs__id_part_t *txn_id,
            apr_pool_t *pool)
 {
   const svn_fs_id_t *new_node_id;
@@ -432,7 +434,8 @@ svn_error_t *
 svn_fs_fs__dag_dir_entry(svn_fs_dirent_t **dirent,
                          dag_node_t *node,
                          const char* name,
-                         apr_pool_t *pool)
+                         apr_pool_t *result_pool,
+                         apr_pool_t *scratch_pool)
 {
   node_revision_t *noderev;
   SVN_ERR(get_node_revision(&noderev, node));
@@ -442,8 +445,8 @@ svn_fs_fs__dag_dir_entry(svn_fs_dirent_t
                             _("Can't get entries of non-directory"));
 
   /* Get a dirent hash for this directory. */
-  return svn_fs_fs__rep_contents_dir_entry(dirent, node->fs,
-                                           noderev, name, pool, pool);
+  return svn_fs_fs__rep_contents_dir_entry(dirent, node->fs, noderev, name,
+                                           result_pool, scratch_pool);
 }
 
 
@@ -452,7 +455,7 @@ svn_fs_fs__dag_set_entry(dag_node_t *nod
                          const char *entry_name,
                          const svn_fs_id_t *id,
                          svn_node_kind_t kind,
-                         const char *txn_id,
+                         const svn_fs_fs__id_part_t *txn_id,
                          apr_pool_t *pool)
 {
   /* Check it's a directory. */
@@ -606,17 +609,31 @@ svn_fs_fs__dag_revision_root(dag_node_t 
                              svn_revnum_t rev,
                              apr_pool_t *pool)
 {
-  svn_fs_id_t *root_id;
+  dag_node_t *new_node;
 
-  SVN_ERR(svn_fs_fs__rev_get_root(&root_id, fs, rev, pool));
-  return svn_fs_fs__dag_get_node(node_p, fs, root_id, pool);
+  /* Construct the node. */
+  new_node = apr_pcalloc(pool, sizeof(*new_node));
+  new_node->fs = fs;
+  SVN_ERR(svn_fs_fs__rev_get_root(&new_node->id, fs, rev, pool));
+
+  /* Grab the contents so we can inspect the node's kind and created path. */
+  new_node->node_pool = pool;
+
+  /* Initialize the KIND and CREATED_PATH attributes */
+  new_node->kind = svn_node_dir;
+  new_node->created_path = "/";
+  new_node->fresh_root_predecessor_id = NULL;
+
+  /* Return a fresh new node */
+  *node_p = new_node;
+  return SVN_NO_ERROR;
 }
 
 
 svn_error_t *
 svn_fs_fs__dag_txn_root(dag_node_t **node_p,
                         svn_fs_t *fs,
-                        const char *txn_id,
+                        const svn_fs_fs__id_part_t *txn_id,
                         apr_pool_t *pool)
 {
   const svn_fs_id_t *root_id, *ignored;
@@ -629,7 +646,7 @@ svn_fs_fs__dag_txn_root(dag_node_t **nod
 svn_error_t *
 svn_fs_fs__dag_txn_base_root(dag_node_t **node_p,
                              svn_fs_t *fs,
-                             const char *txn_id,
+                             const svn_fs_fs__id_part_t *txn_id,
                              apr_pool_t *pool)
 {
   const svn_fs_id_t *base_root_id, *ignored;
@@ -644,8 +661,8 @@ svn_fs_fs__dag_clone_child(dag_node_t **
                            dag_node_t *parent,
                            const char *parent_path,
                            const char *name,
-                           const char *copy_id,
-                           const char *txn_id,
+                           const svn_fs_fs__id_part_t *copy_id,
+                           const svn_fs_fs__id_part_t *txn_id,
                            svn_boolean_t is_parent_copyroot,
                            apr_pool_t *pool)
 {
@@ -718,7 +735,7 @@ svn_fs_fs__dag_clone_child(dag_node_t **
 svn_error_t *
 svn_fs_fs__dag_clone_root(dag_node_t **root_p,
                           svn_fs_t *fs,
-                          const char *txn_id,
+                          const svn_fs_fs__id_part_t *txn_id,
                           apr_pool_t *pool)
 {
   const svn_fs_id_t *base_root_id, *root_id;
@@ -745,7 +762,7 @@ svn_fs_fs__dag_clone_root(dag_node_t **r
 svn_error_t *
 svn_fs_fs__dag_delete(dag_node_t *parent,
                       const char *name,
-                      const char *txn_id,
+                      const svn_fs_fs__id_part_t *txn_id,
                       apr_pool_t *pool)
 {
   node_revision_t *parent_noderev;
@@ -869,7 +886,7 @@ svn_fs_fs__dag_make_file(dag_node_t **ch
                          dag_node_t *parent,
                          const char *parent_path,
                          const char *name,
-                         const char *txn_id,
+                         const svn_fs_fs__id_part_t *txn_id,
                          apr_pool_t *pool)
 {
   /* Call our little helper function */
@@ -882,7 +899,7 @@ svn_fs_fs__dag_make_dir(dag_node_t **chi
                         dag_node_t *parent,
                         const char *parent_path,
                         const char *name,
-                        const char *txn_id,
+                        const svn_fs_fs__id_part_t *txn_id,
                         apr_pool_t *pool)
 {
   /* Call our little helper function */
@@ -909,7 +926,7 @@ svn_fs_fs__dag_get_contents(svn_stream_t
 
   /* Get a stream to the contents. */
   SVN_ERR(svn_fs_fs__get_contents(&contents, file->fs,
-                                  noderev, pool));
+                                  noderev->data_rep, pool));
 
   *contents_p = contents;
 
@@ -1187,7 +1204,7 @@ svn_fs_fs__dag_copy(dag_node_t *to_node,
                     svn_boolean_t preserve_history,
                     svn_revnum_t from_rev,
                     const char *from_path,
-                    const char *txn_id,
+                    const svn_fs_fs__id_part_t *txn_id,
                     apr_pool_t *pool)
 {
   const svn_fs_id_t *id;
@@ -1195,7 +1212,7 @@ svn_fs_fs__dag_copy(dag_node_t *to_node,
   if (preserve_history)
     {
       node_revision_t *from_noderev, *to_noderev;
-      const char *copy_id;
+      svn_fs_fs__id_part_t copy_id;
       const svn_fs_id_t *src_id = svn_fs_fs__dag_get_id(from_node);
       svn_fs_t *fs = svn_fs_fs__dag_get_fs(from_node);
 
@@ -1221,7 +1238,7 @@ svn_fs_fs__dag_copy(dag_node_t *to_node,
       to_noderev->copyroot_path = NULL;
 
       SVN_ERR(svn_fs_fs__create_successor(&id, fs, src_id, to_noderev,
-                                          copy_id, txn_id, pool));
+                                          &copy_id, txn_id, pool));
 
     }
   else  /* don't preserve history */

Modified: subversion/branches/cache-server/subversion/libsvn_fs_fs/dag.h
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_fs_fs/dag.h?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_fs_fs/dag.h (original)
+++ subversion/branches/cache-server/subversion/libsvn_fs_fs/dag.h Tue Oct 15 08:52:06 2013
@@ -27,6 +27,8 @@
 #include "svn_delta.h"
 #include "private/svn_cache.h"
 
+#include "id.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
@@ -224,7 +226,7 @@ svn_error_t *svn_fs_fs__dag_revision_roo
    for a transaction, call svn_fs_fs__dag_clone_root.  */
 svn_error_t *svn_fs_fs__dag_txn_root(dag_node_t **node_p,
                                      svn_fs_t *fs,
-                                     const char *txn_id,
+                                     const svn_fs_fs__id_part_t *txn_id,
                                      apr_pool_t *pool);
 
 
@@ -232,7 +234,7 @@ svn_error_t *svn_fs_fs__dag_txn_root(dag
    allocating from POOL.  Allocate the node in TRAIL->pool.  */
 svn_error_t *svn_fs_fs__dag_txn_base_root(dag_node_t **node_p,
                                           svn_fs_t *fs,
-                                          const char *txn_id,
+                                          const svn_fs_fs__id_part_t *txn_id,
                                           apr_pool_t *pool);
 
 
@@ -242,7 +244,7 @@ svn_error_t *svn_fs_fs__dag_txn_base_roo
    root directory clone.  Allocate *ROOT_P in POOL.  */
 svn_error_t *svn_fs_fs__dag_clone_root(dag_node_t **root_p,
                                        svn_fs_t *fs,
-                                       const char *txn_id,
+                                       const svn_fs_fs__id_part_t *txn_id,
                                        apr_pool_t *pool);
 
 
@@ -272,14 +274,16 @@ svn_error_t *svn_fs_fs__dag_dir_entries(
 
 /* Fetches the NODE's entries and returns a copy of the entry selected
    by the key value given in NAME and set *DIRENT to a copy of that
-   entry. If such entry was found, the copy will be allocated in POOL.
+   entry. If such entry was found, the copy will be allocated in
+   RESULT_POOL.  Temporary data will be used in SCRATCH_POOL.
    Otherwise, the *DIRENT will be set to NULL.
  */
 /* ### This function is currently only called from dag.c. */
 svn_error_t * svn_fs_fs__dag_dir_entry(svn_fs_dirent_t **dirent,
                                        dag_node_t *node,
                                        const char* name,
-                                       apr_pool_t *pool);
+                                       apr_pool_t *result_pool,
+                                       apr_pool_t *scratch_pool);
 
 /* Set ENTRY_NAME in NODE to point to ID (with kind KIND), allocating
    from POOL.  NODE must be a mutable directory.  ID can refer to a
@@ -294,7 +298,7 @@ svn_error_t *svn_fs_fs__dag_set_entry(da
                                       const char *entry_name,
                                       const svn_fs_id_t *id,
                                       svn_node_kind_t kind,
-                                      const char *txn_id,
+                                      const svn_fs_fs__id_part_t *txn_id,
                                       apr_pool_t *pool);
 
 
@@ -321,8 +325,8 @@ svn_error_t *svn_fs_fs__dag_clone_child(
                                         dag_node_t *parent,
                                         const char *parent_path,
                                         const char *name,
-                                        const char *copy_id,
-                                        const char *txn_id,
+                                        const svn_fs_fs__id_part_t *copy_id,
+                                        const svn_fs_fs__id_part_t *txn_id,
                                         svn_boolean_t is_parent_copyroot,
                                         apr_pool_t *pool);
 
@@ -341,7 +345,7 @@ svn_error_t *svn_fs_fs__dag_clone_child(
  */
 svn_error_t *svn_fs_fs__dag_delete(dag_node_t *parent,
                                    const char *name,
-                                   const char *txn_id,
+                                   const svn_fs_fs__id_part_t *txn_id,
                                    apr_pool_t *pool);
 
 
@@ -384,7 +388,7 @@ svn_error_t *svn_fs_fs__dag_make_dir(dag
                                      dag_node_t *parent,
                                      const char *parent_path,
                                      const char *name,
-                                     const char *txn_id,
+                                     const svn_fs_fs__id_part_t *txn_id,
                                      apr_pool_t *pool);
 
 
@@ -495,7 +499,7 @@ svn_error_t *svn_fs_fs__dag_make_file(da
                                       dag_node_t *parent,
                                       const char *parent_path,
                                       const char *name,
-                                      const char *txn_id,
+                                      const svn_fs_fs__id_part_t *txn_id,
                                       apr_pool_t *pool);
 
 
@@ -522,7 +526,7 @@ svn_error_t *svn_fs_fs__dag_copy(dag_nod
                                  svn_boolean_t preserve_history,
                                  svn_revnum_t from_rev,
                                  const char *from_path,
-                                 const char *txn_id,
+                                 const svn_fs_fs__id_part_t *txn_id,
                                  apr_pool_t *pool);
 
 

Modified: subversion/branches/cache-server/subversion/libsvn_fs_fs/fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_fs_fs/fs.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_fs_fs/fs.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_fs_fs/fs.c Tue Oct 15 08:52:06 2013
@@ -37,8 +37,14 @@
 #include "fs_fs.h"
 #include "tree.h"
 #include "lock.h"
+#include "hotcopy.h"
 #include "id.h"
+#include "pack.h"
+#include "recovery.h"
 #include "rep-cache.h"
+#include "revprops.h"
+#include "transaction.h"
+#include "verify.h"
 #include "svn_private_config.h"
 #include "private/svn_fs_util.h"
 
@@ -185,7 +191,7 @@ fs_info(const void **fsfs_info,
 static fs_vtable_t fs_vtable = {
   svn_fs_fs__youngest_rev,
   svn_fs_fs__revision_prop,
-  svn_fs_fs__revision_proplist,
+  svn_fs_fs__get_revision_proplist,
   svn_fs_fs__change_rev_prop,
   svn_fs_fs__set_uuid,
   svn_fs_fs__revision_root,
@@ -223,9 +229,12 @@ initialize_fs_struct(svn_fs_t *fs)
 /* This implements the fs_library_vtable_t.create() API.  Create a new
    fsfs-backed Subversion filesystem at path PATH and link it into
    *FS.  Perform temporary allocations in POOL, and fs-global allocations
-   in COMMON_POOL. */
+   in COMMON_POOL.  The latter must be serialized using COMMON_POOL_LOCK. */
 static svn_error_t *
-fs_create(svn_fs_t *fs, const char *path, apr_pool_t *pool,
+fs_create(svn_fs_t *fs,
+          const char *path,
+          svn_mutex__t *common_pool_lock,
+          apr_pool_t *pool,
           apr_pool_t *common_pool)
 {
   SVN_ERR(svn_fs__check_fs(fs, FALSE));
@@ -235,7 +244,10 @@ fs_create(svn_fs_t *fs, const char *path
   SVN_ERR(svn_fs_fs__create(fs, path, pool));
 
   SVN_ERR(svn_fs_fs__initialize_caches(fs, pool));
-  return fs_serialized_init(fs, common_pool, pool);
+  SVN_MUTEX__WITH_LOCK(common_pool_lock,
+                       fs_serialized_init(fs, common_pool, pool));
+
+  return SVN_NO_ERROR;
 }
 
 
@@ -245,17 +257,26 @@ fs_create(svn_fs_t *fs, const char *path
 /* This implements the fs_library_vtable_t.open() API.  Open an FSFS
    Subversion filesystem located at PATH, set *FS to point to the
    correct vtable for the filesystem.  Use POOL for any temporary
-   allocations, and COMMON_POOL for fs-global allocations. */
+   allocations, and COMMON_POOL for fs-global allocations.
+   The latter must be serialized using COMMON_POOL_LOCK. */
 static svn_error_t *
-fs_open(svn_fs_t *fs, const char *path, apr_pool_t *pool,
+fs_open(svn_fs_t *fs,
+        const char *path,
+        svn_mutex__t *common_pool_lock,
+        apr_pool_t *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__open(fs, path, pool));
 
   SVN_ERR(svn_fs_fs__initialize_caches(fs, pool));
-  return fs_serialized_init(fs, common_pool, pool);
+  SVN_MUTEX__WITH_LOCK(common_pool_lock,
+                       fs_serialized_init(fs, common_pool, pool));
+
+  return SVN_NO_ERROR;
 }
 
 
@@ -264,7 +285,9 @@ fs_open(svn_fs_t *fs, const char *path, 
 static svn_error_t *
 fs_open_for_recovery(svn_fs_t *fs,
                      const char *path,
-                     apr_pool_t *pool, apr_pool_t *common_pool)
+                     svn_mutex__t *common_pool_lock,
+                     apr_pool_t *pool,
+                     apr_pool_t *common_pool)
 {
   /* Recovery for FSFS is currently limited to recreating the 'current'
      file from the latest revision. */
@@ -282,22 +305,26 @@ fs_open_for_recovery(svn_fs_t *fs,
                                      "0 1 1\n", pool));
 
   /* Now open the filesystem properly by calling the vtable method directly. */
-  return fs_open(fs, path, pool, common_pool);
+  return fs_open(fs, path, common_pool_lock, pool, common_pool);
 }
 
 
 
 /* This implements the fs_library_vtable_t.upgrade_fs() API. */
 static svn_error_t *
-fs_upgrade(svn_fs_t *fs, const char *path, apr_pool_t *pool,
+fs_upgrade(svn_fs_t *fs,
+           const char *path,
+           svn_fs_upgrade_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 *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__open(fs, path, pool));
-  SVN_ERR(svn_fs_fs__initialize_caches(fs, pool));
-  SVN_ERR(fs_serialized_init(fs, common_pool, pool));
-  return svn_fs_fs__upgrade(fs, pool);
+  SVN_ERR(fs_open(fs, path, common_pool_lock, pool, common_pool));
+  return svn_fs_fs__upgrade(fs, notify_func, notify_baton,
+                            cancel_func, cancel_baton, pool);
 }
 
 static svn_error_t *
@@ -308,14 +335,11 @@ fs_verify(svn_fs_t *fs, const char *path
           void *notify_baton,
           svn_cancel_func_t cancel_func,
           void *cancel_baton,
+          svn_mutex__t *common_pool_lock,
           apr_pool_t *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__open(fs, path, pool));
-  SVN_ERR(svn_fs_fs__initialize_caches(fs, pool));
-  SVN_ERR(fs_serialized_init(fs, common_pool, pool));
+  SVN_ERR(fs_open(fs, path, common_pool_lock, pool, common_pool));
   return svn_fs_fs__verify(fs, start, end, notify_func, notify_baton,
                            cancel_func, cancel_baton, pool);
 }
@@ -327,14 +351,11 @@ fs_pack(svn_fs_t *fs,
         void *notify_baton,
         svn_cancel_func_t cancel_func,
         void *cancel_baton,
+        svn_mutex__t *common_pool_lock,
         apr_pool_t *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__open(fs, path, pool));
-  SVN_ERR(svn_fs_fs__initialize_caches(fs, pool));
-  SVN_ERR(fs_serialized_init(fs, common_pool, pool));
+  SVN_ERR(fs_open(fs, path, common_pool_lock, pool, common_pool));
   return svn_fs_fs__pack(fs, notify_func, notify_baton,
                          cancel_func, cancel_baton, pool);
 }
@@ -477,7 +498,7 @@ svn_fs_fs__init(const svn_version_t *loa
     return svn_error_createf(SVN_ERR_VERSION_MISMATCH, NULL,
                              _("Unsupported FS loader version (%d) for fsfs"),
                              loader_version->major);
-  SVN_ERR(svn_ver_check_list(fs_version(), checklist));
+  SVN_ERR(svn_ver_check_list2(fs_version(), checklist, svn_ver_equal));
 
   *vtable = &library_vtable;
   return SVN_NO_ERROR;

Modified: subversion/branches/cache-server/subversion/libsvn_fs_fs/fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_fs_fs/fs.h?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_fs_fs/fs.h (original)
+++ subversion/branches/cache-server/subversion/libsvn_fs_fs/fs.h Tue Oct 15 08:52:06 2013
@@ -26,6 +26,8 @@
 #include <apr_pools.h>
 #include <apr_hash.h>
 #include <apr_network_io.h>
+#include <apr_md5.h>
+#include <apr_sha1.h>
 
 #include "svn_fs.h"
 #include "svn_config.h"
@@ -36,6 +38,8 @@
 #include "private/svn_mutex.h"
 #include "private/svn_named_atomic.h"
 
+#include "id.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
@@ -144,6 +148,9 @@ extern "C" {
 /* The minimum format number that supports packed revprops. */
 #define SVN_FS_FS__MIN_PACKED_REVPROP_FORMAT 6
 
+/* Minimum format number that will record moves */
+#define SVN_FS_FS__MIN_MOVE_SUPPORT_FORMAT 7
+
 /* The minimum format number that supports a configuration file (fsfs.conf) */
 #define SVN_FS_FS__MIN_CONFIG_FILE 4
 
@@ -157,13 +164,8 @@ typedef struct fs_fs_shared_txn_data_t
      transaction. */
   struct fs_fs_shared_txn_data_t *next;
 
-  /* This transaction's ID.  For repositories whose format is less
-     than SVN_FS_FS__MIN_TXN_CURRENT_FORMAT, the ID is in the form
-     <rev>-<uniqueifier>, where <uniqueifier> runs from 0-99999 (see
-     create_txn_dir_pre_1_5() in fs_fs.c).  For newer repositories,
-     the form is <rev>-<200 digit base 36 number> (see
-     create_txn_dir() in fs_fs.c). */
-  char txn_id[SVN_FS__TXN_MAX_LEN+1];
+  /* ID of this transaction. */
+  svn_fs_fs__id_part_t txn_id;
 
   /* Whether the transaction's prototype revision file is locked for
      writing by any thread in this process (including the current
@@ -221,7 +223,11 @@ typedef struct fs_fs_shared_data_t
 /* Data structure for the 1st level DAG node cache. */
 typedef struct fs_fs_dag_cache_t fs_fs_dag_cache_t;
 
-/* Key type for all caches that use revision + offset / counter as key. */
+/* Key type for all caches that use revision + offset / counter as key.
+
+   NOTE: always initialize this using calloc() or '= {0};'!  This is used
+   as a cache key and the padding bytes on 32 bit archs should be zero for
+   cache effectiveness. */
 typedef struct pair_cache_key_t
 {
   svn_revnum_t revision;
@@ -229,6 +235,32 @@ typedef struct pair_cache_key_t
   apr_int64_t second;
 } pair_cache_key_t;
 
+/* Key type that identifies a representation / rep header. */
+typedef struct representation_cache_key_t
+{
+  /* Revision that contains the representation */
+  apr_uint32_t revision;
+
+  /* Packed or non-packed representation? */
+  svn_boolean_t is_packed;
+
+  /* Item offset of the representation */
+  apr_uint64_t offset;
+} representation_cache_key_t;
+
+/* Key type that identifies a txdelta window. */
+typedef struct window_cache_key_t
+{
+  /* Revision that contains the representation */
+  apr_uint32_t revision;
+
+  /* Window number within that representation */
+  apr_int32_t chunk_index;
+
+  /* Offset of the representation within REVISION */
+  apr_uint64_t offset;
+} window_cache_key_t;
+
 /* 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
@@ -293,11 +325,11 @@ typedef struct fs_fs_data_t
      respective pack file. */
   svn_cache__t *packed_offset_cache;
 
-  /* Cache for txdelta_window_t objects; the key is (revFilePath, offset) */
+  /* Cache for txdelta_window_t objects; the key is window_cache_key_t */
   svn_cache__t *txdelta_window_cache;
 
   /* Cache for combined windows as svn_stringbuf_t objects;
-     the key is (revFilePath, offset) */
+     the key is window_cache_key_t */
   svn_cache__t *combined_window_cache;
 
   /* Cache for node_revision_t objects; the key is (revision, id offset) */
@@ -307,6 +339,10 @@ typedef struct fs_fs_data_t
      is the revision */
   svn_cache__t *changes_cache;
 
+  /* Cache for svn_fs_fs__rep_header_t objects; the key is a
+     (revision, is_packed, offset) set */
+  svn_cache__t *rep_header_cache;
+
   /* Cache for svn_mergeinfo_t objects; the key is a combination of
      revision, inheritance flags and path. */
   svn_cache__t *mergeinfo_cache;
@@ -395,26 +431,26 @@ typedef struct transaction_t
  * svn_fs_fs__rep_copy. */
 typedef struct representation_t
 {
-  /* Checksums for the contents produced by this representation.
+  /* Checksums digests for the contents produced by this representation.
      This checksum is for the contents the rep shows to consumers,
      regardless of how the rep stores the data under the hood.  It is
      independent of the storage (fulltext, delta, whatever).
 
-     If checksum is NULL, then for compatibility behave as though this
+     If has_sha1 is FALSE, then for compatibility behave as though this
      checksum matches the expected checksum.
 
      The md5 checksum is always filled, unless this is rep which was
      retrieved from the rep-cache.  The sha1 checksum is only computed on
-     a write, for use with rep-sharing; it may be read from an existing
-     representation, but otherwise it is NULL. */
-  svn_checksum_t *md5_checksum;
-  svn_checksum_t *sha1_checksum;
+     a write, for use with rep-sharing. */
+  svn_boolean_t has_sha1;
+  unsigned char sha1_digest[APR_SHA1_DIGESTSIZE];
+  unsigned char md5_digest[APR_MD5_DIGESTSIZE];
 
   /* Revision where this representation is located. */
   svn_revnum_t revision;
 
   /* Offset into the revision file where it is located. */
-  apr_off_t offset;
+  svn_filesize_t offset;
 
   /* The size of the representation in bytes as seen in the revision
      file. */
@@ -424,17 +460,21 @@ typedef struct representation_t
    * the fulltext size is equal to representation size in the rev file, */
   svn_filesize_t expanded_size;
 
-  /* Is this representation a transaction? */
-  const char *txn_id;
+  /* Is this a representation (still) within a transaction? */
+  svn_fs_fs__id_part_t txn_id;
 
   /* For rep-sharing, we need a way of uniquifying node-revs which share the
      same representation (see svn_fs_fs__noderev_same_rep_key() ).  So, we
      store the original txn of the node rev (not the rep!), along with some
-     intra-node uniqification content.
-
-     May be NULL, in which case, it is considered to match other NULL
-     values.*/
-  const char *uniquifier;
+     intra-node uniqification content. */
+  struct
+    {
+      /* unique context, i.e. txn ID, in which the noderev (!) got created */
+      svn_fs_fs__id_part_t noderev_txn_id;
+
+      /* unique value within that txn */
+      apr_uint64_t number;
+    } uniquifier;
 } representation_t;
 
 
@@ -494,25 +534,10 @@ typedef struct node_revision_t
 typedef struct change_t
 {
   /* Path of the change. */
-  const char *path;
-
-  /* Node revision ID of the change. */
-  const svn_fs_id_t *noderev_id;
-
-  /* The kind of change. */
-  svn_fs_path_change_kind_t kind;
-
-  /* Text or property mods? */
-  svn_boolean_t text_mod;
-  svn_boolean_t prop_mod;
-
-  /* Node kind (possibly svn_node_unknown). */
-  svn_node_kind_t node_kind;
-
-  /* Copyfrom revision and path. */
-  svn_revnum_t copyfrom_rev;
-  const char * copyfrom_path;
+  svn_string_t path;
 
+  /* API compatible change description */
+  svn_fs_path_change2_t info;
 } change_t;
 
 



Mime
View raw message