You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2015/11/30 11:24:23 UTC

svn commit: r1717223 [23/50] - in /subversion/branches/ra-git: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ contrib/hook-scripts/ notes/ notes/api-errata/1.9/ notes/move-tracking/ subversion/ subversion/bindings/ctypes-python/...

Modified: subversion/branches/ra-git/subversion/libsvn_fs_x/string_table.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_x/string_table.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_x/string_table.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_x/string_table.c Mon Nov 30 10:24:16 2015
@@ -376,7 +376,7 @@ svn_fs_x__string_table_builder_estimate_
 static void
 create_table(string_sub_table_t *target,
              builder_table_t *source,
-             apr_pool_t *pool,
+             apr_pool_t *result_pool,
              apr_pool_t *scratch_pool)
 {
   int i = 0;
@@ -387,7 +387,8 @@ create_table(string_sub_table_t *target,
 
   /* pack sub-strings */
   target->short_string_count = (apr_size_t)source->short_strings->nelts;
-  target->short_strings = apr_palloc(pool, sizeof(*target->short_strings) *
+  target->short_strings = apr_palloc(result_pool,
+                                     sizeof(*target->short_strings) *
                                            target->short_string_count);
   for (i = 0; i < source->short_strings->nelts; ++i)
     {
@@ -433,13 +434,14 @@ create_table(string_sub_table_t *target,
 
   /* pack long strings */
   target->long_string_count = (apr_size_t)source->long_strings->nelts;
-  target->long_strings = apr_palloc(pool, sizeof(*target->long_strings) *
+  target->long_strings = apr_palloc(result_pool,
+                                    sizeof(*target->long_strings) *
                                           target->long_string_count);
   for (i = 0; i < source->long_strings->nelts; ++i)
     {
       svn_string_t *string = &target->long_strings[i];
       *string = APR_ARRAY_IDX(source->long_strings, i, svn_string_t);
-      string->data = apr_pstrmemdup(pool, string->data, string->len);
+      string->data = apr_pstrmemdup(result_pool, string->data, string->len);
     }
 
   data->len += PADDING; /* add a few extra bytes at the end of the buffer
@@ -447,25 +449,25 @@ create_table(string_sub_table_t *target,
   assert(data->len < data->blocksize);
   memset(data->data + data->len - PADDING, 0, PADDING);
 
-  target->data = apr_pmemdup(pool, data->data, data->len);
+  target->data = apr_pmemdup(result_pool, data->data, data->len);
   target->data_size = data->len;
 }
 
 string_table_t *
 svn_fs_x__string_table_create(const string_table_builder_t *builder,
-                              apr_pool_t *pool)
+                              apr_pool_t *result_pool)
 {
   apr_size_t i;
 
-  string_table_t *result = apr_pcalloc(pool, sizeof(*result));
+  string_table_t *result = apr_pcalloc(result_pool, sizeof(*result));
   result->size = (apr_size_t)builder->tables->nelts;
   result->sub_tables
-    = apr_pcalloc(pool, result->size * sizeof(*result->sub_tables));
+    = apr_pcalloc(result_pool, result->size * sizeof(*result->sub_tables));
 
   for (i = 0; i < result->size; ++i)
     create_table(&result->sub_tables[i],
                  APR_ARRAY_IDX(builder->tables, i, builder_table_t*),
-                 pool,
+                 result_pool,
                  builder->pool);
 
   return result;
@@ -542,7 +544,7 @@ const char*
 svn_fs_x__string_table_get(const string_table_t *table,
                            apr_size_t idx,
                            apr_size_t *length,
-                           apr_pool_t *pool)
+                           apr_pool_t *result_pool)
 {
   apr_size_t table_number = idx >> TABLE_SHIFT;
   apr_size_t sub_index = idx & STRING_INDEX_MASK;
@@ -557,7 +559,7 @@ svn_fs_x__string_table_get(const string_
               if (length)
                 *length = sub_table->long_strings[sub_index].len;
 
-              return apr_pstrmemdup(pool,
+              return apr_pstrmemdup(result_pool,
                                     sub_table->long_strings[sub_index].data,
                                     sub_table->long_strings[sub_index].len);
             }
@@ -568,7 +570,7 @@ svn_fs_x__string_table_get(const string_
             {
               string_header_t *header = sub_table->short_strings + sub_index;
               apr_size_t len = header->head_length + header->tail_length;
-              char *result = apr_palloc(pool, len + PADDING);
+              char *result = apr_palloc(result_pool, len + PADDING);
 
               if (length)
                 *length = len;
@@ -579,7 +581,7 @@ svn_fs_x__string_table_get(const string_
         }
     }
 
-  return apr_pstrmemdup(pool, "", 0);
+  return apr_pstrmemdup(result_pool, "", 0);
 }
 
 svn_error_t *
@@ -830,7 +832,7 @@ const char*
 svn_fs_x__string_table_get_func(const string_table_t *table,
                                 apr_size_t idx,
                                 apr_size_t *length,
-                                apr_pool_t *pool)
+                                apr_pool_t *result_pool)
 {
   apr_size_t table_number = idx >> TABLE_SHIFT;
   apr_size_t sub_index = idx & STRING_INDEX_MASK;
@@ -861,7 +863,7 @@ svn_fs_x__string_table_get_func(const st
               if (length)
                 *length = long_strings[sub_index].len;
 
-              return apr_pstrmemdup(pool,
+              return apr_pstrmemdup(result_pool,
                                     str_data,
                                     long_strings[sub_index].len);
             }
@@ -889,7 +891,7 @@ svn_fs_x__string_table_get_func(const st
               /* reconstruct the char data and return it */
               header = table_copy.short_strings + sub_index;
               len = header->head_length + header->tail_length;
-              result = apr_palloc(pool, len + PADDING);
+              result = apr_palloc(result_pool, len + PADDING);
               if (length)
                 *length = len;
 

Modified: subversion/branches/ra-git/subversion/libsvn_fs_x/string_table.h
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_x/string_table.h?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_x/string_table.h (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_x/string_table.h Mon Nov 30 10:24:16 2015
@@ -69,21 +69,21 @@ apr_size_t
 svn_fs_x__string_table_builder_estimate_size(string_table_builder_t *builder);
 
 /* From the given BUILDER object, create a string table object allocated
- * in POOL that contains all strings previously added to BUILDER.
+ * in RESULT_POOL that contains all strings previously added to BUILDER.
  */
 string_table_t *
 svn_fs_x__string_table_create(const string_table_builder_t *builder,
-                              apr_pool_t *pool);
+                              apr_pool_t *result_pool);
 
 /* Extract string number INDEX from TABLE and return a copy of it allocated
- * in POOL.  If LENGTH is not NULL, set *LENGTH to strlen() of the result
- * string.  Returns an empty string for invalid indexes.
+ * in RESULT_POOL.  If LENGTH is not NULL, set *LENGTH to strlen() of the
+ * result string.  Returns an empty string for invalid indexes.
  */
 const char*
 svn_fs_x__string_table_get(const string_table_t *table,
                            apr_size_t index,
                            apr_size_t *length,
-                           apr_pool_t *pool);
+                           apr_pool_t *result_pool);
 
 /* Write a serialized representation of the string table TABLE to STREAM.
  * Use SCRATCH_POOL for temporary allocations.
@@ -116,15 +116,15 @@ svn_fs_x__deserialize_string_table(void
                                    string_table_t **table);
 
 /* Extract string number INDEX from the cache serialized representation at
- * TABLE and return a copy of it allocated in POOL.  If LENGTH is not NULL,
- * set *LENGTH to strlen() of the result string.  Returns an empty string
- * for invalid indexes.
+ * TABLE and return a copy of it allocated in RESULT_POOL.  If LENGTH is not
+ * NULL, set *LENGTH to strlen() of the result string.  Returns an empty
+ * string for invalid indexes.
  */
 const char*
 svn_fs_x__string_table_get_func(const string_table_t *table,
                                 apr_size_t idx,
                                 apr_size_t *length,
-                                apr_pool_t *pool);
+                                apr_pool_t *result_pool);
 
 #ifdef __cplusplus
 }

Modified: subversion/branches/ra-git/subversion/libsvn_fs_x/temp_serializer.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_x/temp_serializer.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_x/temp_serializer.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_x/temp_serializer.c Mon Nov 30 10:24:16 2015
@@ -71,13 +71,13 @@ encode_number(apr_int64_t number, char *
 const char*
 svn_fs_x__combine_number_and_string(apr_int64_t number,
                                     const char *string,
-                                    apr_pool_t *pool)
+                                    apr_pool_t *result_pool)
 {
   apr_size_t len = strlen(string);
 
   /* number part requires max. 10x7 bits + 1 space.
    * Add another 1 for the terminal 0 */
-  char *key_buffer = apr_palloc(pool, len + 12);
+  char *key_buffer = apr_palloc(result_pool, len + 12);
   const char *key = key_buffer;
 
   /* Prepend the number to the string and separate them by space. No other
@@ -120,7 +120,7 @@ serialize_svn_string(svn_temp_serializer
 /* Utility function to deserialize the STRING inside the BUFFER.
  */
 static void
-deserialize_svn_string(void *buffer, svn_string_t **string)
+deserialize_svn_string(const void *buffer, svn_string_t **string)
 {
   svn_temp_deserializer__resolve(buffer, (void **)string);
   if (*string == NULL)
@@ -173,14 +173,14 @@ svn_fs_x__serialize_apr_array(svn_temp_s
 void
 svn_fs_x__deserialize_apr_array(void *buffer,
                                 apr_array_header_t **array,
-                                apr_pool_t *pool)
+                                apr_pool_t *result_pool)
 {
   svn_temp_deserializer__resolve(buffer, (void **)array);
   if (*array == NULL)
     return;
 
   svn_temp_deserializer__resolve(*array, (void **)&(*array)->elts);
-  (*array)->pool = pool;
+  (*array)->pool = result_pool;
 }
 
 /* auxilliary structure representing the content of a directory array */
@@ -190,6 +190,10 @@ typedef struct dir_data_t
    * (it's int because the directory is an APR array) */
   int count;
 
+  /** Current length of the in-txn in-disk representation of the directory.
+   * SVN_INVALID_FILESIZE if unknown (i.e. committed data). */
+  svn_filesize_t txn_filesize;
+
   /* number of unused dir entry buckets in the index */
   apr_size_t over_provision;
 
@@ -224,7 +228,7 @@ serialize_dir_entry(svn_temp_serializer_
 
   svn_temp_serializer__push(context,
                             (const void * const *)entry_p,
-                            sizeof(svn_fs_x__dirent_t));
+                            sizeof(**entry_p));
 
   svn_temp_serializer__add_string(context, &entry->name);
 
@@ -234,18 +238,19 @@ serialize_dir_entry(svn_temp_serializer_
   svn_temp_serializer__pop(context);
 }
 
-/* Utility function to serialize the ENTRIES into a new serialization
+/* Utility function to serialize the DIR into a new serialization
  * context to be returned.
  *
  * Temporary allocation will be made form SCRATCH_POOL.
  */
 static svn_temp_serializer__context_t *
-serialize_dir(apr_array_header_t *entries,
+serialize_dir(svn_fs_x__dir_data_t *dir,
               apr_pool_t *scratch_pool)
 {
   dir_data_t dir_data;
   int i = 0;
   svn_temp_serializer__context_t *context;
+  apr_array_header_t *entries = dir->entries;
 
   /* calculate sizes */
   int count = entries->nelts;
@@ -256,6 +261,7 @@ serialize_dir(apr_array_header_t *entrie
 
   /* copy the hash entries to an auxiliary struct of known layout */
   dir_data.count = count;
+  dir_data.txn_filesize = dir->txn_filesize;
   dir_data.over_provision = over_provision;
   dir_data.operations = 0;
   dir_data.entries = apr_palloc(scratch_pool, entries_len);
@@ -292,24 +298,32 @@ serialize_dir(apr_array_header_t *entrie
   return context;
 }
 
-/* Utility function to reconstruct a dir entries array from serialized data
- * in BUFFER and DIR_DATA. Allocation will be made form POOL.
+/* Utility function to reconstruct a dir entries struct from serialized data
+ * in BUFFER and DIR_DATA. Allocation will be made form RESULT_POOL.
  */
-static apr_array_header_t *
-deserialize_dir(void *buffer, dir_data_t *dir_data, apr_pool_t *pool)
+static svn_fs_x__dir_data_t *
+deserialize_dir(void *buffer,
+                dir_data_t *dir_data,
+                apr_pool_t *result_pool)
 {
-  apr_array_header_t *result
-    = apr_array_make(pool, dir_data->count, sizeof(svn_fs_x__dirent_t *));
+  svn_fs_x__dir_data_t *result;
   apr_size_t i;
   apr_size_t count;
   svn_fs_x__dirent_t *entry;
   svn_fs_x__dirent_t **entries;
 
+  /* Construct empty directory object. */
+  result = apr_pcalloc(result_pool, sizeof(*result));
+  result->entries
+    = apr_array_make(result_pool, dir_data->count,
+                     sizeof(svn_fs_x__dirent_t *));
+  result->txn_filesize = dir_data->txn_filesize;
+
   /* resolve the reference to the entries array */
   svn_temp_deserializer__resolve(buffer, (void **)&dir_data->entries);
   entries = dir_data->entries;
 
-  /* fixup the references within each entry and add it to the hash */
+  /* fixup the references within each entry and add it to the RESULT */
   for (i = 0, count = dir_data->count; i < count; ++i)
     {
       svn_temp_deserializer__resolve(entries, (void **)&entries[i]);
@@ -319,16 +333,19 @@ deserialize_dir(void *buffer, dir_data_t
       svn_temp_deserializer__resolve(entry, (void **)&entry->name);
 
       /* add the entry to the hash */
-      APR_ARRAY_PUSH(result, svn_fs_x__dirent_t *) = entry;
+      APR_ARRAY_PUSH(result->entries, svn_fs_x__dirent_t *) = entry;
     }
 
   /* return the now complete hash */
   return result;
 }
 
-void
-svn_fs_x__noderev_serialize(svn_temp_serializer__context_t *context,
-                            svn_fs_x__noderev_t * const *noderev_p)
+/**
+ * Serialize a NODEREV_P within the serialization CONTEXT.
+ */
+static void
+noderev_serialize(svn_temp_serializer__context_t *context,
+                  svn_fs_x__noderev_t * const *noderev_p)
 {
   const svn_fs_x__noderev_t *noderev = *noderev_p;
   if (noderev == NULL)
@@ -351,11 +368,12 @@ svn_fs_x__noderev_serialize(svn_temp_ser
   svn_temp_serializer__pop(context);
 }
 
-
-void
-svn_fs_x__noderev_deserialize(void *buffer,
-                              svn_fs_x__noderev_t **noderev_p,
-                              apr_pool_t *pool)
+/**
+ * Deserialize a NODEREV_P within the BUFFER and associate it with.
+ */
+static void
+noderev_deserialize(void *buffer,
+                    svn_fs_x__noderev_t **noderev_p)
 {
   svn_fs_x__noderev_t *noderev;
 
@@ -451,7 +469,7 @@ svn_error_t *
 svn_fs_x__deserialize_txdelta_window(void **item,
                                      void *buffer,
                                      apr_size_t buffer_size,
-                                     apr_pool_t *pool)
+                                     apr_pool_t *result_pool)
 {
   svn_txdelta_window_t *window;
 
@@ -474,38 +492,6 @@ svn_fs_x__deserialize_txdelta_window(voi
   return SVN_NO_ERROR;
 }
 
-svn_error_t *
-svn_fs_x__serialize_manifest(void **data,
-                             apr_size_t *data_len,
-                             void *in,
-                             apr_pool_t *pool)
-{
-  apr_array_header_t *manifest = in;
-
-  *data_len = sizeof(apr_off_t) *manifest->nelts;
-  *data = apr_palloc(pool, *data_len);
-  memcpy(*data, manifest->elts, *data_len);
-
-  return SVN_NO_ERROR;
-}
-
-svn_error_t *
-svn_fs_x__deserialize_manifest(void **out,
-                               void *data,
-                               apr_size_t data_len,
-                               apr_pool_t *pool)
-{
-  apr_array_header_t *manifest = apr_array_make(pool, 1, sizeof(apr_off_t));
-
-  manifest->nelts = (int) (data_len / sizeof(apr_off_t));
-  manifest->nalloc = (int) (data_len / sizeof(apr_off_t));
-  manifest->elts = (char*)data;
-
-  *out = manifest;
-
-  return SVN_NO_ERROR;
-}
-
 /* Auxiliary structure representing the content of a properties hash.
    This structure is much easier to (de-)serialize than an apr_hash.
  */
@@ -579,7 +565,7 @@ svn_fs_x__serialize_properties(void **da
   /* create our auxiliary data structure */
   properties.count = apr_hash_count(hash);
   properties.keys = apr_palloc(pool, sizeof(const char*) * (properties.count + 1));
-  properties.values = apr_palloc(pool, sizeof(const char*) * properties.count);
+  properties.values = apr_palloc(pool, sizeof(const svn_string_t *) * properties.count);
 
   /* populate it with the hash entries */
   for (hi = apr_hash_first(pool, hash), i=0; hi; hi = apr_hash_next(hi), ++i)
@@ -611,9 +597,9 @@ svn_error_t *
 svn_fs_x__deserialize_properties(void **out,
                                  void *data,
                                  apr_size_t data_len,
-                                 apr_pool_t *pool)
+                                 apr_pool_t *result_pool)
 {
-  apr_hash_t *hash = svn_hash__make(pool);
+  apr_hash_t *hash = svn_hash__make(result_pool);
   properties_data_t *properties = (properties_data_t *)data;
   size_t i;
 
@@ -661,7 +647,7 @@ svn_fs_x__serialize_node_revision(void *
                                 pool);
 
   /* serialize the noderev */
-  svn_fs_x__noderev_serialize(context, &noderev);
+  noderev_serialize(context, &noderev);
 
   /* return serialized data */
   serialized = svn_temp_serializer__get(context);
@@ -675,13 +661,13 @@ svn_error_t *
 svn_fs_x__deserialize_node_revision(void **item,
                                     void *buffer,
                                     apr_size_t buffer_size,
-                                    apr_pool_t *pool)
+                                    apr_pool_t *result_pool)
 {
   /* Copy the _full_ buffer as it also contains the sub-structures. */
   svn_fs_x__noderev_t *noderev = (svn_fs_x__noderev_t *)buffer;
 
   /* fixup of all pointers etc. */
-  svn_fs_x__noderev_deserialize(noderev, &noderev, pool);
+  noderev_deserialize(noderev, &noderev);
 
   /* done */
   *item = noderev;
@@ -710,7 +696,7 @@ svn_fs_x__serialize_dir_entries(void **d
                                 void *in,
                                 apr_pool_t *pool)
 {
-  apr_array_header_t *dir = in;
+  svn_fs_x__dir_data_t *dir = in;
 
   /* serialize the dir content into a new serialization context
    * and return the serialized data */
@@ -723,13 +709,13 @@ svn_error_t *
 svn_fs_x__deserialize_dir_entries(void **out,
                                   void *data,
                                   apr_size_t data_len,
-                                  apr_pool_t *pool)
+                                  apr_pool_t *result_pool)
 {
   /* Copy the _full_ buffer as it also contains the sub-structures. */
   dir_data_t *dir_data = (dir_data_t *)data;
 
   /* reconstruct the hash from the serialized data */
-  *out = deserialize_dir(dir_data, dir_data, pool);
+  *out = deserialize_dir(dir_data, dir_data, result_pool);
 
   return SVN_NO_ERROR;
 }
@@ -749,6 +735,20 @@ svn_fs_x__get_sharded_offset(void **out,
   return SVN_NO_ERROR;
 }
 
+svn_error_t *
+svn_fs_x__extract_dir_filesize(void **out,
+                               const void *data,
+                               apr_size_t data_len,
+                               void *baton,
+                               apr_pool_t *pool)
+{
+  const dir_data_t *dir_data = data;
+
+  *(svn_filesize_t *)out = dir_data->txn_filesize;
+
+  return SVN_NO_ERROR;
+}
+
 /* Utility function that returns the lowest index of the first entry in
  * *ENTRIES that points to a dir entry with a name equal or larger than NAME.
  * If an exact match has been found, *FOUND will be set to TRUE. COUNT is
@@ -858,8 +858,9 @@ svn_fs_x__extract_dir_entry(void **out,
   if (found)
     b->hint = pos;
 
-  /* de-serialize that entry or return NULL, if no match has been found */
-  if (found)
+  /* de-serialize that entry or return NULL, if no match has been found.
+   * Be sure to check that the directory contents is still up-to-date. */
+  if (found && dir_data->txn_filesize == b->txn_filesize)
     {
       const svn_fs_x__dirent_t *source =
           svn_temp_deserializer__ptr(entries, (const void *const *)&entries[pos]);
@@ -872,8 +873,7 @@ svn_fs_x__extract_dir_entry(void **out,
       apr_size_t size = lengths[pos];
 
       /* copy & deserialize the entry */
-      svn_fs_x__dirent_t *new_entry = apr_palloc(pool, size);
-      memcpy(new_entry, source, size);
+      svn_fs_x__dirent_t *new_entry = apr_pmemdup(pool, source, size);
 
       svn_temp_deserializer__resolve(new_entry, (void **)&new_entry->name);
       *(svn_fs_x__dirent_t **)out = new_entry;
@@ -893,32 +893,34 @@ slowly_replace_dir_entry(void **data,
 {
   replace_baton_t *replace_baton = (replace_baton_t *)baton;
   dir_data_t *dir_data = (dir_data_t *)*data;
-  apr_array_header_t *dir;
+  svn_fs_x__dir_data_t *dir;
   int idx = -1;
   svn_fs_x__dirent_t *entry;
+  apr_array_header_t *entries;
 
   SVN_ERR(svn_fs_x__deserialize_dir_entries((void **)&dir,
                                             *data,
                                             dir_data->len,
                                             pool));
 
-  entry = svn_fs_x__find_dir_entry(dir, replace_baton->name, &idx);
+  entries = dir->entries;
+  entry = svn_fs_x__find_dir_entry(entries, replace_baton->name, &idx);
 
   /* Replacement or removal? */
   if (replace_baton->new_entry)
     {
       /* Replace ENTRY with / insert the NEW_ENTRY */
       if (entry)
-        APR_ARRAY_IDX(dir, idx, svn_fs_x__dirent_t *)
+        APR_ARRAY_IDX(entries, idx, svn_fs_x__dirent_t *)
           = replace_baton->new_entry;
       else
-        svn_sort__array_insert(dir, &replace_baton->new_entry, idx);
+        svn_sort__array_insert(entries, &replace_baton->new_entry, idx);
     }
   else
     {
       /* Remove the old ENTRY. */
       if (entry)
-        svn_sort__array_delete(dir, idx, 1);
+        svn_sort__array_delete(entries, idx, 1);
     }
 
   return svn_fs_x__serialize_dir_entries(data, data_len, dir, pool);
@@ -940,6 +942,12 @@ svn_fs_x__replace_dir_entry(void **data,
 
   svn_temp_serializer__context_t *context;
 
+  /* update the cached file length info.
+   * Because we are writing to the cache, it is fair to assume that the
+   * caller made sure that the current contents is consistent with the
+   * previous state of the directory file. */
+  dir_data->txn_filesize = replace_baton->txn_filesize;
+
   /* after quite a number of operations, let's re-pack everything.
    * This is to limit the number of wasted space as we cannot overwrite
    * existing data but must always append. */
@@ -1029,17 +1037,26 @@ svn_fs_x__replace_dir_entry(void **data,
   return SVN_NO_ERROR;
 }
 
+svn_error_t *
+svn_fs_x__reset_txn_filesize(void **data,
+                             apr_size_t *data_len,
+                             void *baton,
+                             apr_pool_t *pool)
+{
+  dir_data_t *dir_data = (dir_data_t *)*data;
+  dir_data->txn_filesize = SVN_INVALID_FILESIZE;
+
+  return SVN_NO_ERROR;
+}
+
 svn_error_t  *
 svn_fs_x__serialize_rep_header(void **data,
                                apr_size_t *data_len,
                                void *in,
                                apr_pool_t *pool)
 {
-  svn_fs_x__rep_header_t *copy = apr_palloc(pool, sizeof(*copy));
-  *copy = *(svn_fs_x__rep_header_t *)in;
-
   *data_len = sizeof(svn_fs_x__rep_header_t);
-  *data = copy;
+  *data = in;
 
   return SVN_NO_ERROR;
 }
@@ -1048,12 +1065,8 @@ svn_error_t *
 svn_fs_x__deserialize_rep_header(void **out,
                                  void *data,
                                  apr_size_t data_len,
-                                 apr_pool_t *pool)
+                                 apr_pool_t *result_pool)
 {
-  svn_fs_x__rep_header_t *copy = apr_palloc(pool, sizeof(*copy));
-  SVN_ERR_ASSERT(data_len == sizeof(*copy));
-
-  *copy = *(svn_fs_x__rep_header_t *)data;
   *out = data;
 
   return SVN_NO_ERROR;
@@ -1088,8 +1101,7 @@ serialize_change(svn_temp_serializer__co
  */
 static void
 deserialize_change(void *buffer,
-                   svn_fs_x__change_t **change_p,
-                   apr_pool_t *pool)
+                   svn_fs_x__change_t **change_p)
 {
   svn_fs_x__change_t * change;
 
@@ -1142,7 +1154,7 @@ svn_fs_x__serialize_changes(void **data,
 
   svn_temp_serializer__push(context,
                             (const void * const *)&changes.changes,
-                            changes.count * sizeof(svn_fs_x__change_t*));
+                            changes.count * sizeof(**changes.changes));
 
   for (i = 0; i < changes.count; ++i)
     serialize_change(context, &changes.changes[i]);
@@ -1162,11 +1174,11 @@ svn_error_t *
 svn_fs_x__deserialize_changes(void **out,
                               void *data,
                               apr_size_t data_len,
-                              apr_pool_t *pool)
+                              apr_pool_t *result_pool)
 {
   int i;
   changes_data_t *changes = (changes_data_t *)data;
-  apr_array_header_t *array = apr_array_make(pool, 0,
+  apr_array_header_t *array = apr_array_make(result_pool, 0,
                                              sizeof(svn_fs_x__change_t *));
 
   /* de-serialize our auxiliary data structure */
@@ -1175,8 +1187,7 @@ svn_fs_x__deserialize_changes(void **out
   /* de-serialize each entry and add it to the array */
   for (i = 0; i < changes->count; ++i)
     deserialize_change(changes->changes,
-                       (svn_fs_x__change_t **)&changes->changes[i],
-                       pool);
+                       (svn_fs_x__change_t **)&changes->changes[i]);
 
   /* Use the changes buffer as the array's data buffer
    * (DATA remains valid for at least as long as POOL). */
@@ -1189,149 +1200,4 @@ svn_fs_x__deserialize_changes(void **out
 
   return SVN_NO_ERROR;
 }
-
-/* Auxiliary structure representing the content of a svn_mergeinfo_t hash.
-   This structure is much easier to (de-)serialize than an APR array.
- */
-typedef struct mergeinfo_data_t
-{
-  /* number of paths in the hash */
-  unsigned count;
-
-  /* COUNT keys (paths) */
-  const char **keys;
-
-  /* COUNT keys lengths (strlen of path) */
-  apr_ssize_t *key_lengths;
-
-  /* COUNT entries, each giving the number of ranges for the key */
-  int *range_counts;
-
-  /* all ranges in a single, concatenated buffer */
-  svn_merge_range_t *ranges;
-} mergeinfo_data_t;
-
-svn_error_t *
-svn_fs_x__serialize_mergeinfo(void **data,
-                              apr_size_t *data_len,
-                              void *in,
-                              apr_pool_t *pool)
-{
-  svn_mergeinfo_t mergeinfo = in;
-  mergeinfo_data_t merges;
-  svn_temp_serializer__context_t *context;
-  svn_stringbuf_t *serialized;
-  apr_hash_index_t *hi;
-  unsigned i;
-  int k;
-  apr_size_t range_count;
-
-  /* initialize our auxiliary data structure */
-  merges.count = apr_hash_count(mergeinfo);
-  merges.keys = apr_palloc(pool, sizeof(*merges.keys) * merges.count);
-  merges.key_lengths = apr_palloc(pool, sizeof(*merges.key_lengths) *
-                                        merges.count);
-  merges.range_counts = apr_palloc(pool, sizeof(*merges.range_counts) *
-                                         merges.count);
-
-  i = 0;
-  range_count = 0;
-  for (hi = apr_hash_first(pool, mergeinfo); hi; hi = apr_hash_next(hi), ++i)
-    {
-      svn_rangelist_t *ranges;
-      apr_hash_this(hi, (const void**)&merges.keys[i],
-                        &merges.key_lengths[i],
-                        (void **)&ranges);
-      merges.range_counts[i] = ranges->nelts;
-      range_count += ranges->nelts;
-    }
-
-  merges.ranges = apr_palloc(pool, sizeof(*merges.ranges) * range_count);
-
-  i = 0;
-  for (hi = apr_hash_first(pool, mergeinfo); hi; hi = apr_hash_next(hi))
-    {
-      svn_rangelist_t *ranges = apr_hash_this_val(hi);
-      for (k = 0; k < ranges->nelts; ++k, ++i)
-        merges.ranges[i] = *APR_ARRAY_IDX(ranges, k, svn_merge_range_t*);
-    }
-
-  /* serialize it and all its elements */
-  context = svn_temp_serializer__init(&merges,
-                                      sizeof(merges),
-                                      range_count * 30,
-                                      pool);
-
-  /* keys array */
-  svn_temp_serializer__push(context,
-                            (const void * const *)&merges.keys,
-                            merges.count * sizeof(*merges.keys));
-
-  for (i = 0; i < merges.count; ++i)
-    svn_temp_serializer__add_string(context, &merges.keys[i]);
-
-  svn_temp_serializer__pop(context);
-
-  /* key lengths array */
-  svn_temp_serializer__add_leaf(context,
-                                (const void * const *)&merges.key_lengths,
-                                merges.count * sizeof(*merges.key_lengths));
-
-  /* range counts array */
-  svn_temp_serializer__add_leaf(context,
-                                (const void * const *)&merges.range_counts,
-                                merges.count * sizeof(*merges.range_counts));
-
-  /* ranges */
-  svn_temp_serializer__add_leaf(context,
-                                (const void * const *)&merges.ranges,
-                                range_count * sizeof(*merges.ranges));
-
-  /* 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_x__deserialize_mergeinfo(void **out,
-                                void *data,
-                                apr_size_t data_len,
-                                apr_pool_t *pool)
-{
-  unsigned i;
-  int k, n;
-  mergeinfo_data_t *merges = (mergeinfo_data_t *)data;
-  svn_mergeinfo_t mergeinfo;
-
-  /* de-serialize our auxiliary data structure */
-  svn_temp_deserializer__resolve(merges, (void**)&merges->keys);
-  svn_temp_deserializer__resolve(merges, (void**)&merges->key_lengths);
-  svn_temp_deserializer__resolve(merges, (void**)&merges->range_counts);
-  svn_temp_deserializer__resolve(merges, (void**)&merges->ranges);
-
-  /* de-serialize keys and add entries to the result */
-  n = 0;
-  mergeinfo = svn_hash__make(pool);
-  for (i = 0; i < merges->count; ++i)
-    {
-      svn_rangelist_t *ranges = apr_array_make(pool,
-                                               merges->range_counts[i],
-                                               sizeof(svn_merge_range_t*));
-      for (k = 0; k < merges->range_counts[i]; ++k, ++n)
-        APR_ARRAY_PUSH(ranges, svn_merge_range_t*) = &merges->ranges[n];
-
-      svn_temp_deserializer__resolve(merges->keys,
-                                     (void**)&merges->keys[i]);
-      apr_hash_set(mergeinfo, merges->keys[i], merges->key_lengths[i], ranges);
-    }
-
-  /* done */
-  *out = mergeinfo;
-
-  return SVN_NO_ERROR;
-}
 

Modified: subversion/branches/ra-git/subversion/libsvn_fs_x/temp_serializer.h
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_x/temp_serializer.h?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_x/temp_serializer.h (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_x/temp_serializer.h Mon Nov 30 10:24:16 2015
@@ -20,8 +20,8 @@
  * ====================================================================
  */
 
-#ifndef SVN_LIBSVN_FS__TEMP_SERIALIZER_H
-#define SVN_LIBSVN_FS__TEMP_SERIALIZER_H
+#ifndef SVN_LIBSVN_FS_X_TEMP_SERIALIZER_H
+#define SVN_LIBSVN_FS_X_TEMP_SERIALIZER_H
 
 #include "private/svn_temp_serializer.h"
 #include "fs.h"
@@ -29,28 +29,12 @@
 /**
  * Prepend the @a number to the @a string in a space efficient way such that
  * no other (number,string) combination can produce the same result.
- * Allocate temporaries as well as the result from @a pool.
+ * Allocate the result from @a result_pool.
  */
 const char*
 svn_fs_x__combine_number_and_string(apr_int64_t number,
                                     const char *string,
-                                    apr_pool_t *pool);
-
-/**
- * Serialize a @a noderev_p within the serialization @a context.
- */
-void
-svn_fs_x__noderev_serialize(struct svn_temp_serializer__context_t *context,
-                            svn_fs_x__noderev_t * const *noderev_p);
-
-/**
- * Deserialize a @a noderev_p within the @a buffer and associate it with
- * @a pool.
- */
-void
-svn_fs_x__noderev_deserialize(void *buffer,
-                              svn_fs_x__noderev_t **noderev_p,
-                              apr_pool_t *pool);
+                                    apr_pool_t *result_pool);
 
 /**
  * Serialize APR array @a *a within the serialization @a context.
@@ -62,12 +46,12 @@ svn_fs_x__serialize_apr_array(struct svn
 
 /**
  * Deserialize APR @a *array within the @a buffer.  Set its pool member to
- * @a pool.  The elements within the array must not contain pointers.
+ * @a result_pool.  The elements within the array must not contain pointers.
  */
 void
 svn_fs_x__deserialize_apr_array(void *buffer,
                                 apr_array_header_t **array,
-                                apr_pool_t *pool);
+                                apr_pool_t *result_pool);
 
 
 /**
@@ -104,27 +88,7 @@ svn_error_t *
 svn_fs_x__deserialize_txdelta_window(void **item,
                                      void *buffer,
                                      apr_size_t buffer_size,
-                                     apr_pool_t *pool);
-
-/**
- * Implements #svn_cache__serialize_func_t for a manifest
- * (@a in is an #apr_array_header_t of apr_off_t elements).
- */
-svn_error_t *
-svn_fs_x__serialize_manifest(void **data,
-                             apr_size_t *data_len,
-                             void *in,
-                             apr_pool_t *pool);
-
-/**
- * Implements #svn_cache__deserialize_func_t for a manifest
- * (@a *out is an #apr_array_header_t of apr_off_t elements).
- */
-svn_error_t *
-svn_fs_x__deserialize_manifest(void **out,
-                               void *data,
-                               apr_size_t data_len,
-                               apr_pool_t *pool);
+                                     apr_pool_t *result_pool);
 
 /**
  * Implements #svn_cache__serialize_func_t for a properties hash
@@ -144,7 +108,7 @@ svn_error_t *
 svn_fs_x__deserialize_properties(void **out,
                                  void *data,
                                  apr_size_t data_len,
-                                 apr_pool_t *pool);
+                                 apr_pool_t *result_pool);
 
 /**
  * Implements #svn_cache__serialize_func_t for #svn_fs_x__noderev_t
@@ -162,10 +126,10 @@ svn_error_t *
 svn_fs_x__deserialize_node_revision(void **item,
                                     void *buffer,
                                     apr_size_t buffer_size,
-                                    apr_pool_t *pool);
+                                    apr_pool_t *result_pool);
 
 /**
- * Implements #svn_cache__serialize_func_t for a directory contents array
+ * Implements #svn_cache__serialize_func_t for a #svn_fs_x__dir_data_t
  */
 svn_error_t *
 svn_fs_x__serialize_dir_entries(void **data,
@@ -174,13 +138,13 @@ svn_fs_x__serialize_dir_entries(void **d
                                 apr_pool_t *pool);
 
 /**
- * Implements #svn_cache__deserialize_func_t for a directory contents array
+ * Implements #svn_cache__deserialize_func_t for a #svn_fs_x__dir_data_t
  */
 svn_error_t *
 svn_fs_x__deserialize_dir_entries(void **out,
                                   void *data,
                                   apr_size_t data_len,
-                                  apr_pool_t *pool);
+                                  apr_pool_t *result_pool);
 
 /**
  * Implements #svn_cache__partial_getter_func_t.  Set (apr_off_t) @a *out
@@ -194,6 +158,18 @@ svn_fs_x__get_sharded_offset(void **out,
                              apr_pool_t *pool);
 
 /**
+ * Implements #svn_cache__partial_getter_func_t.
+ * Set (svn_filesize_t) @a *out to the filesize info stored with the
+ * serialized directory in @a data of @a data_len.  @a baton is unused.
+ */
+svn_error_t *
+svn_fs_x__extract_dir_filesize(void **out,
+                               const void *data,
+                               apr_size_t data_len,
+                               void *baton,
+                               apr_pool_t *pool);
+
+/**
  * Baton type to be used with svn_fs_x__extract_dir_entry. */
 typedef struct svn_fs_x__ede_baton_t
 {
@@ -202,12 +178,18 @@ typedef struct svn_fs_x__ede_baton_t
 
   /* Lookup hint [in / out] */
   apr_size_t hint;
+
+  /** Current length of the in-txn in-disk representation of the directory.
+   * SVN_INVALID_FILESIZE if unknown. */
+  svn_filesize_t txn_filesize;
 } svn_fs_x__ede_baton_t;
 
 /**
  * Implements #svn_cache__partial_getter_func_t for a single
  * #svn_fs_x__dirent_t within a serialized directory contents hash,
- * identified by its name (given in @a svn_fs_x__ede_baton_t @a *baton).
+ * identified by its name (in (svn_fs_x__ede_baton_t *) @a *baton).
+ * If the filesize specified in the baton does not match the cached
+ * value for this directory, @a *out will be NULL as well.
  */
 svn_error_t *
 svn_fs_x__extract_dir_entry(void **out,
@@ -220,7 +202,10 @@ svn_fs_x__extract_dir_entry(void **out,
  * Describes the change to be done to a directory: Set the entry
  * identify by @a name to the value @a new_entry. If the latter is
  * @c NULL, the entry shall be removed if it exists. Otherwise it
- * will be replaced or automatically added, respectively.
+ * will be replaced or automatically added, respectively.  The
+ * @a filesize allows readers to identify stale cache data (e.g.
+ * due to concurrent access to txns); writers use it to update the
+ * cached file size info.
  */
 typedef struct replace_baton_t
 {
@@ -229,6 +214,10 @@ typedef struct replace_baton_t
 
   /** directory entry to insert instead */
   svn_fs_x__dirent_t *new_entry;
+
+  /** Current length of the in-txn in-disk representation of the directory.
+   * SVN_INVALID_FILESIZE if unknown. */
+  svn_filesize_t txn_filesize;
 } replace_baton_t;
 
 /**
@@ -243,6 +232,17 @@ svn_fs_x__replace_dir_entry(void **data,
                             apr_pool_t *pool);
 
 /**
+ * Implements #svn_cache__partial_setter_func_t for a #svn_fs_x__dir_data_t
+ * at @a *data, resetting its txn_filesize field to SVN_INVALID_FILESIZE.
+ * &a baton should be NULL.
+ */
+svn_error_t *
+svn_fs_x__reset_txn_filesize(void **data,
+                             apr_size_t *data_len,
+                             void *baton,
+                             apr_pool_t *pool);
+
+/**
  * Implements #svn_cache__serialize_func_t for a #svn_fs_x__rep_header_t.
  */
 svn_error_t *
@@ -258,7 +258,7 @@ svn_error_t *
 svn_fs_x__deserialize_rep_header(void **out,
                                  void *data,
                                  apr_size_t data_len,
-                                 apr_pool_t *pool);
+                                 apr_pool_t *result_pool);
 
 /**
  * Implements #svn_cache__serialize_func_t for an #apr_array_header_t of
@@ -278,24 +278,6 @@ svn_error_t *
 svn_fs_x__deserialize_changes(void **out,
                               void *data,
                               apr_size_t data_len,
-                              apr_pool_t *pool);
-
-/**
- * Implements #svn_cache__serialize_func_t for #svn_mergeinfo_t objects.
- */
-svn_error_t *
-svn_fs_x__serialize_mergeinfo(void **data,
-                              apr_size_t *data_len,
-                              void *in,
-                              apr_pool_t *pool);
-
-/**
- * Implements #svn_cache__deserialize_func_t for #svn_mergeinfo_t objects.
- */
-svn_error_t *
-svn_fs_x__deserialize_mergeinfo(void **out,
-                                void *data,
-                                apr_size_t data_len,
-                                apr_pool_t *pool);
+                              apr_pool_t *result_pool);
 
 #endif