Author: rhuijben
Date: Mon Apr 13 10:47:33 2015
New Revision: 1673153

URL: http://svn.apache.org/r1673153
Log:
Make 'svn ls -v file:///my/repos/tags' and 'svn ls --xml file:///my/repos/tags'
about 20 times faster on tags directories containing far too many tags
(like 8000), by simply avoiding a lot of unneeded work. (Removes 95% of the
time from profile runs). The same code is also used by svnserve, and I think
serf/mod_dav should be faster as well.

This patch simply makes the code just ask for the dirent fields that
it really cares about, thereby skipping the request for 'has_props'
which takes 95% of the time, because it fetches all properties on
all the created tags (which are stored in many different revision, thereby
getting very bad caching behavior).

Measurements on a repository that contains a repository with an
empty /trunk dir, copied as /trunk@1 to /tags/T00001 ... /tags/T08000/
each as their own revision.

The results appear to vary by the number of tags (and probably some cache
size), but for 8000 revisions this changes the processing time on a
ramdrive from 1 minute 11 to just 3 seconds.

I think we need a separate patch which allows filesystem implementations
to answer 'has props' in a cheaper way, that doesn't trash the entire
memory cache.

* subversion/svn/list-cmd.c
  (print_dirent_fields,
   print_dirent_fields_verbose,
   print_dirent_xml_fields): New constant variables.
  (svn_cl__list): Only request the required fields.

Modified:
    subversion/trunk/subversion/svn/list-cmd.c

Modified: subversion/trunk/subversion/svn/list-cmd.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/list-cmd.c?rev=1673153&r1=1673152&r2=1673153&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/list-cmd.c (original)
+++ subversion/trunk/subversion/svn/list-cmd.c Mon Apr 13 10:47:33 2015
@@ -49,6 +49,12 @@ struct print_baton {
   svn_boolean_t in_external;
 };
 
+/* Field flags required for this function */
+static const apr_uint32_t print_dirent_fields = SVN_DIRENT_KIND;
+static const apr_uint32_t print_dirent_fields_verbose = (
+    SVN_DIRENT_KIND  | SVN_DIRENT_SIZE | SVN_DIRENT_TIME |
+    SVN_DIRENT_CREATED_REV | SVN_DIRENT_LAST_AUTHOR);
+
 /* This implements the svn_client_list_func2_t API, printing a single
    directory entry in text format. */
 static svn_error_t *
@@ -161,7 +167,10 @@ print_dirent(void *baton,
     }
 }
 
-
+/* Field flags required for this function */
+static const apr_uint32_t print_dirent_xml_fields = (
+    SVN_DIRENT_KIND  | SVN_DIRENT_SIZE | SVN_DIRENT_TIME |
+    SVN_DIRENT_CREATED_REV | SVN_DIRENT_LAST_AUTHOR);
 /* This implements the svn_client_list_func2_t API, printing a single dirent
    in XML format. */
 static svn_error_t *
@@ -314,10 +323,12 @@ svn_cl__list(apr_getopt_t *os,
                                   "mode"));
     }
 
-  if (opt_state->verbose || opt_state->xml)
-    dirent_fields = SVN_DIRENT_ALL;
+  if (opt_state->xml)
+    dirent_fields = print_dirent_xml_fields;
+  else if (opt_state->verbose)
+    dirent_fields = print_dirent_fields_verbose;
   else
-    dirent_fields = SVN_DIRENT_KIND; /* the only thing we actually need... */
+    dirent_fields = print_dirent_fields;
 
   pb.ctx = ctx;
   pb.verbose = opt_state->verbose;


Reply via email to