Backport of the code limiting the time spent walking the node history
when committing a file.
As it turns out, some users make scripted commits that not only create
deep histories for individual files but create many of those files with
the exact same depths of history, i.e. number of changes.
Without this patch, committing the e.g. 65536th change to this set of
files will take hours instead of the usual seconds. With this patch
we are down to a few minutes.
* subversion/libsvn_fs_fs/fs_fs.c
(SVN_FS_FS_MAX_DELTIFICATION_WALK): define limit to the effort we spend
on finding a delta base
(choose_delta_base): don't attempt walks longer than the defined limit
git-svn-id: https://svn.apache.org/repos/asf/subversion/branches/1.7.x-fsfs-commit@1536790 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/subversion/libsvn_fs_fs/fs_fs.c b/subversion/libsvn_fs_fs/fs_fs.c
index 4e14aa0..5bcd6b6 100644
--- a/subversion/libsvn_fs_fs/fs_fs.c
+++ b/subversion/libsvn_fs_fs/fs_fs.c
@@ -78,6 +78,13 @@
#define SVN_FS_FS_DEFAULT_MAX_FILES_PER_DIR 1000
#endif
+/* Finding a deltification base takes operations proportional to the
+ number of changes being skipped. To prevent exploding runtime
+ during commits, limit the deltification range to this value.
+ Should be a power of 2 minus one.
+ Values < 1 disable deltification. */
+#define SVN_FS_FS_MAX_DELTIFICATION_WALK 1023
+
/* Following are defines that specify the textual elements of the
native filesystem directories and revision files. */
@@ -5483,6 +5490,16 @@
count = noderev->predecessor_count;
count = count & (count - 1);
+ /* Finding the delta base over a very long distance can become extremely
+ expensive for very deep histories, possibly causing client timeouts etc.
+ OTOH, this is a rare operation and its gains are minimal. Lets simply
+ start deltification anew close every other 1000 changes or so. */
+ if (noderev->predecessor_count - count > SVN_FS_FS_MAX_DELTIFICATION_WALK)
+ {
+ *rep = NULL;
+ return SVN_NO_ERROR;
+ }
+
/* Walk back a number of predecessors equal to the difference
between count and the original predecessor count. (For example,
if noderev has ten predecessors and we want the eighth file rev,