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/18 20:17:53 UTC

svn commit: r986832 - in /subversion/branches/performance/subversion: libsvn_fs_fs/temp_serializer.c libsvn_subr/cache-inprocess.c libsvn_subr/cache-membuffer.c libsvn_subr/cache-memcache.c

Author: stefan2
Date: Wed Aug 18 18:17:52 2010
New Revision: 986832

URL: http://svn.apache.org/viewvc?rev=986832&view=rev
Log:
Reduce the (process globally) mutex-ed cache getter code by only
copying the serialized buffer in that critical section and performing
the de-serialization of the buffer content after the end of that section.

As a result, the server scalability increases slightly and de-serializer
functions get somewhat simplified as the data duplication has already
been done by the cache object.

* subversion/libsvn_subr/cache-memcache.c
  (memcache_get): already no local sync. but buffer must survive the
   end of the function
* subversion/libsvn_subr/cache-membuffer.c
  (membuffer_cache_set): fix compiler warning
  (membuffer_cache_get): duplicate cached data in CS, serialize outside
* subversion/libsvn_subr/cache-inprocess.c
  (inprocess_cache_get): dito
* subversion/libsvn_fs_fs/temp_serializer.c
  (svn_fs_fs__deserialize_txdelta_window, svn_fs_fs__deserialize_manifest,
   svn_fs_fs__deserialize_id, svn_fs_fs__deserialize_node_revision,
   svn_fs_fs__deserialize_dir_entries): remove the buffer duplication code

Modified:
    subversion/branches/performance/subversion/libsvn_fs_fs/temp_serializer.c
    subversion/branches/performance/subversion/libsvn_subr/cache-inprocess.c
    subversion/branches/performance/subversion/libsvn_subr/cache-membuffer.c
    subversion/branches/performance/subversion/libsvn_subr/cache-memcache.c

