Author: stefan2
Date: Sat Apr 27 17:08:16 2013
New Revision: 1476626

URL: http://svn.apache.org/r1476626
Log:
On the fsfs-format7 branch: cache noderevs containers

* subversion/libsvn_fs_fs/fs.h
  (fs_fs_data_t.noderevs_container_cache): add cache as new member
* subversion/libsvn_fs_fs/caching.c
  (svn_fs_fs__initialize_caches): initialize the new cache for fsfs-f7

* subversion/libsvn_fs_fs/noderevs.h
  (svn_fs_fs__serialize_noderevs_container,
   svn_fs_fs__deserialize_noderevs_container): declare cache serialization /
                                               deserialization functions
* subversion/libsvn_fs_fs/noderevs.c
  (svn_fs_fs__serialize_noderevs_container,
   svn_fs_fs__deserialize_noderevs_container): implement them

* subversion/libsvn_fs_fs/cached_data.c
  (get_node_revision_body): hit the new cache, if applicable
  (block_read_changes_container): populate the new cache

Modified:
    subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/cached_data.c
    subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/caching.c
    subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs.h
    subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/noderevs.c
    subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/noderevs.h

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/cached_data.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/cached_data.c?rev=1476626&r1=1476625&r2=1476626&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/cached_data.c 
(original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/cached_data.c Sat 
Apr 27 17:08:16 2013
@@ -327,12 +327,36 @@ get_node_revision_body(node_revision_t *
     {
       /* noderevs in rev / pack files can be cached */
       const svn_fs_fs__id_part_t *rev_item = svn_fs_fs__id_rev_item(id);
-
       pair_cache_key_t key;
+    
+      /* First, try a noderevs container cache lookup. */
+      if (   is_packed_rev(fs, rev_item->revision)
+          && ffd->noderevs_container_cache)
+        {
+          svn_fs_fs__noderevs_t *noderevs;
+          apr_off_t offset;
+          apr_uint32_t sub_item;
+          SVN_ERR(svn_fs_fs__item_offset(&offset, &sub_item, fs,
+                                         rev_item->revision, NULL,
+                                         rev_item->number, pool));
+          key.revision = packed_base_rev(fs, rev_item->revision);
+          key.second = offset;
+
+          SVN_ERR(svn_cache__get((void **)&noderevs, &is_cached,
+                                 ffd->noderevs_container_cache, &key, pool));
+          if (is_cached)
+            {
+              SVN_ERR(svn_fs_fs__noderevs_get(noderev_p, noderevs, sub_item,
+                                              pool));
+              return SVN_NO_ERROR;
+            }
+        }
+
       key.revision = rev_item->revision;
       key.second = rev_item->number;
     
-      /* First, try a cache lookup. If that succeeds, we are done here. */
+      /* Not found or not applicable. Try a noderev cache lookup.
+       * If that succeeds, we are done here. */
       if (ffd->node_revision_cache)
         {
           SVN_ERR(svn_cache__get((void **) noderev_p,
@@ -2522,10 +2546,23 @@ block_read_noderevs_container(node_revis
                               svn_boolean_t must_read,
                               apr_pool_t *pool)
 {
+  fs_fs_data_t *ffd = fs->fsap_data;
   svn_fs_fs__noderevs_t *container;
   svn_stream_t *stream;
-  if (!must_read)
-    return SVN_NO_ERROR;
+  pair_cache_key_t key;
+
+  key.revision = packed_base_rev(fs, entry->items[0].revision);
+  key.second = entry->offset;
+
+  /* already in cache? */
+  if (!must_read && ffd->noderevs_container_cache)
+    {
+      svn_boolean_t is_cached = FALSE;
+      SVN_ERR(svn_cache__has_key(&is_cached, ffd->noderevs_container_cache,
+                                 &key, pool));
+      if (is_cached)
+        return SVN_NO_ERROR;
+    }
 
   SVN_ERR(auto_select_stream(&stream, fs, file, file_stream, entry, pool));
 
@@ -2535,7 +2572,12 @@ block_read_noderevs_container(node_revis
 
   /* extract requested data */
 
-  SVN_ERR(svn_fs_fs__noderevs_get(noderev_p, container, sub_item, pool));
+  if (must_read)
+    SVN_ERR(svn_fs_fs__noderevs_get(noderev_p, container, sub_item, pool));
+
+  if (ffd->noderevs_container_cache)
+    SVN_ERR(svn_cache__set(ffd->noderevs_container_cache, &key, container,
+                           pool));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/caching.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/caching.c?rev=1476626&r1=1476625&r2=1476626&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/caching.c 
(original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/caching.c Sat Apr 
27 17:08:16 2013
@@ -27,6 +27,7 @@
 #include "tree.h"
 #include "index.h"
 #include "changes.h"
+#include "noderevs.h"
 #include "temp_serializer.h"
 #include "../libsvn_fs/fs-loader.h"
 
@@ -582,6 +583,19 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
 
   if (ffd->format >= SVN_FS_FS__MIN_LOG_ADDRESSING_FORMAT)
     {
+      SVN_ERR(create_cache(&(ffd->noderevs_container_cache),
+                           NULL,
+                           membuffer,
+                           0, 0, /* Do not use inprocess cache */
+                           svn_fs_fs__serialize_noderevs_container,
+                           svn_fs_fs__deserialize_noderevs_container,
+                           sizeof(pair_cache_key_t),
+                           apr_pstrcat(pool, prefix, "NODEREVSCNT",
+                                       (char *)NULL),
+                           SVN_CACHE__MEMBUFFER_HIGH_PRIORITY,
+                           fs,
+                           no_handler,
+                           fs->pool));
       SVN_ERR(create_cache(&(ffd->changes_container_cache),
                            NULL,
                            membuffer,
@@ -651,6 +665,7 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
     }
   else
     {
+      ffd->noderevs_container_cache = NULL;
       ffd->changes_container_cache = NULL;
 
       ffd->l2p_header_cache = NULL;

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs.h?rev=1476626&r1=1476625&r2=1476626&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs.h (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs.h Sat Apr 27 
17:08:16 2013
@@ -340,11 +340,15 @@ typedef struct fs_fs_data_t
    * the key is (revision, item index) */
   svn_cache__t *node_revision_cache;
 
+  /* Cache for noderevs_t containers;
+     the key is a (pack file revision, file offset) pair */
+  svn_cache__t *noderevs_container_cache;
+
   /* Cache for change lists as APR arrays of change_t * objects; the key
      is the revision */
   svn_cache__t *changes_cache;
 
-  /* Cache for change_list_t conatiners;
+  /* Cache for change_list_t containers;
      the key is a (pack file revision, file offset) pair */
   svn_cache__t *changes_container_cache;
 

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/noderevs.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/noderevs.c?rev=1476626&r1=1476625&r2=1476626&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/noderevs.c 
(original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/noderevs.c Sat Apr 
27 17:08:16 2013
@@ -24,6 +24,7 @@
 
 #include "private/svn_packed_data.h"
 #include "private/svn_subr_private.h"
+#include "private/svn_temp_serializer.h"
 
 #include "noderevs.h"
 #include "string_table.h"
@@ -838,3 +839,60 @@ svn_fs_fs__read_noderevs_container(svn_f
   
   return SVN_NO_ERROR;
 }
+
+svn_error_t *
+svn_fs_fs__serialize_noderevs_container(void **data,
+                                        apr_size_t *data_len,
+                                        void *in,
+                                        apr_pool_t *pool)
+{
+  svn_fs_fs__noderevs_t *noderevs = in;
+  svn_stringbuf_t *serialized;
+  apr_size_t size
+    = noderevs->ids->elt_size * noderevs->ids->nelts
+    + noderevs->data_reps->elt_size * noderevs->data_reps->nelts
+    + noderevs->prop_reps->elt_size * noderevs->prop_reps->nelts
+    + noderevs->noderevs->elt_size * noderevs->noderevs->nelts
+    + 10 * noderevs->noderevs->elt_size
+    + 100;
+
+  /* serialize array header and all its elements */
+  svn_temp_serializer__context_t *context
+    = svn_temp_serializer__init(noderevs, sizeof(*noderevs), size, pool);
+
+  /* serialize sub-structures */
+  svn_fs_fs__serialize_string_table(context, &noderevs->paths);
+  svn_fs_fs__serialize_apr_array(context, &noderevs->ids);
+  svn_fs_fs__serialize_apr_array(context, &noderevs->data_reps);
+  svn_fs_fs__serialize_apr_array(context, &noderevs->prop_reps);
+  svn_fs_fs__serialize_apr_array(context, &noderevs->noderevs);
+
+  /* return the serialized result */
+  serialized = svn_temp_serializer__get(context);
+
+  *data = serialized->data;
+  *data_len = serialized->len;
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_fs_fs__deserialize_noderevs_container(void **out,
+                                          void *data,
+                                          apr_size_t data_len,
+                                          apr_pool_t *pool)
+{
+  svn_fs_fs__noderevs_t *noderevs = (svn_fs_fs__noderevs_t *)data;
+
+  /* de-serialize sub-structures */
+  svn_fs_fs__deserialize_string_table(noderevs, &noderevs->paths);
+  svn_fs_fs__deserialize_apr_array(noderevs, &noderevs->ids, pool);
+  svn_fs_fs__deserialize_apr_array(noderevs, &noderevs->data_reps, pool);
+  svn_fs_fs__deserialize_apr_array(noderevs, &noderevs->prop_reps, pool);
+  svn_fs_fs__deserialize_apr_array(noderevs, &noderevs->noderevs, pool);
+
+  /* done */
+  *out = noderevs;
+
+  return SVN_NO_ERROR;
+}

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/noderevs.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/noderevs.h?rev=1476626&r1=1476625&r2=1476626&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/noderevs.h 
(original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/noderevs.h Sat Apr 
27 17:08:16 2013
@@ -97,4 +97,22 @@ svn_fs_fs__read_noderevs_container(svn_f
                                    apr_pool_t *result_pool,
                                    apr_pool_t *scratch_pool);
 
+/* Implements #svn_cache__serialize_func_t for svn_fs_fs__noderevs_t
+ * objects.
+ */
+svn_error_t *
+svn_fs_fs__serialize_noderevs_container(void **data,
+                                        apr_size_t *data_len,
+                                        void *in,
+                                        apr_pool_t *pool);
+
+/* Implements #svn_cache__deserialize_func_t for svn_fs_fs__noderevs_t
+ * objects.
+ */
+svn_error_t *
+svn_fs_fs__deserialize_noderevs_container(void **out,
+                                          void *data,
+                                          apr_size_t data_len,
+                                          apr_pool_t *pool);
+
 #endif
\ No newline at end of file


Reply via email to