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 2010/08/09 20:14:02 UTC

svn commit: r983760 - in /subversion/branches/performance/subversion/libsvn_fs_fs: caching.c fs.h fs_fs.c

Author: stefan2
Date: Mon Aug  9 18:14:01 2010
New Revision: 983760

URL: http://svn.apache.org/viewvc?rev=983760&view=rev
Log:
* subversion/libsvn_fs_fs/fs.h
  (fs_fs_data_t): add node_revision_cache member
* subversion/libsvn_fs_fs/fs_fs.c
  (get_noderev_cache_key, get_cached_node_revision_body,
   set_cached_node_revision_body): new functions to get / set noderevs from / to cache
  (get_node_revision_body): speed up using the noderev cache
* subversion/libsvn_fs_fs/caching.c
  (svn_fs_fs__initialize_caches): initialize the revnode cache; fix a comment

Modified:
    subversion/branches/performance/subversion/libsvn_fs_fs/caching.c
    subversion/branches/performance/subversion/libsvn_fs_fs/fs.h
    subversion/branches/performance/subversion/libsvn_fs_fs/fs_fs.c

Modified: subversion/branches/performance/subversion/libsvn_fs_fs/caching.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_fs_fs/caching.c?rev=983760&r1=983759&r2=983760&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_fs_fs/caching.c (original)
+++ subversion/branches/performance/subversion/libsvn_fs_fs/caching.c Mon Aug  9 18:14:01 2010
@@ -300,7 +300,7 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
   /* initialize file handle cache as configured */
   ffd->file_handle_cache = get_global_file_handle_cache();
 