Modified: subversion/branches/performance/subversion/libsvn_fs_fs/temp_serializer.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_fs_fs/temp_serializer.c?rev=986832&r1=986831&r2=986832&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_fs_fs/temp_serializer.c (original)
+++ subversion/branches/performance/subversion/libsvn_fs_fs/temp_serializer.c Wed Aug 18 18:17:52 2010
@@ -492,9 +492,7 @@ svn_fs_fs__deserialize_txdelta_window(vo
 
   /* Copy the _full_ buffer as it also contains the sub-structures. */
   svn_fs_fs__txdelta_cached_window_t *window_info =
-      apr_palloc(pool, buffer_size);
-
-  memcpy(window_info, buffer, buffer_size);
+      (svn_fs_fs__txdelta_cached_window_t *)buffer;
 
   /* pointer reference fixup */
   svn_temp_deserializer__resolve(window_info,
@@ -536,11 +534,12 @@ svn_fs_fs__deserialize_manifest(void **o
                                 apr_size_t data_len,
                                 apr_pool_t *pool)
 {
-  apr_array_header_t *manifest = apr_array_make(pool,
-                                                data_len / sizeof(apr_off_t),
-                                                sizeof(apr_off_t));
-  memcpy(manifest->elts, data, data_len);
+  apr_array_header_t *manifest = apr_array_make(pool, 1, sizeof(apr_off_t));
+
   manifest->nelts = data_len / sizeof(apr_off_t);
+  manifest->nalloc = data_len / sizeof(apr_off_t);
+  manifest->elts = (char*)data;
+
   *out = manifest;
 
   return SVN_NO_ERROR;
@@ -581,8 +580,7 @@ svn_fs_fs__deserialize_id(void **out,
                           apr_pool_t *pool)
 {
   /* Copy the _full_ buffer as it also contains the sub-structures. */
-  svn_fs_id_t *id = apr_palloc(pool, data_len);
-  memcpy(id, data, data_len);
+  svn_fs_id_t *id = (svn_fs_id_t *)data;
 
   /* fixup of all pointers etc. */
   svn_fs_fs__id_deserialize(id, &id);
@@ -629,8 +627,7 @@ svn_fs_fs__deserialize_node_revision(voi
                                      apr_pool_t *pool)
 {
   /* Copy the _full_ buffer as it also contains the sub-structures. */
-  node_revision_t *noderev = apr_palloc(pool, buffer_size);
-  memcpy(noderev, buffer, buffer_size);
+  node_revision_t *noderev = (node_revision_t *)buffer;
 
   /* fixup of all pointers etc. */
   svn_fs_fs__noderev_deserialize(noderev, &noderev);
@@ -670,8 +667,7 @@ svn_fs_fs__deserialize_dir_entries(void 
                                    apr_pool_t *pool)
 {
   /* Copy the _full_ buffer as it also contains the sub-structures. */
-  hash_data_t *hash_data = apr_palloc(pool, data_len);
-  memcpy(hash_data, data, data_len);
+  hash_data_t *hash_data = (hash_data_t *)data;
 
   /* reconstruct the hash from the serialized data */
   *out = deserialize_dir(hash_data, hash_data, pool);

Modified: subversion/branches/performance/subversion/libsvn_subr/cache-inprocess.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_subr/cache-inprocess.c?rev=986832&r1=986831&r2=986832&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_subr/cache-inprocess.c (original)
+++ subversion/branches/performance/subversion/libsvn_subr/cache-inprocess.c Wed Aug 18 18:17:52 2010
@@ -207,7 +207,7 @@ inprocess_cache_get(void **value_p,
 {
   inprocess_cache_t *cache = cache_void;
   struct cache_entry *entry;
-  svn_error_t *err = SVN_NO_ERROR;
+  char* buffer;
 
   SVN_ERR(lock_cache(cache));
 
@@ -220,13 +220,23 @@ inprocess_cache_get(void **value_p,
 
   move_page_to_front(cache, entry->page);
 
+  /* duplicate the buffer entry */
+  buffer = apr_palloc(pool, entry->size);
+  memcpy(buffer, entry->value, entry->size);
+
+  /* the cache is no longer being accessed */
+  SVN_ERR(unlock_cache(cache, SVN_NO_ERROR));
+
+  /* deserialize the buffer content. Usually, this will directly
+     modify the buffer content directly.
+   */
   *found = TRUE;
   if (entry->value)
-    err = cache->deserialize_func(value_p, entry->value, entry->size, pool);
+    return cache->deserialize_func(value_p, buffer, entry->size, pool);
   else
     *value_p = NULL;
 
-  return unlock_cache(cache, err);
+  return unlock_cache(cache, SVN_NO_ERROR);
 }
 
 /* Removes PAGE from the LRU list, removes all of its entries from

Modified: subversion/branches/performance/subversion/libsvn_subr/cache-membuffer.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_subr/cache-membuffer.c?rev=986832&r1=986831&r2=986832&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_subr/cache-membuffer.c (original)
+++ subversion/branches/performance/subversion/libsvn_subr/cache-membuffer.c Wed Aug 18 18:17:52 2010
@@ -750,13 +750,12 @@ membuffer_cache_set(svn_membuffer_t *cac
   entry_t *entry;
   char *buffer;
   apr_size_t size;
-  svn_error_t *err;
 
   /* find the entry group that will hold the key.
    */
   group_index = get_group_index(cache, key, key_len, to_find, pool);
   if (group_index == -1)
-    return err;
+    return SVN_NO_ERROR;
 
   /* Serialize data data.
    */
@@ -818,7 +817,7 @@ membuffer_cache_get(svn_membuffer_t *cac
   apr_uint32_t group_index;
   unsigned char to_find[KEY_SIZE];
   entry_t *entry;
-  svn_error_t *err = SVN_NO_ERROR;
+  char* buffer;
 
   /* find the entry group that will hold the key.
    */
@@ -842,26 +841,23 @@ membuffer_cache_get(svn_membuffer_t *cac
       /* no such entry found.
        */
       *item = NULL;
+      return unlock_cache(cache, SVN_NO_ERROR);
     }
-  else
-    {
-      /* update hit statistics
-       */
-      entry->hit_count++;
-      cache->hit_count++;
-      cache->total_hits++;
 
-      /* re-construct the original data object from its serialized form.
-       */
-      err = deserializer(item,
-                         (const char*)cache->data + entry->offset,
-                         entry->size,
-                         pool);
-    }
+  buffer = apr_palloc(pool, entry->size);
+  memcpy(buffer, (const char*)cache->data + entry->offset, entry->size);
 
-  /* done here -> unlock the cache
+  /* update hit statistics
    */
-  return unlock_cache(cache, err);
+  entry->hit_count++;
+  cache->hit_count++;
+  cache->total_hits++;
+
+  SVN_ERR(unlock_cache(cache, SVN_NO_ERROR));
+
+  /* re-construct the original data object from its serialized form.
+   */
+  return deserializer(item, buffer, entry->size, pool);
 }
 
 svn_error_t* 
@@ -1157,7 +1153,7 @@ serialize_svn_stringbuf(char **buffer,
   svn_stringbuf_t *value_str = item;
 
   *buffer = value_str->data;
-  *buffer_size = value_str->len;
+  *buffer_size = value_str->len + 1;
 
   return SVN_NO_ERROR;
 }
@@ -1170,7 +1166,13 @@ deserialize_svn_stringbuf(void **item,
                           apr_size_t buffer_size,
                           apr_pool_t *pool)
 {
-  *item = svn_string_ncreate(buffer, buffer_size, pool);
+  svn_string_t *value_str = apr_palloc(pool, sizeof(svn_string_t));
+
+  value_str->data = (char*)buffer;
+  value_str->len = buffer_size-1;
+
+  *item = value_str;
+
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/performance/subversion/libsvn_subr/cache-memcache.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_subr/cache-memcache.c?rev=986832&r1=986831&r2=986832&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_subr/cache-memcache.c (original)
+++ subversion/branches/performance/subversion/libsvn_subr/cache-memcache.c Wed Aug 18 18:17:52 2010
@@ -141,7 +141,7 @@ memcache_get(void **value_p,
   mc_key = build_key(cache, key, subpool);
 
   apr_err = apr_memcache_getp(cache->memcache,
-                              (cache->deserialize_func ? subpool : pool),
+                              pool,
                               mc_key,
                               &data,
                               &data_len,