You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2013/09/05 23:52:35 UTC

svn commit: r1520437 - in /subversion/trunk/subversion/libsvn_fs_x: cached_data.c cached_data.h noderevs.c noderevs.h tree.c

Author: stefan2
Date: Thu Sep  5 21:52:34 2013
New Revision: 1520437

URL: http://svn.apache.org/r1520437
Log:
Optimize the mergeinfo_count checking code in FSX.  Add a partial cache
accessor for mergeinfo_counts in noderevs containers.  Plus provide the
infrastructure handing the info through.

* subversion/libsvn_fs_x/noderevs.h
  (svn_fs_x__mergeinfo_count_get_func): declare new partial accessor

* subversion/libsvn_fs_x/noderevs.c
  (svn_fs_x__mergeinfo_count_get_func): implement

* subversion/libsvn_fs_x/cached_data.h
  (svn_fs_x__get_mergeinfo_count): declare new data access function

* subversion/libsvn_fs_x/cached_data.c
  (svn_fs_x__get_mergeinfo_count): implement

* subversion/libsvn_fs_x/tree.c
  (verify_node): use the new mergeinfo accessor to speed up

Modified:
    subversion/trunk/subversion/libsvn_fs_x/cached_data.c
    subversion/trunk/subversion/libsvn_fs_x/cached_data.h
    subversion/trunk/subversion/libsvn_fs_x/noderevs.c
    subversion/trunk/subversion/libsvn_fs_x/noderevs.h
    subversion/trunk/subversion/libsvn_fs_x/tree.c

