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 [18/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/cached_data.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_x/cached_data.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_x/cached_data.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_x/cached_data.c Mon Nov 30 10:24:16 2015
@@ -173,21 +173,6 @@ dgb__log_access(svn_fs_t *fs,
   return SVN_NO_ERROR;
 }
 
-/* Convenience wrapper around svn_io_file_aligned_seek, taking filesystem
-   FS instead of a block size. */
-static svn_error_t *
-aligned_seek(svn_fs_t *fs,
-             apr_file_t *file,
-             apr_off_t *buffer_start,
-             apr_off_t offset,
-             apr_pool_t *scratch_pool)
-{
-  svn_fs_x__data_t *ffd = fs->fsap_data;
-  return svn_error_trace(svn_io_file_aligned_seek(file, ffd->block_size,
-                                                  buffer_start, offset,
-                                                  scratch_pool));
-}
-
 /* Open the revision file for the item given by ID in filesystem FS and
    store the newly opened file in FILE.  Seek to the item's location before
    returning.
@@ -207,11 +192,10 @@ open_and_seek_revision(svn_fs_x__revisio
 
   SVN_ERR(svn_fs_x__ensure_revision_exists(rev, fs, scratch_pool));
 
-  SVN_ERR(svn_fs_x__open_pack_or_rev_file(&rev_file, fs, rev, result_pool,
-                                          scratch_pool));
+  SVN_ERR(svn_fs_x__rev_file_init(&rev_file, fs, rev, result_pool));
   SVN_ERR(svn_fs_x__item_offset(&offset, &sub_item, fs, rev_file, id,
                                 scratch_pool));
-  SVN_ERR(aligned_seek(fs, rev_file->file, NULL, offset, scratch_pool));
+  SVN_ERR(svn_fs_x__rev_file_seek(rev_file, NULL, offset));
 
   *file = rev_file;
 
@@ -233,12 +217,12 @@ open_and_seek_transaction(svn_fs_x__revi
   apr_uint32_t sub_item = 0;
   apr_int64_t txn_id = svn_fs_x__get_txn_id(rep->id.change_set);
 
-  SVN_ERR(svn_fs_x__open_proto_rev_file(file, fs, txn_id, result_pool,
-                                        scratch_pool));
+  SVN_ERR(svn_fs_x__rev_file_open_proto_rev(file, fs, txn_id, result_pool,
+                                            scratch_pool));
 
   SVN_ERR(svn_fs_x__item_offset(&offset, &sub_item, fs, *file, &rep->id,
                                 scratch_pool));
-  SVN_ERR(aligned_seek(fs, (*file)->file, NULL, offset, scratch_pool));
+  SVN_ERR(svn_fs_x__rev_file_seek(*file, NULL, offset));
 
   return SVN_NO_ERROR;
 }
@@ -294,6 +278,7 @@ get_node_revision_body(svn_fs_x__noderev
   if (svn_fs_x__is_txn(id->change_set))
     {
       apr_file_t *file;
+      svn_stream_t *stream;
 
       /* This is a transaction node-rev.  Its storage logic is very
          different from that of rev / pack files. */
@@ -314,10 +299,9 @@ get_node_revision_body(svn_fs_x__noderev
           return svn_error_trace(err);
         }
 
-      SVN_ERR(svn_fs_x__read_noderev(noderev_p,
-                                     svn_stream_from_aprfile2(file,
-                                                              FALSE,
-                                                              scratch_pool),
+      /* Be sure to close the file ASAP. */
+      stream = svn_stream_from_aprfile2(file, FALSE, scratch_pool);
+      SVN_ERR(svn_fs_x__read_noderev(noderev_p, stream,
                                      result_pool, scratch_pool));
     }
   else
@@ -328,8 +312,8 @@ get_node_revision_body(svn_fs_x__noderev
       svn_revnum_t revision = svn_fs_x__get_revnum(id->change_set);
       svn_fs_x__pair_cache_key_t key;
 
-      SVN_ERR(svn_fs_x__open_pack_or_rev_file(&revision_file, fs, revision,
-                                              scratch_pool, scratch_pool));
+      SVN_ERR(svn_fs_x__rev_file_init(&revision_file, fs, revision,
+                                      scratch_pool));
 
       /* First, try a noderevs container cache lookup. */
       if (   svn_fs_x__is_packed_rev(fs, revision)
@@ -355,16 +339,13 @@ get_node_revision_body(svn_fs_x__noderev
 
       /* 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,
-                                 &is_cached,
-                                 ffd->node_revision_cache,
-                                 &key,
-                                 result_pool));
-          if (is_cached)
-            return SVN_NO_ERROR;
-        }
+      SVN_ERR(svn_cache__get((void **) noderev_p,
+                             &is_cached,
+                             ffd->node_revision_cache,
+                             &key,
+                             result_pool));
+      if (is_cached)
+        return SVN_NO_ERROR;
 
       /* block-read will parse the whole block and will also return
          the one noderev that we need right now. */
@@ -423,8 +404,8 @@ svn_fs_x__get_mergeinfo_count(apr_int64_
       svn_revnum_t revision = svn_fs_x__get_revnum(id->change_set);
 
       svn_fs_x__revision_file_t *rev_file;
-      SVN_ERR(svn_fs_x__open_pack_or_rev_file(&rev_file, fs, revision,
-                                              scratch_pool, scratch_pool));
+      SVN_ERR(svn_fs_x__rev_file_init(&rev_file, fs, revision,
+                                      scratch_pool));
 
       if (   svn_fs_x__is_packed_rev(fs, revision)
           && ffd->noderevs_container_cache)
@@ -505,39 +486,13 @@ typedef struct rep_state_t
   int chunk_index;  /* number of the window to read */
 } rep_state_t;
 
-/* Simple wrapper around svn_fs_x__get_file_offset to simplify callers. */
-static svn_error_t *
-get_file_offset(apr_off_t *offset,
-                rep_state_t *rs,
-                apr_pool_t *scratch_pool)
-{
-  return svn_error_trace(svn_fs_x__get_file_offset(offset,
-                                                   rs->sfile->rfile->file,
-                                                   scratch_pool));
-}
-
-/* Simple wrapper around svn_io_file_aligned_seek to simplify callers. */
-static svn_error_t *
-rs_aligned_seek(rep_state_t *rs,
-                apr_off_t *buffer_start,
-                apr_off_t offset,
-                apr_pool_t *scratch_pool)
-{
-  svn_fs_x__data_t *ffd = rs->sfile->fs->fsap_data;
-  return svn_error_trace(svn_io_file_aligned_seek(rs->sfile->rfile->file,
-                                                  ffd->block_size,
-                                                  buffer_start, offset,
-                                                  scratch_pool));
-}
-
 /* Open FILE->FILE and FILE->STREAM if they haven't been opened, yet. */
 static svn_error_t*
 auto_open_shared_file(shared_file_t *file)
 {
   if (file->rfile == NULL)
-    SVN_ERR(svn_fs_x__open_pack_or_rev_file(&file->rfile, file->fs,
-                                            file->revision, file->pool,
-                                            file->pool));
+    SVN_ERR(svn_fs_x__rev_file_init(&file->rfile, file->fs,
+                                    file->revision, file->pool));
 
   return SVN_NO_ERROR;
 }
@@ -571,9 +526,8 @@ auto_read_diff_version(rep_state_t *rs,
   if (rs->ver == -1)
     {
       char buf[4];
-      SVN_ERR(rs_aligned_seek(rs, NULL, rs->start, scratch_pool));
-      SVN_ERR(svn_io_file_read_full2(rs->sfile->rfile->file, buf,
-                                     sizeof(buf), NULL, NULL, scratch_pool));
+      SVN_ERR(svn_fs_x__rev_file_seek(rs->sfile->rfile, NULL, rs->start));
+      SVN_ERR(svn_fs_x__rev_file_read(rs->sfile->rfile, buf, sizeof(buf)));
 
       /* ### Layering violation */
       if (! ((buf[0] == 'S') && (buf[1] == 'V') && (buf[2] == 'N')))
@@ -655,7 +609,7 @@ create_rep_state_body(rep_state_t **rep_
                      : NULL;
 
   /* cache lookup, i.e. skip reading the rep header if possible */
-  if (ffd->rep_header_cache && SVN_IS_VALID_REVNUM(revision))
+  if (SVN_IS_VALID_REVNUM(revision))
     SVN_ERR(svn_cache__get((void **) &rh, &is_cached,
                            ffd->rep_header_cache, &key, result_pool));
 
@@ -680,6 +634,8 @@ create_rep_state_body(rep_state_t **rep_
   /* read rep header, if necessary */
   if (!is_cached)
     {
+      svn_stream_t *stream;
+
       /* we will need the on-disk location for non-txn reps */
       apr_off_t offset;
       svn_boolean_t in_container = TRUE;
@@ -731,21 +687,21 @@ create_rep_state_body(rep_state_t **rep_
               return SVN_NO_ERROR;
             }
 
-          SVN_ERR(rs_aligned_seek(rs, NULL, offset, scratch_pool));
+          SVN_ERR(svn_fs_x__rev_file_seek(rs->sfile->rfile, NULL, offset));
         }
 
-      SVN_ERR(svn_fs_x__read_rep_header(&rh, rs->sfile->rfile->stream,
+      SVN_ERR(svn_fs_x__rev_file_stream(&stream, rs->sfile->rfile));
+      SVN_ERR(svn_fs_x__read_rep_header(&rh, stream,
                                         result_pool, scratch_pool));
-      SVN_ERR(get_file_offset(&rs->start, rs, result_pool));
+      SVN_ERR(svn_fs_x__rev_file_offset(&rs->start, rs->sfile->rfile));
 
       /* populate the cache if appropriate */
       if (SVN_IS_VALID_REVNUM(revision))
         {
           SVN_ERR(block_read(NULL, fs, &rs->rep_id, rs->sfile->rfile,
                              result_pool, scratch_pool));
-          if (ffd->rep_header_cache)
-            SVN_ERR(svn_cache__set(ffd->rep_header_cache, &key, rh,
-                                   scratch_pool));
+          SVN_ERR(svn_cache__set(ffd->rep_header_cache, &key, rh,
+                                 scratch_pool));
         }
     }
 
@@ -820,8 +776,7 @@ svn_fs_x__check_rep(svn_fs_x__representa
   svn_revnum_t revision = svn_fs_x__get_revnum(rep->id.change_set);
 
   svn_fs_x__revision_file_t *rev_file;
-  SVN_ERR(svn_fs_x__open_pack_or_rev_file(&rev_file, fs, revision,
-                                          scratch_pool, scratch_pool));
+  SVN_ERR(svn_fs_x__rev_file_init(&rev_file, fs, revision, scratch_pool));
 
   /* Does REP->ID refer to an actual item? Which one is it? */
   SVN_ERR(svn_fs_x__item_offset(&offset, &sub_item, fs, rev_file, &rep->id,
@@ -838,7 +793,7 @@ svn_fs_x__check_rep(svn_fs_x__representa
           && entry->type != SVN_FS_X__ITEM_TYPE_FILE_PROPS
           && entry->type != SVN_FS_X__ITEM_TYPE_DIR_PROPS
           && entry->type != SVN_FS_X__ITEM_TYPE_REPS_CONT))
-    return svn_error_createf(SVN_ERR_REPOS_CORRUPTED, NULL,
+    return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
                              _("No representation found at offset %s "
                                "for item %s in revision %ld"),
                              apr_off_t_toa(scratch_pool, offset),
@@ -1075,22 +1030,14 @@ get_cached_window_sizes(window_sizes_t *
                         svn_boolean_t *is_cached,
                         apr_pool_t *pool)
 {
-  if (! rs->window_cache)
-    {
-      /* txdelta window has not been enabled */
-      *is_cached = FALSE;
-    }
-  else
-    {
-      svn_fs_x__window_cache_key_t key = { 0 };
-      SVN_ERR(svn_cache__get_partial((void **)sizes,
-                                     is_cached,
-                                     rs->window_cache,
-                                     get_window_key(&key, rs),
-                                     get_cached_window_sizes_func,
-                                     NULL,
-                                     pool));
-    }
+  svn_fs_x__window_cache_key_t key = { 0 };
+  SVN_ERR(svn_cache__get_partial((void **)sizes,
+                                 is_cached,
+                                 rs->window_cache,
+                                 get_window_key(&key, rs),
+                                 get_cached_window_sizes_func,
+                                 NULL,
+                                 pool));
 
   return SVN_NO_ERROR;
 }
@@ -1103,33 +1050,25 @@ get_cached_window(svn_txdelta_window_t *
                   apr_pool_t *result_pool,
                   apr_pool_t *scratch_pool)
 {
-  if (! rs->window_cache)
-    {
-      /* txdelta window has not been enabled */
-      *is_cached = FALSE;
-    }
-  else
-    {
-      /* ask the cache for the desired txdelta window */
-      svn_fs_x__txdelta_cached_window_t *cached_window;
-      svn_fs_x__window_cache_key_t key = { 0 };
-      get_window_key(&key, rs);
-      key.chunk_index = chunk_index;
-      SVN_ERR(svn_cache__get((void **) &cached_window,
-                             is_cached,
-                             rs->window_cache,
-                             &key,
-                             result_pool));
-
-      if (*is_cached)
-        {
-          /* found it. Pass it back to the caller. */
-          *window_p = cached_window->window;
-
-          /* manipulate the RS as if we just read the data */
-          rs->current = cached_window->end_offset;
-          rs->chunk_index = chunk_index;
-        }
+  /* ask the cache for the desired txdelta window */
+  svn_fs_x__txdelta_cached_window_t *cached_window;
+  svn_fs_x__window_cache_key_t key = { 0 };
+  get_window_key(&key, rs);
+  key.chunk_index = chunk_index;
+  SVN_ERR(svn_cache__get((void **) &cached_window,
+                         is_cached,
+                         rs->window_cache,
+                         &key,
+                         result_pool));
+
+  if (*is_cached)
+    {
+      /* found it. Pass it back to the caller. */
+      *window_p = cached_window->window;
+
+      /* manipulate the RS as if we just read the data */
+      rs->current = cached_window->end_offset;
+      rs->chunk_index = chunk_index;
     }
 
   return SVN_NO_ERROR;
@@ -1145,23 +1084,20 @@ set_cached_window(svn_txdelta_window_t *
                   apr_off_t start_offset,
                   apr_pool_t *scratch_pool)
 {
-  if (rs->window_cache)
-    {
-      /* store the window and the first offset _past_ it */
-      svn_fs_x__txdelta_cached_window_t cached_window;
-      svn_fs_x__window_cache_key_t key = {0};
-
-      cached_window.window = window;
-      cached_window.start_offset = start_offset - rs->start;
-      cached_window.end_offset = rs->current;
-
-      /* but key it with the start offset because that is the known state
-       * when we will look it up */
-      SVN_ERR(svn_cache__set(rs->window_cache,
-                             get_window_key(&key, rs),
-                             &cached_window,
-                             scratch_pool));
-    }
+  /* store the window and the first offset _past_ it */
+  svn_fs_x__txdelta_cached_window_t cached_window;
+  svn_fs_x__window_cache_key_t key = {0};
+
+  cached_window.window = window;
+  cached_window.start_offset = start_offset - rs->start;
+  cached_window.end_offset = rs->current;
+
+  /* but key it with the start offset because that is the known state
+   * when we will look it up */
+  SVN_ERR(svn_cache__set(rs->window_cache,
+                         get_window_key(&key, rs),
+                         &cached_window,
+                         scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -1178,23 +1114,13 @@ get_cached_combined_window(svn_stringbuf
                            svn_boolean_t *is_cached,
                            apr_pool_t *pool)
 {
-  if (! rs->combined_cache)
-    {
-      /* txdelta window has not been enabled */
-      *is_cached = FALSE;
-    }
-  else
-    {
-      /* ask the cache for the desired txdelta window */
-      svn_fs_x__window_cache_key_t key = { 0 };
-      return svn_cache__get((void **)window_p,
-                            is_cached,
-                            rs->combined_cache,
-                            get_window_key(&key, rs),
-                            pool);
-    }
-
-  return SVN_NO_ERROR;
+  /* ask the cache for the desired txdelta window */
+  svn_fs_x__window_cache_key_t key = { 0 };
+  return svn_cache__get((void **)window_p,
+                        is_cached,
+                        rs->combined_cache,
+                        get_window_key(&key, rs),
+                        pool);
 }
 
 /* Store the WINDOW read for the rep state RS in the current FSX session's
@@ -1205,18 +1131,13 @@ set_cached_combined_window(svn_stringbuf
                            rep_state_t *rs,
                            apr_pool_t *scratch_pool)
 {
-  if (rs->combined_cache)
-    {
-      /* but key it with the start offset because that is the known state
-       * when we will look it up */
-      svn_fs_x__window_cache_key_t key = { 0 };
-      return svn_cache__set(rs->combined_cache,
-                            get_window_key(&key, rs),
-                            window,
-                            scratch_pool);
-    }
-
-  return SVN_NO_ERROR;
+  /* but key it with the start offset because that is the known state
+   * when we will look it up */
+  svn_fs_x__window_cache_key_t key = { 0 };
+  return svn_cache__set(rs->combined_cache,
+                        get_window_key(&key, rs),
+                        window,
+                        scratch_pool);
 }
 
 /* Build an array of rep_state structures in *LIST giving the delta
@@ -1364,6 +1285,8 @@ read_delta_window(svn_txdelta_window_t *
   apr_off_t start_offset;
   apr_off_t end_offset;
   apr_pool_t *iterpool;
+  svn_stream_t *stream;
+  svn_fs_x__revision_file_t *file;
 
   SVN_ERR_ASSERT(rs->chunk_index <= this_chunk);
 
@@ -1378,6 +1301,7 @@ read_delta_window(svn_txdelta_window_t *
 
   /* someone has to actually read the data from file.  Open it */
   SVN_ERR(auto_open_shared_file(rs->sfile));
+  file = rs->sfile->rfile;
 
   /* invoke the 'block-read' feature for non-txn data.
      However, don't do that if we are in the middle of some representation,
@@ -1386,8 +1310,8 @@ read_delta_window(svn_txdelta_window_t *
       && svn_fs_x__is_revision(rs->rep_id.change_set)
       && rs->window_cache)
     {
-      SVN_ERR(block_read(NULL, rs->sfile->fs, &rs->rep_id,
-                         rs->sfile->rfile, result_pool, scratch_pool));
+      SVN_ERR(block_read(NULL, rs->sfile->fs, &rs->rep_id, file,
+                         result_pool, scratch_pool));
 
       /* reading the whole block probably also provided us with the
          desired txdelta window */
@@ -1405,18 +1329,19 @@ read_delta_window(svn_txdelta_window_t *
   /* RS->FILE may be shared between RS instances -> make sure we point
    * to the right data. */
   start_offset = rs->start + rs->current;
-  SVN_ERR(rs_aligned_seek(rs, NULL, start_offset, scratch_pool));
+  SVN_ERR(svn_fs_x__rev_file_seek(file, NULL, start_offset));
 
   /* Skip windows to reach the current chunk if we aren't there yet. */
   iterpool = svn_pool_create(scratch_pool);
   while (rs->chunk_index < this_chunk)
     {
-      apr_file_t *file = rs->sfile->rfile->file;
+      apr_file_t *apr_file;
       svn_pool_clear(iterpool);
 
-      SVN_ERR(svn_txdelta_skip_svndiff_window(file, rs->ver, iterpool));
+      SVN_ERR(svn_fs_x__rev_file_get(&apr_file, file));
+      SVN_ERR(svn_txdelta_skip_svndiff_window(apr_file, rs->ver, iterpool));
       rs->chunk_index++;
-      SVN_ERR(svn_fs_x__get_file_offset(&start_offset, file, iterpool));
+      SVN_ERR(svn_fs_x__get_file_offset(&start_offset, apr_file, iterpool));
 
       rs->current = start_offset - rs->start;
       if (rs->current >= rs->size)
@@ -1428,9 +1353,10 @@ read_delta_window(svn_txdelta_window_t *
   svn_pool_destroy(iterpool);
 
   /* Actually read the next window. */
-  SVN_ERR(svn_txdelta_read_svndiff_window(nwin, rs->sfile->rfile->stream,
-                                          rs->ver, result_pool));
-  SVN_ERR(get_file_offset(&end_offset, rs, scratch_pool));
+  SVN_ERR(svn_fs_x__rev_file_stream(&stream, file));
+  SVN_ERR(svn_txdelta_read_svndiff_window(nwin, stream, rs->ver,
+                                          result_pool));
+  SVN_ERR(svn_fs_x__rev_file_offset(&end_offset, file));
   rs->current = end_offset - rs->start;
   if (rs->current > rs->size)
     return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
@@ -1458,24 +1384,21 @@ read_container_window(svn_stringbuf_t **
   svn_fs_x__data_t *ffd = fs->fsap_data;
   svn_fs_x__pair_cache_key_t key;
   svn_revnum_t revision = svn_fs_x__get_revnum(rs->rep_id.change_set);
+  svn_boolean_t is_cached = FALSE;
+  svn_fs_x__reps_baton_t baton;
 
   SVN_ERR(auto_set_start_offset(rs, scratch_pool));
   key.revision = svn_fs_x__packed_base_rev(fs, revision);
   key.second = rs->start;
 
   /* already in cache? */
-  if (ffd->reps_container_cache)
-    {
-      svn_boolean_t is_cached = FALSE;
-      svn_fs_x__reps_baton_t baton;
-      baton.fs = fs;
-      baton.idx = rs->sub_item;
-
-      SVN_ERR(svn_cache__get_partial((void**)&extractor, &is_cached,
-                                     ffd->reps_container_cache, &key,
-                                     svn_fs_x__reps_get_func, &baton,
-                                     result_pool));
-    }
+  baton.fs = fs;
+  baton.idx = rs->sub_item;
+
+  SVN_ERR(svn_cache__get_partial((void**)&extractor, &is_cached,
+                                 ffd->reps_container_cache, &key,
+                                 svn_fs_x__reps_get_func, &baton,
+                                 result_pool));
 
   /* read from disk, if necessary */
   if (extractor == NULL)
@@ -1587,7 +1510,7 @@ get_combined_window(svn_stringbuf_t **re
 }
 
 /* Returns whether or not the expanded fulltext of the file is cachable
- * based on its size SIZE.  The decision depends on the cache used by RB.
+ * based on its size SIZE.  The decision depends on the cache used by FFD.
  */
 static svn_boolean_t
 fulltext_size_is_cachable(svn_fs_x__data_t *ffd,
@@ -1690,23 +1613,23 @@ cache_windows(svn_filesize_t *fulltext_l
       else
         {
           svn_txdelta_window_t *window;
+          svn_fs_x__revision_file_t *file = rs->sfile->rfile;
+          svn_stream_t *stream;
           apr_off_t start_offset = rs->start + rs->current;
           apr_off_t end_offset;
           apr_off_t block_start;
 
           /* navigate to & read the current window */
-          SVN_ERR(rs_aligned_seek(rs, &block_start, start_offset, iterpool));
-          SVN_ERR(svn_txdelta_read_svndiff_window(&window,
-                                                  rs->sfile->rfile->stream,
-                                                  rs->ver, iterpool));
+          SVN_ERR(svn_fs_x__rev_file_stream(&stream, file));
+          SVN_ERR(svn_fs_x__rev_file_seek(file, &block_start, start_offset));
+          SVN_ERR(svn_txdelta_read_svndiff_window(&window, stream, rs->ver,
+                                                  iterpool));
 
           /* aggregate expanded window size */
           *fulltext_len += window->tview_len;
 
           /* determine on-disk window size */
-          SVN_ERR(svn_fs_x__get_file_offset(&end_offset,
-                                            rs->sfile->rfile->file,
-                                            iterpool));
+          SVN_ERR(svn_fs_x__rev_file_offset(&end_offset, rs->sfile->rfile));
           rs->current = end_offset - rs->start;
           if (rs->current > rs->size)
             return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
@@ -1735,25 +1658,22 @@ cache_windows(svn_filesize_t *fulltext_l
 static svn_error_t *
 read_rep_header(svn_fs_x__rep_header_t **rep_header,
                 svn_fs_t *fs,
-                svn_stream_t *stream,
+                svn_fs_x__revision_file_t *file,
                 svn_fs_x__representation_cache_key_t *key,
                 apr_pool_t *pool)
 {
   svn_fs_x__data_t *ffd = fs->fsap_data;
+  svn_stream_t *stream;
   svn_boolean_t is_cached = FALSE;
 
-  if (ffd->rep_header_cache)
-    {
-      SVN_ERR(svn_cache__get((void**)rep_header, &is_cached,
-                             ffd->rep_header_cache, key, pool));
-      if (is_cached)
-        return SVN_NO_ERROR;
-    }
+  SVN_ERR(svn_cache__get((void**)rep_header, &is_cached,
+                         ffd->rep_header_cache, key, pool));
+  if (is_cached)
+    return SVN_NO_ERROR;
 
+  SVN_ERR(svn_fs_x__rev_file_stream(&stream, file));
   SVN_ERR(svn_fs_x__read_rep_header(rep_header, stream, pool, pool));
-
-  if (ffd->rep_header_cache)
-    SVN_ERR(svn_cache__set(ffd->rep_header_cache, key, *rep_header, pool));
+  SVN_ERR(svn_cache__set(ffd->rep_header_cache, key, *rep_header, pool));
 
   return SVN_NO_ERROR;
 }
@@ -1779,8 +1699,7 @@ svn_fs_x__get_representation_length(svn_
   key.revision = svn_fs_x__get_revnum(entry->items[0].change_set);
   key.is_packed = svn_fs_x__is_packed_rev(fs, key.revision);
   key.item_index = entry->items[0].number;
-  SVN_ERR(read_rep_header(&rep_header, fs, rev_file->stream, &key,
-                          scratch_pool));
+  SVN_ERR(read_rep_header(&rep_header, fs, rev_file, &key, scratch_pool));
 
   /* prepare representation reader state (rs) structure */
   SVN_ERR(init_rep_state(&rs, rep_header, fs, rev_file, entry,
@@ -2186,7 +2105,7 @@ svn_fs_x__get_contents(svn_stream_t **co
       /* Make the stream attempt fulltext cache lookups if the fulltext
        * is cacheable.  If it is not, then also don't try to buffer and
        * cache it. */
-      if (ffd->fulltext_cache && cache_fulltext
+      if (   cache_fulltext
           && SVN_IS_VALID_REVNUM(revision)
           && fulltext_size_is_cachable(ffd, len))
         {
@@ -2257,8 +2176,7 @@ svn_fs_x__try_process_file_contents(svn_
 
       fulltext_cache_key.revision = svn_fs_x__get_revnum(rep->id.change_set);
       fulltext_cache_key.second = rep->id.number;
-      if (ffd->fulltext_cache
-          && SVN_IS_VALID_REVNUM(fulltext_cache_key.revision)
+      if (   SVN_IS_VALID_REVNUM(fulltext_cache_key.revision)
           && fulltext_size_is_cachable(ffd, rep->expanded_size))
         {
           cache_access_wrapper_baton_t wrapper_baton;
@@ -2344,12 +2262,11 @@ svn_fs_x__get_file_delta_stream(svn_txde
   svn_stream_t *source_stream, *target_stream;
   rep_state_t *rep_state;
   svn_fs_x__rep_header_t *rep_header;
-  svn_fs_x__data_t *ffd = fs->fsap_data;
 
   /* Try a shortcut: if the target is stored as a delta against the source,
      then just use that delta.  However, prefer using the fulltext cache
      whenever that is available. */
-  if (target->data_rep && (source || !ffd->fulltext_cache))
+  if (target->data_rep && source)
     {
       /* Read target's base rep if any. */
       SVN_ERR(create_rep_state(&rep_state, &rep_header, NULL,
@@ -2449,117 +2366,147 @@ compare_dirent_name(const void *a,
   return strcmp(lhs->name, rhs);
 }
 
-/* Into ENTRIES, read all directories entries from the key-value text in
- * STREAM.  If INCREMENTAL is TRUE, read until the end of the STREAM and
+/* Into ENTRIES, parse all directories entries from the serialized form in
+ * DATA.  If INCREMENTAL is TRUE, read until the end of the STREAM and
  * update the data.  ID is provided for nicer error messages.
+ *
+ * The contents of DATA will be shared with the items in ENTRIES, i.e. it
+ * must not be modified afterwards and must remain valid as long as ENTRIES
+ * is valid.  Use SCRATCH_POOL for temporary allocations.
  */
 static svn_error_t *
-read_dir_entries(apr_array_header_t *entries,
-                 svn_stream_t *stream,
-                 svn_boolean_t incremental,
-                 const svn_fs_x__id_t *id,
-                 apr_pool_t *result_pool,
-                 apr_pool_t *scratch_pool)
+parse_dir_entries(apr_array_header_t **entries_p,
+                  const svn_stringbuf_t *data,
+                  svn_boolean_t incremental,
+                  const svn_fs_x__id_t *id,
+                  apr_pool_t *result_pool,
+                  apr_pool_t *scratch_pool)
 {
-  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+  const apr_byte_t *p = (const apr_byte_t *)data->data;
+  const apr_byte_t *end = p + data->len;
+  apr_uint64_t count;
   apr_hash_t *hash = incremental ? svn_hash__make(scratch_pool) : NULL;
-  const char *terminator = SVN_HASH_TERMINATOR;
-
-  /* Read until the terminator (non-incremental) or the end of STREAM
-     (incremental mode).  In the latter mode, we use a temporary HASH
-     to make updating and removing entries cheaper. */
-  while (1)
-    {
-      svn_hash__entry_t entry;
-      svn_fs_x__dirent_t *dirent;
-      char *str;
-
-      svn_pool_clear(iterpool);
-      SVN_ERR(svn_hash__read_entry(&entry, stream, terminator,
-                                   incremental, iterpool));
+  apr_array_header_t *entries;
 
-      /* End of directory? */
-      if (entry.key == NULL)
-        {
-          /* In incremental mode, we skip the terminator and read the
-             increments following it until the end of the stream. */
-          if (incremental && terminator)
-            terminator = NULL;
-          else
-            break;
-        }
+  /* Construct the resulting container. */
+  p = svn__decode_uint(&count, p, end);
+  if (count > INT_MAX)
+    return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
+                             _("Directory for '%s' is too large"),
+                             svn_fs_x__id_unparse(id, scratch_pool)->data);
 
-      /* Deleted entry? */
-      if (entry.val == NULL)
-        {
-          /* We must be in incremental mode */
-          assert(hash);
-          apr_hash_set(hash, entry.key, entry.keylen, NULL);
-          continue;
-        }
+  entries = apr_array_make(result_pool, (int)count,
+                           sizeof(svn_fs_x__dirent_t *));
 
-      /* Add a new directory entry. */
+  while (p != end)
+    {
+      apr_size_t len;
+      svn_fs_x__dirent_t *dirent;
       dirent = apr_pcalloc(result_pool, sizeof(*dirent));
-      dirent->name = apr_pstrmemdup(result_pool, entry.key, entry.keylen);
 
-      str = svn_cstring_tokenize(" ", &entry.val);
-      if (str == NULL)
+      /* The part of the serialized entry that is not the name will be
+       * about 6 bytes or less.  Since APR allocates with an 8 byte
+       * alignment (4 bytes loss on average per string), simply using
+       * the name string in DATA already gives us near-optimal memory
+       * usage. */
+      dirent->name = (const char *)p;
+      len = strlen(dirent->name);
+      p += len + 1;
+      if (p == end)
         return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
-                      _("Directory entry corrupt in '%s'"),
-                      svn_fs_x__id_unparse(id, scratch_pool)->data);
+                            _("Directory entry missing kind in '%s'"),
+                            svn_fs_x__id_unparse(id, scratch_pool)->data);
 
-      if (strcmp(str, SVN_FS_X__KIND_FILE) == 0)
-        {
-          dirent->kind = svn_node_file;
-        }
-      else if (strcmp(str, SVN_FS_X__KIND_DIR) == 0)
-        {
-          dirent->kind = svn_node_dir;
-        }
-      else
-        {
-          return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
-                      _("Directory entry corrupt in '%s'"),
-                      svn_fs_x__id_unparse(id, scratch_pool)->data);
-        }
+      dirent->kind = (svn_node_kind_t)*(p++);
+      if (p == end)
+        return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
+                            _("Directory entry missing change set in '%s'"),
+                            svn_fs_x__id_unparse(id, scratch_pool)->data);
 
-      str = svn_cstring_tokenize(" ", &entry.val);
-      if (str == NULL)
+      p = svn__decode_int(&dirent->id.change_set, p, end);
+      if (p == end)
         return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
-                      _("Directory entry corrupt in '%s'"),
-                      svn_fs_x__id_unparse(id, scratch_pool)->data);
+                            _("Directory entry missing item number in '%s'"),
+                            svn_fs_x__id_unparse(id, scratch_pool)->data);
 
-      SVN_ERR(svn_fs_x__id_parse(&dirent->id, str));
+      p = svn__decode_uint(&dirent->id.number, p, end);
 
       /* In incremental mode, update the hash; otherwise, write to the
        * final array. */
       if (incremental)
-        apr_hash_set(hash, entry.key, entry.keylen, dirent);
+        {
+          /* Insertion / update or a deletion? */
+          if (svn_fs_x__id_used(&dirent->id))
+            apr_hash_set(hash, dirent->name, len, dirent);
+          else
+            apr_hash_set(hash, dirent->name, len, NULL);
+        }
       else
-        APR_ARRAY_PUSH(entries, svn_fs_x__dirent_t *) = dirent;
+        {
+          APR_ARRAY_PUSH(entries, svn_fs_x__dirent_t *) = dirent;
+        }
     }
 
-  /* Convert container to a sorted array. */
   if (incremental)
     {
+      /* Convert container into a sorted array. */
       apr_hash_index_t *hi;
-      for (hi = apr_hash_first(iterpool, hash); hi; hi = apr_hash_next(hi))
+      for (hi = apr_hash_first(scratch_pool, hash); hi; hi = apr_hash_next(hi))
         APR_ARRAY_PUSH(entries, svn_fs_x__dirent_t *) = apr_hash_this_val(hi);
+
+      if (!sorted(entries))
+        svn_sort__array(entries, compare_dirents);
+    }
+  else
+    {
+      /* Check that we read the expected amount of entries. */
+      if ((apr_uint64_t)entries->nelts != count)
+        return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
+                            _("Directory length mismatch in '%s'"),
+                            svn_fs_x__id_unparse(id, scratch_pool)->data);
     }
 
-  if (!sorted(entries))
-    svn_sort__array(entries, compare_dirents);
+ *entries_p = entries;
 
-  svn_pool_destroy(iterpool);
+  return SVN_NO_ERROR;
+}
+
+/* For directory NODEREV in FS, return the *FILESIZE of its in-txn
+ * representation.  If the directory representation is comitted data,
+ * set *FILESIZE to SVN_INVALID_FILESIZE. Use SCRATCH_POOL for temporaries.
+ */
+static svn_error_t *
+get_txn_dir_info(svn_filesize_t *filesize,
+                 svn_fs_t *fs,
+                 svn_fs_x__noderev_t *noderev,
+                 apr_pool_t *scratch_pool)
+{
+  if (noderev->data_rep
+      && ! svn_fs_x__is_revision(noderev->data_rep->id.change_set))
+    {
+      const svn_io_dirent2_t *dirent;
+      const char *filename;
+
+      filename = svn_fs_x__path_txn_node_children(fs, &noderev->noderev_id,
+                                                  scratch_pool, scratch_pool);
+
+      SVN_ERR(svn_io_stat_dirent2(&dirent, filename, FALSE, FALSE,
+                                  scratch_pool, scratch_pool));
+      *filesize = dirent->filesize;
+    }
+  else
+    {
+      *filesize = SVN_INVALID_FILESIZE;
+    }
 
   return SVN_NO_ERROR;
 }
 
-/* Fetch the contents of a directory into ENTRIES.  Values are stored
+/* Fetch the contents of a directory into DIR.  Values are stored
    as filename to string mappings; further conversion is necessary to
    convert them into svn_fs_x__dirent_t values. */
 static svn_error_t *
-get_dir_contents(apr_array_header_t **entries,
+get_dir_contents(svn_fs_x__dir_data_t *dir,
                  svn_fs_t *fs,
                  svn_fs_x__noderev_t *noderev,
                  apr_pool_t *result_pool,
@@ -2567,44 +2514,67 @@ get_dir_contents(apr_array_header_t **en
 {
   svn_stream_t *contents;
   const svn_fs_x__id_t *id = &noderev->noderev_id;
+  apr_size_t len;
+  svn_stringbuf_t *text;
+  svn_boolean_t incremental;
 
-  *entries = apr_array_make(result_pool, 16, sizeof(svn_fs_x__dirent_t *));
+  /* Initialize the result. */
+  dir->txn_filesize = SVN_INVALID_FILESIZE;
+
+  /* Read dir contents - unless there is none in which case we are done. */
   if (noderev->data_rep
       && ! svn_fs_x__is_revision(noderev->data_rep->id.change_set))
     {
-      const char *filename
-        = svn_fs_x__path_txn_node_children(fs, id, scratch_pool,
-                                           scratch_pool);
+      /* Get location & current size of the directory representation. */
+      const char *filename;
+      apr_file_t *file;
+
+      filename = svn_fs_x__path_txn_node_children(fs, id, scratch_pool,
+                                                  scratch_pool);
 
       /* The representation is mutable.  Read the old directory
          contents from the mutable children file, followed by the
          changes we've made in this transaction. */
-      SVN_ERR(svn_stream_open_readonly(&contents, filename, scratch_pool,
-                                       scratch_pool));
-      SVN_ERR(read_dir_entries(*entries, contents, TRUE,  id,
-                               result_pool, scratch_pool));
-      SVN_ERR(svn_stream_close(contents));
+      SVN_ERR(svn_io_file_open(&file, filename, APR_READ | APR_BUFFERED,
+                               APR_OS_DEFAULT, scratch_pool));
+
+      /* Obtain txn children file size. */
+      SVN_ERR(svn_io_file_size_get(&dir->txn_filesize, file, scratch_pool));
+      len = (apr_size_t)dir->txn_filesize;
+
+      /* Finally, provide stream access to FILE. */
+      contents = svn_stream_from_aprfile2(file, FALSE, scratch_pool);
+      incremental = TRUE;
     }
   else if (noderev->data_rep)
     {
-      /* Undeltify content before parsing it. Otherwise, we could only
-       * parse it byte-by-byte.
-       */
-      apr_size_t len = noderev->data_rep->expanded_size;
-      svn_stringbuf_t *text;
-
       /* The representation is immutable.  Read it normally. */
+      len = noderev->data_rep->expanded_size;
       SVN_ERR(svn_fs_x__get_contents(&contents, fs, noderev->data_rep,
                                      FALSE, scratch_pool));
-      SVN_ERR(svn_stringbuf_from_stream(&text, contents, len, scratch_pool));
-      SVN_ERR(svn_stream_close(contents));
-
-      /* de-serialize hash */
-      contents = svn_stream_from_stringbuf(text, scratch_pool);
-      SVN_ERR(read_dir_entries(*entries, contents, FALSE,  id,
-                               result_pool, scratch_pool));
+      incremental = FALSE;
+    }
+  else
+    {
+      /* Empty representation == empty directory. */
+      dir->entries = apr_array_make(result_pool, 0,
+                                    sizeof(svn_fs_x__dirent_t *));
+      return SVN_NO_ERROR;
     }
 
+  /* Read the whole stream contents into a single buffer.
+   * Due to our LEN hint, no allocation overhead occurs.
+   *
+   * Also, a large portion of TEXT will be file / dir names which we
+   * directly reference from DIR->ENTRIES instead of copying them.
+   * Hence, we need to use the RESULT_POOL here. */
+  SVN_ERR(svn_stringbuf_from_stream(&text, contents, len, result_pool));
+  SVN_ERR(svn_stream_close(contents));
+
+  /* de-serialize hash */
+  SVN_ERR(parse_dir_entries(&dir->entries, text, incremental, id,
+                            result_pool, scratch_pool));
+
   return SVN_NO_ERROR;
 }
 
@@ -2618,26 +2588,24 @@ locate_dir_cache(svn_fs_t *fs,
                  svn_fs_x__noderev_t *noderev)
 {
   svn_fs_x__data_t *ffd = fs->fsap_data;
-  if (svn_fs_x__is_txn(noderev->noderev_id.change_set))
+
+  if (!noderev->data_rep)
     {
-      /* data in txns must be addressed by ID since the representation has
-         not been created, yet. */
+      /* no data rep -> empty directory.
+         Use a key that does definitely not clash with non-NULL reps. */
+      key->change_set = SVN_FS_X__INVALID_CHANGE_SET;
+      key->number = SVN_FS_X__ITEM_INDEX_UNUSED;
+    }
+  else if (svn_fs_x__is_txn(noderev->noderev_id.change_set))
+    {
+      /* data in txns must be addressed by noderev ID since the
+         representation has not been created, yet. */
       *key = noderev->noderev_id;
     }
   else
     {
       /* committed data can use simple rev,item pairs */
-      if (noderev->data_rep)
-        {
-          *key = noderev->data_rep->id;
-        }
-      else
-        {
-          /* no data rep -> empty directory.
-             Use a key that does definitely not clash with non-NULL reps. */
-          key->change_set = SVN_FS_X__INVALID_CHANGE_SET;
-          key->number = SVN_FS_X__ITEM_INDEX_UNUSED;
-        }
+      *key = noderev->data_rep->id;
     }
 
   return ffd->dir_cache;
@@ -2651,26 +2619,35 @@ svn_fs_x__rep_contents_dir(apr_array_hea
                            apr_pool_t *scratch_pool)
 {
   svn_fs_x__id_t key;
+  svn_fs_x__dir_data_t *dir;
 
   /* find the cache we may use */
   svn_cache__t *cache = locate_dir_cache(fs, &key, noderev);
-  if (cache)
+  svn_boolean_t found;
+
+  SVN_ERR(svn_cache__get((void **)&dir, &found, cache, &key, result_pool));
+  if (found)
     {
-      svn_boolean_t found;
+      /* Verify that the cached dir info is not stale
+       * (no-op for committed data). */
+      svn_filesize_t filesize;
+      SVN_ERR(get_txn_dir_info(&filesize, fs, noderev, scratch_pool));
 
-      SVN_ERR(svn_cache__get((void **)entries_p, &found, cache, &key,
-                             result_pool));
-      if (found)
-        return SVN_NO_ERROR;
+      if (filesize == dir->txn_filesize)
+        {
+          /* Still valid. Done. */
+          *entries_p = dir->entries;
+          return SVN_NO_ERROR;
+        }
     }
 
   /* Read in the directory contents. */
-  SVN_ERR(get_dir_contents(entries_p, fs, noderev, result_pool,
-                           scratch_pool));
+  dir = apr_pcalloc(scratch_pool, sizeof(*dir));
+  SVN_ERR(get_dir_contents(dir, fs, noderev, result_pool, scratch_pool));
+  *entries_p = dir->entries;
 
   /* Update the cache, if we are to use one. */
-  if (cache)
-    SVN_ERR(svn_cache__set(cache, &key, *entries_p, scratch_pool));
+  SVN_ERR(svn_cache__set(cache, &key, dir, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -2699,40 +2676,45 @@ svn_fs_x__rep_contents_dir_entry(svn_fs_
   /* find the cache we may use */
   svn_fs_x__id_t key;
   svn_cache__t *cache = locate_dir_cache(fs, &key, noderev);
-  if (cache)
-    {
-      svn_fs_x__ede_baton_t baton;
-      baton.hint = *hint;
-      baton.name = name;
-
-      /* Cache lookup. */
-      SVN_ERR(svn_cache__get_partial((void **)dirent,
-                                     &found,
-                                     cache,
-                                     &key,
-                                     svn_fs_x__extract_dir_entry,
-                                     &baton,
-                                     result_pool));
-
-      /* Remember the new clue only if we found something at that spot. */
-      if (found)
-        *hint = baton.hint;
-    }
+  svn_fs_x__ede_baton_t baton;
+
+  svn_filesize_t filesize;
+  SVN_ERR(get_txn_dir_info(&filesize, fs, noderev, scratch_pool));
+
+   /* Cache lookup. */
+  baton.hint = *hint;
+  baton.name = name;
+  baton.txn_filesize = filesize;
+
+  SVN_ERR(svn_cache__get_partial((void **)dirent,
+                                 &found,
+                                 cache,
+                                 &key,
+                                 svn_fs_x__extract_dir_entry,
+                                 &baton,
+                                 result_pool));
+
+  /* Remember the new clue only if we found something at that spot. */
+  if (found)
+    *hint = baton.hint;
 
   /* fetch data from disk if we did not find it in the cache */
   if (! found)
     {
-      apr_array_header_t *entries;
       svn_fs_x__dirent_t *entry;
       svn_fs_x__dirent_t *entry_copy = NULL;
+      svn_fs_x__dir_data_t dir;
+
+      /* Read in the directory contents. */
+      SVN_ERR(get_dir_contents(&dir, fs, noderev, scratch_pool,
+                               scratch_pool));
 
-      /* read the dir from the file system. It will probably be put it
-         into the cache for faster lookup in future calls. */
-      SVN_ERR(svn_fs_x__rep_contents_dir(&entries, fs, noderev,
-                                         scratch_pool, scratch_pool));
+      /* Update the cache, if we are to use one. */
+      if (cache)
+        SVN_ERR(svn_cache__set(cache, &key, &dir, scratch_pool));
 
       /* find desired entry and return a copy in POOL, if found */
-      entry = svn_fs_x__find_dir_entry(entries, name, NULL);
+      entry = svn_fs_x__find_dir_entry(dir.entries, name, NULL);
       if (entry)
         {
           entry_copy = apr_pmemdup(result_pool, entry, sizeof(*entry_copy));
@@ -2755,6 +2737,7 @@ svn_fs_x__get_proplist(apr_hash_t **prop
   apr_hash_t *proplist;
   svn_stream_t *stream;
   const svn_fs_x__id_t *noderev_id = &noderev->noderev_id;
+  svn_error_t *err;
 
   if (noderev->prop_rep
       && !svn_fs_x__is_revision(noderev->prop_rep->id.change_set))
@@ -2766,8 +2749,19 @@ svn_fs_x__get_proplist(apr_hash_t **prop
 
       SVN_ERR(svn_stream_open_readonly(&stream, filename, scratch_pool,
                                        scratch_pool));
-      SVN_ERR(svn_hash_read2(proplist, stream, SVN_HASH_TERMINATOR,
-                             result_pool));
+      err = svn_hash_read2(proplist, stream, SVN_HASH_TERMINATOR,
+                          result_pool);
+      if (err)
+        {
+          svn_string_t *id_str = svn_fs_x__id_unparse(&noderev->noderev_id,
+                                                      scratch_pool);
+
+          err = svn_error_compose_create(err, svn_stream_close(stream));
+          return svn_error_quick_wrapf(err,
+                   _("malformed property list for node-revision '%s' in '%s'"),
+                   id_str->data, filename);
+        }
+
       SVN_ERR(svn_stream_close(stream));
     }
   else if (noderev->prop_rep)
@@ -2778,7 +2772,7 @@ svn_fs_x__get_proplist(apr_hash_t **prop
 
       key.revision = svn_fs_x__get_revnum(rep->id.change_set);
       key.second = rep->id.number;
-      if (ffd->properties_cache && SVN_IS_VALID_REVNUM(key.revision))
+      if (SVN_IS_VALID_REVNUM(key.revision))
         {
           svn_boolean_t is_cached;
           SVN_ERR(svn_cache__get((void **) proplist_p, &is_cached,
@@ -2790,11 +2784,22 @@ svn_fs_x__get_proplist(apr_hash_t **prop
       proplist = apr_hash_make(result_pool);
       SVN_ERR(svn_fs_x__get_contents(&stream, fs, noderev->prop_rep, FALSE,
                                      scratch_pool));
-      SVN_ERR(svn_hash_read2(proplist, stream, SVN_HASH_TERMINATOR,
-                             result_pool));
+      err = svn_hash_read2(proplist, stream, SVN_HASH_TERMINATOR,
+                           result_pool);
+      if (err)
+        {
+          svn_string_t *id_str = svn_fs_x__id_unparse(&noderev->noderev_id,
+                                                      scratch_pool);
+
+          err = svn_error_compose_create(err, svn_stream_close(stream));
+          return svn_error_quick_wrapf(err,
+                   _("malformed property list for node-revision '%s'"),
+                   id_str->data);
+        }
+
       SVN_ERR(svn_stream_close(stream));
 
-      if (ffd->properties_cache && SVN_IS_VALID_REVNUM(rep->id.change_set))
+      if (SVN_IS_VALID_REVNUM(rep->id.change_set))
         SVN_ERR(svn_cache__set(ffd->properties_cache, &key, proplist,
                                scratch_pool));
     }
@@ -2829,12 +2834,11 @@ svn_fs_x__get_changes(apr_array_header_t
   /* Provide revision file. */
 
   SVN_ERR(svn_fs_x__ensure_revision_exists(rev, fs, scratch_pool));
-  SVN_ERR(svn_fs_x__open_pack_or_rev_file(&revision_file, fs, rev,
-                                          scratch_pool, scratch_pool));
+  SVN_ERR(svn_fs_x__rev_file_init(&revision_file, fs, rev, scratch_pool));
 
   /* try cache lookup first */
 
-  if (ffd->changes_container_cache && svn_fs_x__is_packed_rev(fs, rev))
+  if (svn_fs_x__is_packed_rev(fs, rev))
     {
       apr_off_t offset;
       apr_uint32_t sub_item;
@@ -2850,15 +2854,11 @@ svn_fs_x__get_changes(apr_array_header_t
                                      svn_fs_x__changes_get_list_func,
                                      &sub_item, result_pool));
     }
-  else if (ffd->changes_cache)
+  else
     {
       SVN_ERR(svn_cache__get((void **) changes, &found, ffd->changes_cache,
                              &rev, result_pool));
     }
-  else
-    {
-      found = FALSE;
-    }
 
   if (!found)
     {
@@ -2890,20 +2890,16 @@ block_read_contents(svn_fs_t *fs,
                     apr_off_t max_offset,
                     apr_pool_t *scratch_pool)
 {
-  svn_fs_x__data_t *ffd = fs->fsap_data;
   svn_fs_x__representation_cache_key_t header_key = { 0 };
   rep_state_t rs = { 0 };
   svn_filesize_t fulltext_len;
   svn_fs_x__rep_header_t *rep_header;
 
-  if (!ffd->txdelta_window_cache || !ffd->combined_window_cache)
-    return SVN_NO_ERROR;
-
   header_key.revision = (apr_int32_t)key->revision;
   header_key.is_packed = svn_fs_x__is_packed_rev(fs, header_key.revision);
   header_key.item_index = key->second;
 
-  SVN_ERR(read_rep_header(&rep_header, fs, rev_file->stream, &header_key,
+  SVN_ERR(read_rep_header(&rep_header, fs, rev_file, &header_key,
                           scratch_pool));
   SVN_ERR(init_rep_state(&rs, rep_header, fs, rev_file, entry, scratch_pool));
   SVN_ERR(cache_windows(&fulltext_len, fs, &rs, max_offset, scratch_pool));
@@ -2930,8 +2926,7 @@ read_item(svn_stream_t **stream,
   svn_stringbuf_t *text = svn_stringbuf_create_ensure(entry->size, pool);
   text->len = entry->size;
   text->data[text->len] = 0;
-  SVN_ERR(svn_io_file_read_full2(rev_file->file, text->data, text->len,
-                                 NULL, NULL, pool));
+  SVN_ERR(svn_fs_x__rev_file_read(rev_file, text->data, text->len));
 
   /* Return (construct, calculate) stream and checksum. */
   *stream = svn_stream_from_stringbuf(text, pool);
@@ -2976,14 +2971,13 @@ block_read_changes(apr_array_header_t **
   svn_fs_x__data_t *ffd = fs->fsap_data;
   svn_stream_t *stream;
   svn_revnum_t revision = svn_fs_x__get_revnum(entry->items[0].change_set);
-  if (!must_read && !ffd->changes_cache)
-    return SVN_NO_ERROR;
+  apr_size_t estimated_size;
 
   /* we don't support containers, yet */
   SVN_ERR_ASSERT(entry->item_count == 1);
 
   /* already in cache? */
-  if (!must_read && ffd->changes_cache)
+  if (!must_read)
     {
       svn_boolean_t is_cached = FALSE;
       SVN_ERR(svn_cache__has_key(&is_cached, ffd->changes_cache, &revision,
@@ -2995,24 +2989,20 @@ block_read_changes(apr_array_header_t **
   SVN_ERR(read_item(&stream, fs, rev_file, entry, scratch_pool));
 
   /* read changes from revision file */
-
   SVN_ERR(svn_fs_x__read_changes(changes, stream, result_pool, scratch_pool));
 
   /* cache for future reference */
 
-  if (ffd->changes_cache)
-    {
-      /* Guesstimate for the size of the in-cache representation. */
-      apr_size_t estimated_size = (apr_size_t)250 * (*changes)->nelts;
+  /* Guesstimate for the size of the in-cache representation. */
+  estimated_size = (apr_size_t)250 * (*changes)->nelts;
 
-      /* Don't even serialize data that probably won't fit into the
-        * cache.  This often implies that either CHANGES is very
-        * large, memory is scarce or both.  Having a huge temporary
-        * copy would not be a good thing in either case. */
-      if (svn_cache__is_cachable(ffd->changes_cache, estimated_size))
-        SVN_ERR(svn_cache__set(ffd->changes_cache, &revision, *changes,
-                               scratch_pool));
-    }
+  /* Don't even serialize data that probably won't fit into the
+   * cache.  This often implies that either CHANGES is very
+   * large, memory is scarce or both.  Having a huge temporary
+   * copy would not be a good thing in either case. */
+  if (svn_cache__is_cachable(ffd->changes_cache, estimated_size))
+    SVN_ERR(svn_cache__set(ffd->changes_cache, &revision, *changes,
+                           scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -3037,7 +3027,7 @@ block_read_changes_container(apr_array_h
   key.second = entry->offset;
 
   /* already in cache? */
-  if (!must_read && ffd->changes_container_cache)
+  if (!must_read)
     {
       svn_boolean_t is_cached = FALSE;
       SVN_ERR(svn_cache__has_key(&is_cached, ffd->changes_container_cache,
@@ -3058,10 +3048,8 @@ block_read_changes_container(apr_array_h
   if (must_read)
     SVN_ERR(svn_fs_x__changes_get_list(changes, container, sub_item,
                                        result_pool));
-
-  if (ffd->changes_container_cache)
-    SVN_ERR(svn_cache__set(ffd->changes_container_cache, &key, container,
-                           scratch_pool));
+  SVN_ERR(svn_cache__set(ffd->changes_container_cache, &key, container,
+                         scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -3078,14 +3066,12 @@ block_read_noderev(svn_fs_x__noderev_t *
 {
   svn_fs_x__data_t *ffd = fs->fsap_data;
   svn_stream_t *stream;
-  if (!must_read && !ffd->node_revision_cache)
-    return SVN_NO_ERROR;
 
   /* we don't support containers, yet */
   SVN_ERR_ASSERT(entry->item_count == 1);
 
   /* already in cache? */
-  if (!must_read && ffd->node_revision_cache)
+  if (!must_read)
     {
       svn_boolean_t is_cached = FALSE;
       SVN_ERR(svn_cache__has_key(&is_cached, ffd->node_revision_cache, key,
@@ -3100,9 +3086,8 @@ block_read_noderev(svn_fs_x__noderev_t *
 
   SVN_ERR(svn_fs_x__read_noderev(noderev_p, stream, result_pool,
                                  scratch_pool));
-  if (ffd->node_revision_cache)
-    SVN_ERR(svn_cache__set(ffd->node_revision_cache, key, *noderev_p,
-                           scratch_pool));
+  SVN_ERR(svn_cache__set(ffd->node_revision_cache, key, *noderev_p,
+                         scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -3127,7 +3112,7 @@ block_read_noderevs_container(svn_fs_x__
   key.second = entry->offset;
 
   /* already in cache? */
-  if (!must_read && ffd->noderevs_container_cache)
+  if (!must_read)
     {
       svn_boolean_t is_cached = FALSE;
       SVN_ERR(svn_cache__has_key(&is_cached, ffd->noderevs_container_cache,
@@ -3147,9 +3132,8 @@ block_read_noderevs_container(svn_fs_x__
     SVN_ERR(svn_fs_x__noderevs_get(noderev_p, container, sub_item,
                                    result_pool));
 
-  if (ffd->noderevs_container_cache)
-    SVN_ERR(svn_cache__set(ffd->noderevs_container_cache, &key, container,
-                           scratch_pool));
+  SVN_ERR(svn_cache__set(ffd->noderevs_container_cache, &key, container,
+                         scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -3174,7 +3158,7 @@ block_read_reps_container(svn_fs_x__rep_
   key.second = entry->offset;
 
   /* already in cache? */
-  if (!must_read && ffd->reps_container_cache)
+  if (!must_read)
     {
       svn_boolean_t is_cached = FALSE;
       SVN_ERR(svn_cache__has_key(&is_cached, ffd->reps_container_cache,
@@ -3195,9 +3179,8 @@ block_read_reps_container(svn_fs_x__rep_
     SVN_ERR(svn_fs_x__reps_get(extractor, fs, container, sub_item,
                                result_pool));
 
-  if (ffd->noderevs_container_cache)
-    SVN_ERR(svn_cache__set(ffd->reps_container_cache, &key, container,
-                           scratch_pool));
+  SVN_ERR(svn_cache__set(ffd->reps_container_cache, &key, container,
+                         scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -3232,8 +3215,7 @@ block_read(void **result,
   do
     {
       /* fetch list of items in the block surrounding OFFSET */
-      SVN_ERR(aligned_seek(fs, revision_file->file, &block_start, offset,
-                           iterpool));
+      SVN_ERR(svn_fs_x__rev_file_seek(revision_file, &block_start, offset));
       SVN_ERR(svn_fs_x__p2l_index_lookup(&entries, fs, revision_file,
                                          revision, block_start,
                                          ffd->block_size, scratch_pool,
@@ -3272,8 +3254,8 @@ block_read(void **result,
               key.revision = svn_fs_x__get_revnum(entry->items[0].change_set);
               key.second = entry->items[0].number;
 
-              SVN_ERR(svn_io_file_seek(revision_file->file, SEEK_SET,
-                                       &entry->offset, iterpool));
+              SVN_ERR(svn_fs_x__rev_file_seek(revision_file, NULL,
+                                              entry->offset));
               switch (entry->type)
                 {
                   case SVN_FS_X__ITEM_TYPE_FILE_REP:
@@ -3289,11 +3271,10 @@ block_read(void **result,
                     break;
 
                   case SVN_FS_X__ITEM_TYPE_NODEREV:
-                    if (ffd->node_revision_cache || is_result)
-                      SVN_ERR(block_read_noderev((svn_fs_x__noderev_t **)&item,
-                                                 fs, revision_file,
-                                                 entry, &key, is_result,
-                                                 pool, iterpool));
+                    SVN_ERR(block_read_noderev((svn_fs_x__noderev_t **)&item,
+                                               fs, revision_file,
+                                               entry, &key, is_result,
+                                               pool, iterpool));
                     break;
 
                   case SVN_FS_X__ITEM_TYPE_CHANGES:

Modified: subversion/branches/ra-git/subversion/libsvn_fs_x/cached_data.h
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_x/cached_data.h?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_x/cached_data.h (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_x/cached_data.h Mon Nov 30 10:24:16 2015
@@ -20,8 +20,8 @@
  * ====================================================================
  */
 
-#ifndef SVN_LIBSVN_FS__CACHED_DATA_H
-#define SVN_LIBSVN_FS__CACHED_DATA_H
+#ifndef SVN_LIBSVN_FS_X_CACHED_DATA_H
+#define SVN_LIBSVN_FS_X_CACHED_DATA_H
 
 #include "svn_pools.h"
 #include "svn_fs.h"

Modified: subversion/branches/ra-git/subversion/libsvn_fs_x/caching.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_x/caching.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_x/caching.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_x/caching.c Mon Nov 30 10:24:16 2015
@@ -23,8 +23,7 @@
 #include "fs.h"
 #include "fs_x.h"
 #include "id.h"
-#include "dag.h"
-#include "tree.h"
+#include "dag_cache.h"
 #include "index.h"
 #include "changes.h"
 #include "noderevs.h"
@@ -260,42 +259,42 @@ init_callbacks(svn_cache__t *cache,
                svn_cache__error_handler_t error_handler,
                apr_pool_t *pool)
 {
-  if (cache != NULL)
-    {
 #ifdef SVN_DEBUG_CACHE_DUMP_STATS
 
-      /* schedule printing the access statistics upon pool cleanup,
-       * i.e. end of FSX session.
-       */
-      dump_cache_baton_t *baton;
-
-      baton = apr_palloc(pool, sizeof(*baton));
-      baton->pool = pool;
-      baton->cache = cache;
-
-      apr_pool_cleanup_register(pool,
-                                baton,
-                                dump_cache_statistics,
-                                apr_pool_cleanup_null);
-#endif
+  /* schedule printing the access statistics upon pool cleanup,
+   * i.e. end of FSX session.
+   */
+  dump_cache_baton_t *baton;
 
-      if (error_handler)
-        SVN_ERR(svn_cache__set_error_handler(cache,
-                                             error_handler,
-                                             fs,
-                                             pool));
+  baton = apr_palloc(pool, sizeof(*baton));
+  baton->pool = pool;
+  baton->cache = cache;
+
+  apr_pool_cleanup_register(pool,
+                            baton,
+                            dump_cache_statistics,
+                            apr_pool_cleanup_null);
+#endif
 
-    }
+  if (error_handler)
+    SVN_ERR(svn_cache__set_error_handler(cache,
+                                          error_handler,
+                                          fs,
+                                          pool));
 
   return SVN_NO_ERROR;
 }
 
 /* Sets *CACHE_P to cache instance based on provided options.
- * Creates memcache if MEMCACHE is not NULL. Creates membuffer cache if
- * MEMBUFFER is not NULL. Fallbacks to inprocess cache if MEMCACHE and
- * MEMBUFFER are NULL and pages is non-zero.  Sets *CACHE_P to NULL
- * otherwise.  Use the given PRIORITY class for the new cache.  If it
- * is 0, then use the default priority class.
+ *
+ * If DUMMY_CACHE is set, create a null cache.  Otherwise, creates a memcache
+ * if MEMCACHE is not NULL or a membuffer cache if MEMBUFFER is not NULL.
+ * Falls back to inprocess cache if no other cache type has been selected
+ * and PAGES is not 0.  Create a null cache otherwise.
+ *
+ * Use the given PRIORITY class for the new cache.  If PRIORITY is 0, then
+ * use the default priority class. HAS_NAMESPACE indicates whether we
+ * prefixed this cache instance with a namespace.
  *
  * Unless NO_HANDLER is true, register an error handler that reports errors
  * as warnings to the FS warning callback.
@@ -313,8 +312,10 @@ create_cache(svn_cache__t **cache_p,
              apr_ssize_t klen,
              const char *prefix,
              apr_uint32_t priority,
+             svn_boolean_t has_namespace,
              svn_fs_t *fs,
              svn_boolean_t no_handler,
+             svn_boolean_t dummy_cache,
              apr_pool_t *result_pool,
              apr_pool_t *scratch_pool)
 {
@@ -324,7 +325,11 @@ create_cache(svn_cache__t **cache_p,
   if (priority == 0)
     priority = SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY;
 
-  if (memcache)
+  if (dummy_cache)
+    {
+      SVN_ERR(svn_cache__create_null(cache_p, prefix, result_pool));
+    }
+  else if (memcache)
     {
       SVN_ERR(svn_cache__create_memcache(cache_p, memcache,
                                          serializer, deserializer, klen,
@@ -335,9 +340,12 @@ create_cache(svn_cache__t **cache_p,
     }
   else if (membuffer)
     {
+      /* We assume caches with namespaces to be relatively short-lived,
+       * i.e. their data will not be needed after a while. */
       SVN_ERR(svn_cache__create_membuffer_cache(
                 cache_p, membuffer, serializer, deserializer,
-                klen, prefix, priority, FALSE, result_pool, scratch_pool));
+                klen, prefix, priority, FALSE, has_namespace,
+                result_pool, scratch_pool));
     }
   else if (pages)
     {
@@ -347,7 +355,7 @@ create_cache(svn_cache__t **cache_p,
     }
   else
     {
-      *cache_p = NULL;
+      SVN_ERR(svn_cache__create_null(cache_p, prefix, result_pool));
     }
 
   SVN_ERR(init_callbacks(*cache_p, fs, error_handler, result_pool));
@@ -362,6 +370,7 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
   svn_fs_x__data_t *ffd = fs->fsap_data;
   const char *prefix = apr_pstrcat(scratch_pool,
                                    "fsx:", fs->uuid,
+                                   "--", ffd->instance_id,
                                    "/", normalize_key_part(fs->path,
                                                            scratch_pool),
                                    ":",
@@ -372,6 +381,7 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
   svn_boolean_t cache_fulltexts;
   svn_boolean_t cache_revprops;
   const char *cache_namespace;
+  svn_boolean_t has_namespace;
 
   /* Evaluating the cache configuration. */
   SVN_ERR(read_config(&cache_namespace,
@@ -383,6 +393,7 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
 
   prefix = apr_pstrcat(scratch_pool, "ns:", cache_namespace, ":", prefix,
                        SVN_VA_NULL);
+  has_namespace = strlen(cache_namespace) > 0;
 
   membuffer = svn_cache__get_global_membuffer_cache();
 
@@ -407,21 +418,6 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
                               apr_pool_cleanup_null);
 #endif
 
-  /* Rough estimate: revision DAG nodes have size around 320 bytes, so
-   * let's put 16 on a page. */
-  SVN_ERR(create_cache(&(ffd->rev_node_cache),
-                       NULL,
-                       membuffer,
-                       1024, 16,
-                       svn_fs_x__dag_serialize,
-                       svn_fs_x__dag_deserialize,
-                       APR_HASH_KEY_STRING,
-                       apr_pstrcat(scratch_pool, prefix, "DAG", SVN_VA_NULL),
-                       SVN_CACHE__MEMBUFFER_LOW_PRIORITY,
-                       fs,
-                       no_handler,
-                       fs->pool, scratch_pool));
-
   /* 1st level DAG node cache */
   ffd->dag_node_cache = svn_fs_x__create_dag_cache(fs->pool);
 
@@ -435,24 +431,9 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
                        sizeof(svn_fs_x__id_t),
                        apr_pstrcat(scratch_pool, prefix, "DIR", SVN_VA_NULL),
                        SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
+                       has_namespace,
                        fs,
-                       no_handler,
-                       fs->pool, scratch_pool));
-
-  /* Only 16 bytes per entry (a revision number + the corresponding offset).
-     Since we want ~8k pages, that means 512 entries per page. */
-  SVN_ERR(create_cache(&(ffd->packed_offset_cache),
-                       NULL,
-                       membuffer,
-                       32, 1,
-                       svn_fs_x__serialize_manifest,
-                       svn_fs_x__deserialize_manifest,
-                       sizeof(svn_revnum_t),
-                       apr_pstrcat(scratch_pool, prefix, "PACK-MANIFEST",
-                                   SVN_VA_NULL),
-                       SVN_CACHE__MEMBUFFER_HIGH_PRIORITY,
-                       fs,
-                       no_handler,
+                       no_handler, FALSE,
                        fs->pool, scratch_pool));
 
   /* initialize node revision cache, if caching has been enabled */
@@ -466,8 +447,9 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
                        apr_pstrcat(scratch_pool, prefix, "NODEREVS",
                                    SVN_VA_NULL),
                        SVN_CACHE__MEMBUFFER_HIGH_PRIORITY,
+                       has_namespace,
                        fs,
-                       no_handler,
+                       no_handler, FALSE,
                        fs->pool, scratch_pool));
 
   /* initialize representation header cache, if caching has been enabled */
@@ -481,8 +463,9 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
                        apr_pstrcat(scratch_pool, prefix, "REPHEADER",
                                    SVN_VA_NULL),
                        SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
+                       has_namespace,
                        fs,
-                       no_handler,
+                       no_handler, FALSE,
                        fs->pool, scratch_pool));
 
   /* initialize node change list cache, if caching has been enabled */
@@ -496,136 +479,90 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
                        apr_pstrcat(scratch_pool, prefix, "CHANGES",
                                    SVN_VA_NULL),
                        0,
+                       has_namespace,
                        fs,
-                       no_handler,
+                       no_handler, FALSE,
                        fs->pool, scratch_pool));
 
   /* if enabled, cache fulltext and other derived information */
-  if (cache_fulltexts)
-    {
-      SVN_ERR(create_cache(&(ffd->fulltext_cache),
-                           ffd->memcache,
-                           membuffer,
-                           0, 0, /* Do not use inprocess cache */
-                           /* Values are svn_stringbuf_t */
-                           NULL, NULL,
-                           sizeof(svn_fs_x__pair_cache_key_t),
-                           apr_pstrcat(scratch_pool, prefix, "TEXT",
-                                       SVN_VA_NULL),
-                           SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
-                           fs,
-                           no_handler,
-                           fs->pool, scratch_pool));
-
-      SVN_ERR(create_cache(&(ffd->properties_cache),
-                           NULL,
-                           membuffer,
-                           0, 0, /* Do not use inprocess cache */
-                           svn_fs_x__serialize_properties,
-                           svn_fs_x__deserialize_properties,
-                           sizeof(svn_fs_x__pair_cache_key_t),
-                           apr_pstrcat(scratch_pool, prefix, "PROP",
-                                       SVN_VA_NULL),
-                           SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
-                           fs,
-                           no_handler,
-                           fs->pool, scratch_pool));
-
-      SVN_ERR(create_cache(&(ffd->mergeinfo_cache),
-                           NULL,
-                           membuffer,
-                           0, 0, /* Do not use inprocess cache */
-                           svn_fs_x__serialize_mergeinfo,
-                           svn_fs_x__deserialize_mergeinfo,
-                           APR_HASH_KEY_STRING,
-                           apr_pstrcat(scratch_pool, prefix, "MERGEINFO",
-                                       SVN_VA_NULL),
-                           0,
-                           fs,
-                           no_handler,
-                           fs->pool, scratch_pool));
-
-      SVN_ERR(create_cache(&(ffd->mergeinfo_existence_cache),
-                           NULL,
-                           membuffer,
-                           0, 0, /* Do not use inprocess cache */
-                           /* Values are svn_stringbuf_t */
-                           NULL, NULL,
-                           APR_HASH_KEY_STRING,
-                           apr_pstrcat(scratch_pool, prefix, "HAS_MERGEINFO",
-                                       SVN_VA_NULL),
-                           0,
-                           fs,
-                           no_handler,
-                           fs->pool, scratch_pool));
-    }
-  else
-    {
-      ffd->fulltext_cache = NULL;
-      ffd->properties_cache = NULL;
-      ffd->mergeinfo_cache = NULL;
-      ffd->mergeinfo_existence_cache = NULL;
-    }
+  SVN_ERR(create_cache(&(ffd->fulltext_cache),
+                       ffd->memcache,
+                       membuffer,
+                       0, 0, /* Do not use inprocess cache */
+                       /* Values are svn_stringbuf_t */
+                       NULL, NULL,
+                       sizeof(svn_fs_x__pair_cache_key_t),
+                       apr_pstrcat(scratch_pool, prefix, "TEXT",
+                                   SVN_VA_NULL),
+                       SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
+                       has_namespace,
+                       fs,
+                       no_handler, !cache_fulltexts,
+                       fs->pool, scratch_pool));
+
+  SVN_ERR(create_cache(&(ffd->properties_cache),
+                       NULL,
+                       membuffer,
+                       0, 0, /* Do not use inprocess cache */
+                       svn_fs_x__serialize_properties,
+                       svn_fs_x__deserialize_properties,
+                       sizeof(svn_fs_x__pair_cache_key_t),
+                       apr_pstrcat(scratch_pool, prefix, "PROP",
+                                   SVN_VA_NULL),
+                       SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
+                       has_namespace,
+                       fs,
+                       no_handler, !cache_fulltexts,
+                       fs->pool, scratch_pool));
 
   /* if enabled, cache revprops */
-  if (cache_revprops)
-    {
-      SVN_ERR(create_cache(&(ffd->revprop_cache),
-                           NULL,
-                           membuffer,
-                           0, 0, /* Do not use inprocess cache */
-                           svn_fs_x__serialize_properties,
-                           svn_fs_x__deserialize_properties,
-                           sizeof(svn_fs_x__pair_cache_key_t),
-                           apr_pstrcat(scratch_pool, prefix, "REVPROP",
-                                       SVN_VA_NULL),
-                           SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
-                           fs,
-                           no_handler,
-                           fs->pool, scratch_pool));
-    }
-  else
-    {
-      ffd->revprop_cache = NULL;
-    }
+  SVN_ERR(create_cache(&(ffd->revprop_cache),
+                       NULL,
+                       membuffer,
+                       0, 0, /* Do not use inprocess cache */
+                       svn_fs_x__serialize_properties,
+                       svn_fs_x__deserialize_properties,
+                       sizeof(svn_fs_x__pair_cache_key_t),
+                       apr_pstrcat(scratch_pool, prefix, "REVPROP",
+                                   SVN_VA_NULL),
+                       SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
+                       has_namespace,
+                       fs,
+                       no_handler, !cache_revprops,
+                       fs->pool, scratch_pool));
 
   /* if enabled, cache text deltas and their combinations */
-  if (cache_txdeltas)
-    {
-      SVN_ERR(create_cache(&(ffd->txdelta_window_cache),
-                           NULL,
-                           membuffer,
-                           0, 0, /* Do not use inprocess cache */
-                           svn_fs_x__serialize_txdelta_window,
-                           svn_fs_x__deserialize_txdelta_window,
-                           sizeof(svn_fs_x__window_cache_key_t),
-                           apr_pstrcat(scratch_pool, prefix, "TXDELTA_WINDOW",
-                                       SVN_VA_NULL),
-                           SVN_CACHE__MEMBUFFER_LOW_PRIORITY,
-                           fs,
-                           no_handler,
-                           fs->pool, scratch_pool));
-
-      SVN_ERR(create_cache(&(ffd->combined_window_cache),
-                           NULL,
-                           membuffer,
-                           0, 0, /* Do not use inprocess cache */
-                           /* Values are svn_stringbuf_t */
-                           NULL, NULL,
-                           sizeof(svn_fs_x__window_cache_key_t),
-                           apr_pstrcat(scratch_pool, prefix, "COMBINED_WINDOW",
-                                       SVN_VA_NULL),
-                           SVN_CACHE__MEMBUFFER_LOW_PRIORITY,
-                           fs,
-                           no_handler,
-                           fs->pool, scratch_pool));
-    }
-  else
-    {
-      ffd->txdelta_window_cache = NULL;
-      ffd->combined_window_cache = NULL;
-    }
+  SVN_ERR(create_cache(&(ffd->txdelta_window_cache),
+                       NULL,
+                       membuffer,
+                       0, 0, /* Do not use inprocess cache */
+                       svn_fs_x__serialize_txdelta_window,
+                       svn_fs_x__deserialize_txdelta_window,
+                       sizeof(svn_fs_x__window_cache_key_t),
+                       apr_pstrcat(scratch_pool, prefix, "TXDELTA_WINDOW",
+                                   SVN_VA_NULL),
+                       SVN_CACHE__MEMBUFFER_LOW_PRIORITY,
+                       has_namespace,
+                       fs,
+                       no_handler, !cache_txdeltas,
+                       fs->pool, scratch_pool));
+
+  SVN_ERR(create_cache(&(ffd->combined_window_cache),
+                       NULL,
+                       membuffer,
+                       0, 0, /* Do not use inprocess cache */
+                       /* Values are svn_stringbuf_t */
+                       NULL, NULL,
+                       sizeof(svn_fs_x__window_cache_key_t),
+                       apr_pstrcat(scratch_pool, prefix, "COMBINED_WINDOW",
+                                   SVN_VA_NULL),
+                       SVN_CACHE__MEMBUFFER_LOW_PRIORITY,
+                       has_namespace,
+                       fs,
+                       no_handler, !cache_txdeltas,
+                       fs->pool, scratch_pool));
 
+  /* Caches for our various container types. */
   SVN_ERR(create_cache(&(ffd->noderevs_container_cache),
                        NULL,
                        membuffer,
@@ -636,8 +573,9 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
                        apr_pstrcat(scratch_pool, prefix, "NODEREVSCNT",
                                    SVN_VA_NULL),
                        SVN_CACHE__MEMBUFFER_HIGH_PRIORITY,
+                       has_namespace,
                        fs,
-                       no_handler,
+                       no_handler, FALSE,
                        fs->pool, scratch_pool));
   SVN_ERR(create_cache(&(ffd->changes_container_cache),
                        NULL,
@@ -649,8 +587,9 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
                        apr_pstrcat(scratch_pool, prefix, "CHANGESCNT",
                                    SVN_VA_NULL),
                        0,
+                       has_namespace,
                        fs,
-                       no_handler,
+                       no_handler, FALSE,
                        fs->pool, scratch_pool));
   SVN_ERR(create_cache(&(ffd->reps_container_cache),
                        NULL,
@@ -662,10 +601,12 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
                        apr_pstrcat(scratch_pool, prefix, "REPSCNT",
                                    SVN_VA_NULL),
                        0,
+                       has_namespace,
                        fs,
-                       no_handler,
+                       no_handler, FALSE,
                        fs->pool, scratch_pool));
 
+  /* Cache index info. */
   SVN_ERR(create_cache(&(ffd->l2p_header_cache),
                        NULL,
                        membuffer,
@@ -677,8 +618,9 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
                        apr_pstrcat(scratch_pool, prefix, "L2P_HEADER",
                                    SVN_VA_NULL),
                        SVN_CACHE__MEMBUFFER_HIGH_PRIORITY,
+                       has_namespace,
                        fs,
-                       no_handler,
+                       no_handler, FALSE,
                        fs->pool, scratch_pool));
   SVN_ERR(create_cache(&(ffd->l2p_page_cache),
                        NULL,
@@ -691,8 +633,9 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
                        apr_pstrcat(scratch_pool, prefix, "L2P_PAGE",
                                    SVN_VA_NULL),
                        SVN_CACHE__MEMBUFFER_HIGH_PRIORITY,
+                       has_namespace,
                        fs,
-                       no_handler,
+                       no_handler, FALSE,
                        fs->pool, scratch_pool));
   SVN_ERR(create_cache(&(ffd->p2l_header_cache),
                        NULL,
@@ -704,8 +647,9 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
                        apr_pstrcat(scratch_pool, prefix, "P2L_HEADER",
                                    SVN_VA_NULL),
                        SVN_CACHE__MEMBUFFER_HIGH_PRIORITY,
+                       has_namespace,
                        fs,
-                       no_handler,
+                       no_handler, FALSE,
                        fs->pool, scratch_pool));
   SVN_ERR(create_cache(&(ffd->p2l_page_cache),
                        NULL,
@@ -717,8 +661,9 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
                        apr_pstrcat(scratch_pool, prefix, "P2L_PAGE",
                                    SVN_VA_NULL),
                        SVN_CACHE__MEMBUFFER_HIGH_PRIORITY,
+                       has_namespace,
                        fs,
-                       no_handler,
+                       no_handler, FALSE,
                        fs->pool, scratch_pool));
 
   return SVN_NO_ERROR;

Modified: subversion/branches/ra-git/subversion/libsvn_fs_x/changes.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_x/changes.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_x/changes.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_x/changes.c Mon Nov 30 10:24:16 2015
@@ -222,7 +222,7 @@ svn_error_t *
 svn_fs_x__changes_get_list(apr_array_header_t **list,
                            const svn_fs_x__changes_t *changes,
                            apr_size_t idx,
-                           apr_pool_t *pool)
+                           apr_pool_t *result_pool)
 {
   int first;
   int last;
@@ -235,7 +235,7 @@ svn_fs_x__changes_get_list(apr_array_hea
   /* validate index */
   if (idx + 1 >= (apr_size_t)changes->offsets->nelts)
     return svn_error_createf(SVN_ERR_FS_CONTAINER_INDEX, NULL,
-                             apr_psprintf(pool,
+                             apr_psprintf(result_pool,
                                           _("Changes list index %%%s"
                                             " exceeds container size %%d"),
                                           APR_SIZE_T_FMT),
@@ -246,18 +246,19 @@ svn_fs_x__changes_get_list(apr_array_hea
   last = APR_ARRAY_IDX(changes->offsets, (int)idx + 1, int);
 
   /* construct result */
-  *list = apr_array_make(pool, last - first, sizeof(svn_fs_x__change_t*));
+  *list = apr_array_make(result_pool, last - first,
+                         sizeof(svn_fs_x__change_t*));
   for (i = first; i < last; ++i)
     {
       const binary_change_t *binary_change
         = &APR_ARRAY_IDX(changes->changes, i, binary_change_t);
 
       /* convert BINARY_CHANGE into a standard FSX svn_fs_x__change_t */
-      svn_fs_x__change_t *change = apr_pcalloc(pool, sizeof(*change));
+      svn_fs_x__change_t *change = apr_pcalloc(result_pool, sizeof(*change));
       change->path.data = svn_fs_x__string_table_get(changes->paths,
                                                      binary_change->path,
                                                      &change->path.len,
-                                                     pool);
+                                                     result_pool);
 
       if (binary_change->noderev_id.change_set != SVN_FS_X__INVALID_CHANGE_SET)
         change->noderev_id = binary_change->noderev_id;
@@ -276,7 +277,7 @@ svn_fs_x__changes_get_list(apr_array_hea
           = svn_fs_x__string_table_get(changes->paths,
                                         binary_change->copyfrom_path,
                                         NULL,
-                                        pool);
+                                        result_pool);
 
       /* add it to the result */
       APR_ARRAY_PUSH(*list, svn_fs_x__change_t*) = change;
@@ -437,14 +438,14 @@ svn_error_t *
 svn_fs_x__deserialize_changes_container(void **out,
                                          void *data,
                                          apr_size_t data_len,
-                                         apr_pool_t *pool)
+                                         apr_pool_t *result_pool)
 {
   svn_fs_x__changes_t *changes = (svn_fs_x__changes_t *)data;
 
   /* de-serialize sub-structures */
   svn_fs_x__deserialize_string_table(changes, &changes->paths);
-  svn_fs_x__deserialize_apr_array(changes, &changes->changes, pool);
-  svn_fs_x__deserialize_apr_array(changes, &changes->offsets, pool);
+  svn_fs_x__deserialize_apr_array(changes, &changes->changes, result_pool);
+  svn_fs_x__deserialize_apr_array(changes, &changes->offsets, result_pool);
 
   /* done */
   *out = changes;

Modified: subversion/branches/ra-git/subversion/libsvn_fs_x/changes.h
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_x/changes.h?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_x/changes.h (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_x/changes.h Mon Nov 30 10:24:16 2015
@@ -20,8 +20,8 @@
  * ====================================================================
  */
 
-#ifndef SVN_LIBSVN_FS__CHANGES_H
-#define SVN_LIBSVN_FS__CHANGES_H
+#ifndef SVN_LIBSVN_FS_X_CHANGES_H
+#define SVN_LIBSVN_FS_X_CHANGES_H
 
 #include "svn_io.h"
 #include "fs.h"
@@ -78,7 +78,7 @@ svn_error_t *
 svn_fs_x__changes_get_list(apr_array_header_t **list,
                            const svn_fs_x__changes_t *changes,
                            apr_size_t idx,
-                           apr_pool_t *pool);
+                           apr_pool_t *result_pool);
 
 /* I/O interface. */
 
@@ -114,7 +114,7 @@ svn_error_t *
 svn_fs_x__deserialize_changes_container(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 for svn_fs_x__changes_t,
  * setting *OUT to the change list (apr_array_header_t *) selected by