-  /* if enabled, enable the txdelta window cache */
+  /* initialize txdelta window cache, if that has been enabled */
   if (get_global_membuffer_cache() &&
       svn_fs_fs__get_cache_config()->cache_txdeltas)
     {
@@ -322,5 +322,28 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
     SVN_ERR(svn_cache__set_error_handler(ffd->txdelta_window_cache,
                                          warn_on_cache_errors, fs, pool));
 
+  /* initialize node revision cache, if caching has been enabled */
+  if (get_global_membuffer_cache())
+    {
+      SVN_ERR(svn_cache__create_membuffer_cache(&(ffd->node_revision_cache),
+                                                get_global_membuffer_cache(),
+                                                svn_fs_fs__serialize_node_revision,
+                                                svn_fs_fs__deserialize_node_revision,
+                                                APR_HASH_KEY_STRING,
+                                                apr_pstrcat(pool,
+                                                            prefix,
+                                                            "NODEREVS",
+                                                            NULL),
+                                                fs->pool));
+    }
+  else
+    {
+      ffd->node_revision_cache = NULL;
+    }
+
+  if (ffd->node_revision_cache && ! no_handler)
+    SVN_ERR(svn_cache__set_error_handler(ffd->node_revision_cache,
+                                         warn_on_cache_errors, fs, pool));
+
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/performance/subversion/libsvn_fs_fs/fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_fs_fs/fs.h?rev=983760&r1=983759&r2=983760&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_fs_fs/fs.h (original)
+++ subversion/branches/performance/subversion/libsvn_fs_fs/fs.h Mon Aug  9 18:14:01 2010
@@ -247,6 +247,9 @@ typedef struct
   /* Cache for txdelta_window_t objects; the key is (revFilePath, offset) */
   svn_cache__t *txdelta_window_cache;
 
+  /* Cache for node_revision_t objects; the key is (revision, id offset) */
+  svn_cache__t *node_revision_cache;
+
   /* Data shared between all svn_fs_t objects for a given filesystem. */
   fs_fs_shared_data_t *shared;
 

Modified: subversion/branches/performance/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_fs_fs/fs_fs.c?rev=983760&r1=983759&r2=983760&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/branches/performance/subversion/libsvn_fs_fs/fs_fs.c Mon Aug  9 18:14:01 2010
@@ -2079,6 +2079,66 @@ read_rep_offsets(representation_t **rep_
   return SVN_NO_ERROR;
 }
 
+/* Combine the revision and offset of the ID to a string that will
+ * be used as a cache key. Allocations will be made from POOL.
+ */
+static const char *
+get_noderev_cache_key(const svn_fs_id_t *id, apr_pool_t *pool)
+{
+  return svn_fs_fs__combine_two_numbers(svn_fs_fs__id_rev(id),
+                                        svn_fs_fs__id_offset(id),
+                                        pool);
+}
+
+/* Look up the NODEREV_P for ID in FS' node revsion cache. If noderev 
+ * caching has been enabled and the data can be found, IS_CACHED will
+ * be set to TRUE. The noderev will be allocated from POOL.
+ *
+ * Non-permanent ids (e.g. ids within a TXN) will not be cached.
+ */
+static svn_error_t *
+get_cached_node_revision_body(node_revision_t **noderev_p,
+                              svn_fs_t *fs,
+                              const svn_fs_id_t *id,
+                              svn_boolean_t *is_cached,
+                              apr_pool_t *pool)
+{
+  fs_fs_data_t *ffd = fs->fsap_data;
+  if (! ffd->node_revision_cache || svn_fs_fs__id_txn_id(id))
+    *is_cached = FALSE;
+  else
+    SVN_ERR(svn_cache__get((void **) noderev_p,
+                           is_cached,
+                           ffd->node_revision_cache,
+                           get_noderev_cache_key(id, pool),
+                           pool));
+
+  return SVN_NO_ERROR;
+}
+
+/* If noderev caching has been enabled, store the NODEREV_P for the given ID
+ * in FS' node revsion cache. SCRATCH_POOL is used for temporary allcations.
+ *
+ * Non-permanent ids (e.g. ids within a TXN) will not be cached.
+ */
+static svn_error_t *
+set_cached_node_revision_body(node_revision_t *noderev_p,
+                              svn_fs_t *fs,
+                              const svn_fs_id_t *id,
+                              apr_pool_t *scratch_pool)
+{
+  fs_fs_data_t *ffd = fs->fsap_data;
+
+  if (ffd->node_revision_cache && !svn_fs_fs__id_txn_id(id))
+    return svn_cache__set(ffd->node_revision_cache,
+                          get_noderev_cache_key(id, scratch_pool),
+                          noderev_p,
+                          scratch_pool);
+
+  return SVN_NO_ERROR;
+}
+
+
 /* Get the node-revision for the node ID in FS.
    Set *NODEREV_P to the new node-revision structure, allocated in POOL.
    See svn_fs_fs__get_node_revision, which wraps this and adds another
@@ -2091,6 +2151,12 @@ get_node_revision_body(node_revision_t *
 {
   svn_file_handle_cache__handle_t *revision_file;
   svn_error_t *err;
+  svn_boolean_t is_cached = FALSE;
+
+  /* First, try a cache lookup. If that succeeds, we are done here. */
+  SVN_ERR(get_cached_node_revision_body(noderev_p, fs, id, &is_cached, pool));
+  if (is_cached)
+    return SVN_NO_ERROR;
 
   if (svn_fs_fs__id_txn_id(id))
     {
@@ -2126,12 +2192,15 @@ get_node_revision_body(node_revision_t *
       return svn_error_return(err);
     }
 
-  return svn_fs_fs__read_noderev(noderev_p,
-                                 svn_stream__from_cached_file_handle
-                                     (revision_file,
+  SVN_ERR(svn_fs_fs__read_noderev(noderev_p,
+                                  svn_stream__from_cached_file_handle
+                                      (revision_file,
                                       FALSE,
                                       pool),
-                                 pool);
+                                  pool));
+
+  /* The noderev is not in cache, yet. Add it, if caching has been enabled. */
+  return set_cached_node_revision_body(*noderev_p, fs, id, pool);
 }
 
 svn_error_t *