Modified: subversion/trunk/subversion/libsvn_fs_x/cached_data.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/cached_data.c?rev=1520437&r1=1520436&r2=1520437&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/cached_data.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/cached_data.c Thu Sep  5 21:52:34 2013
@@ -413,6 +413,57 @@ svn_fs_x__get_node_revision(node_revisio
 
 
 svn_error_t *
+svn_fs_x__get_mergeinfo_count(apr_int64_t *count,
+                              svn_fs_t *fs,
+                              const svn_fs_id_t *id,
+                              apr_pool_t *pool)
+{
+  node_revision_t *noderev;
+
+  /* If we want a full acccess log, we need to provide full data and
+     cannot take shortcuts here. */
+#if !defined(SVN_FS_X__LOG_ACCESS)
+
+  /* First, try a noderevs container cache lookup. */
+  if (! svn_fs_x__id_is_txn(id))
+    {
+      /* noderevs in rev / pack files can be cached */
+      const svn_fs_x__id_part_t *rev_item = svn_fs_x__id_rev_item(id);
+      fs_x_data_t *ffd = fs->fsap_data;
+
+      if (   svn_fs_x__is_packed_rev(fs, rev_item->revision)
+          && ffd->noderevs_container_cache)
+        {
+          pair_cache_key_t key;
+          apr_off_t offset;
+          apr_uint32_t sub_item;
+          svn_boolean_t is_cached;
+
+          SVN_ERR(svn_fs_x__item_offset(&offset, &sub_item, fs,
+                                        rev_item->revision, NULL,
+                                        rev_item->number, pool));
+          key.revision = svn_fs_x__packed_base_rev(fs, rev_item->revision);
+          key.second = offset;
+
+          SVN_ERR(svn_cache__get_partial((void **)count, &is_cached,
+                                         ffd->noderevs_container_cache, &key,
+                                         svn_fs_x__mergeinfo_count_get_func,
+                                         &sub_item, pool));
+          if (is_cached)
+            return SVN_NO_ERROR;
+        }
+    }
+#endif
+
+  /* fallback to the naive implementation handling all edge cases */
+  SVN_ERR(svn_fs_x__get_node_revision(&noderev, fs, id, pool));
+  *count = noderev->mergeinfo_count;
+
+  return SVN_NO_ERROR;
+}
+
+
+svn_error_t *
 svn_fs_x__rev_get_root(svn_fs_id_t **root_id_p,
                        svn_fs_t *fs,
                        svn_revnum_t rev,

Modified: subversion/trunk/subversion/libsvn_fs_x/cached_data.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/cached_data.h?rev=1520437&r1=1520436&r2=1520437&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/cached_data.h (original)
+++ subversion/trunk/subversion/libsvn_fs_x/cached_data.h Thu Sep  5 21:52:34 2013
@@ -39,6 +39,14 @@ svn_fs_x__get_node_revision(node_revisio
                             const svn_fs_id_t *id,
                             apr_pool_t *pool);
 
+/* Set *COUNT to the value of the mergeinfo_count member of the node-
+   revision for the node ID in FS.  Do any allocations in POOL. */
+svn_error_t *
+svn_fs_x__get_mergeinfo_count(apr_int64_t *count,
+                              svn_fs_t *fs,
+                              const svn_fs_id_t *id,
+                              apr_pool_t *pool);
+
 /* Set *ROOT_ID to the node-id for the root of revision REV in
    filesystem FS.  Do any allocations in POOL. */
 svn_error_t *

Modified: subversion/trunk/subversion/libsvn_fs_x/noderevs.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/noderevs.c?rev=1520437&r1=1520436&r2=1520437&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/noderevs.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/noderevs.c Thu Sep  5 21:52:34 2013
@@ -1014,3 +1014,25 @@ svn_fs_x__noderevs_get_func(void **out,
 
   return SVN_NO_ERROR;
 }
+
+svn_error_t *
+svn_fs_x__mergeinfo_count_get_func(void **out,
+                                   const void *data,
+                                   apr_size_t data_len,
+                                   void *baton,
+                                   apr_pool_t *pool)
+{
+  binary_noderev_t *binary_noderev;
+  apr_array_header_t noderevs;
+
+  apr_uint32_t idx = *(apr_uint32_t *)baton;
+  const svn_fs_x__noderevs_t *container = data;
+
+  /* Resolve all container pointers */
+  resolve_apr_array_header(&noderevs, container, &container->noderevs);
+  binary_noderev = &APR_ARRAY_IDX(&noderevs, idx, binary_noderev_t);
+  
+  *(apr_int64_t *)out = binary_noderev->mergeinfo_count;
+
+  return SVN_NO_ERROR;
+}

Modified: subversion/trunk/subversion/libsvn_fs_x/noderevs.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/noderevs.h?rev=1520437&r1=1520436&r2=1520437&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/noderevs.h (original)
+++ subversion/trunk/subversion/libsvn_fs_x/noderevs.h Thu Sep  5 21:52:34 2013
@@ -127,4 +127,15 @@ svn_fs_x__noderevs_get_func(void **out,
                              void *baton,
                              apr_pool_t *pool);
 
+/* Implements svn_cache__partial_getter_func_t for the mergeinfo_count in
+ * the stored noderevs, setting *OUT to the apr_int64_t counter value of
+ * the noderev selected by the apr_uint32_t index passed in as *BATON.
+ */
+svn_error_t *
+svn_fs_x__mergeinfo_count_get_func(void **out,
+                                   const void *data,
+                                   apr_size_t data_len,
+                                   void *baton,
+                                   apr_pool_t *pool);
+
 #endif

Modified: subversion/trunk/subversion/libsvn_fs_x/tree.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/tree.c?rev=1520437&r1=1520436&r2=1520437&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/tree.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/tree.c Thu Sep  5 21:52:34 2013
@@ -4253,19 +4253,25 @@ verify_node(dag_node_t *node,
         {
           svn_fs_dirent_t *dirent = svn__apr_hash_index_val(hi);
           dag_node_t *child;
-          svn_revnum_t child_rev;
           apr_int64_t child_mergeinfo;
 
           svn_pool_clear(iterpool);
 
           /* Compute CHILD_REV. */
-          SVN_ERR(svn_fs_x__dag_get_node(&child, fs, dirent->id, iterpool));
-          SVN_ERR(svn_fs_x__dag_get_revision(&child_rev, child, iterpool));
+          if (svn_fs_x__id_rev(dirent->id) == rev)
+            {
+              SVN_ERR(svn_fs_x__dag_get_node(&child, fs, dirent->id,
+                                             iterpool));
+              SVN_ERR(verify_node(child, rev, iterpool));
+              SVN_ERR(svn_fs_x__dag_get_mergeinfo_count(&child_mergeinfo,
+                                                        child));
+            }
+          else
+            {
+              SVN_ERR(svn_fs_x__get_mergeinfo_count(&child_mergeinfo, fs,
+                                                    dirent->id, iterpool));
+            }
 
-          if (child_rev == rev)
-            SVN_ERR(verify_node(child, rev, iterpool));
-
-          SVN_ERR(svn_fs_x__dag_get_mergeinfo_count(&child_mergeinfo, child));
           children_mergeinfo += child_mergeinfo;
         }