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

svn commit: r1605201 [2/5] - in /subversion/branches/svn-auth-x509: ./ build/generator/ subversion/bindings/javahl/native/ subversion/bindings/javahl/src/org/apache/subversion/javahl/ subversion/bindings/javahl/tests/org/apache/subversion/javahl/ subve...

Modified: subversion/branches/svn-auth-x509/subversion/libsvn_fs_fs/cached_data.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/libsvn_fs_fs/cached_data.c?rev=1605201&r1=1605200&r2=1605201&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/libsvn_fs_fs/cached_data.c (original)
+++ subversion/branches/svn-auth-x509/subversion/libsvn_fs_fs/cached_data.c Tue Jun 24 21:29:59 2014
@@ -88,12 +88,13 @@ dbg_log_access(svn_fs_t *fs,
   const char *type = types[item_type];
   const char *pack = "";
   apr_off_t offset;
-  svn_fs_fs__revision_file_t rev_file;
+  svn_fs_fs__revision_file_t *rev_file;
 
-  svn_fs_fs__init_revision_file(&rev_file, fs, revision, scratch_pool);
+  SVN_ERR(svn_fs_fs__open_pack_or_rev_file(&rev_file, fs, revision,
+                                           scratch_pool));
 
   /* determine rev / pack file offset */
-  SVN_ERR(svn_fs_fs__item_offset(&offset, fs, &rev_file, revision, NULL,
+  SVN_ERR(svn_fs_fs__item_offset(&offset, fs, rev_file, revision, NULL,
                                  item_index, scratch_pool));
 
   /* constructing the pack file description */
@@ -156,7 +157,7 @@ dbg_log_access(svn_fs_t *fs,
   if (svn_fs_fs__use_log_addressing(fs, revision))
     {
       /* reverse index lookup: get item description in ENTRY */
-      SVN_ERR(svn_fs_fs__p2l_entry_lookup(&entry, fs, &rev_file, revision,
+      SVN_ERR(svn_fs_fs__p2l_entry_lookup(&entry, fs, rev_file, revision,
                                           offset, scratch_pool));
       if (entry)
         {
@@ -284,7 +285,8 @@ static svn_error_t *
 get_node_revision_body(node_revision_t **noderev_p,
                        svn_fs_t *fs,
                        const svn_fs_id_t *id,
-                       apr_pool_t *pool)
+                       apr_pool_t *result_pool,
+                       apr_pool_t *scratch_pool)
 {
   svn_error_t *err;
   svn_boolean_t is_cached = FALSE;
@@ -297,8 +299,10 @@ get_node_revision_body(node_revision_t *
       /* This is a transaction node-rev.  Its storage logic is very
          different from that of rev / pack files. */
       err = svn_io_file_open(&file,
-                             svn_fs_fs__path_txn_node_rev(fs, id, pool),
-                             APR_READ | APR_BUFFERED, APR_OS_DEFAULT, pool);
+                             svn_fs_fs__path_txn_node_rev(fs, id,
+                             scratch_pool),
+                             APR_READ | APR_BUFFERED, APR_OS_DEFAULT,
+                             scratch_pool);
       if (err)
         {
           if (APR_STATUS_IS_ENOENT(err->apr_err))
@@ -313,8 +317,8 @@ get_node_revision_body(node_revision_t *
       SVN_ERR(svn_fs_fs__read_noderev(noderev_p,
                                       svn_stream_from_aprfile2(file,
                                                                FALSE,
-                                                               pool),
-                                      pool));
+                                                               scratch_pool),
+                                      result_pool, scratch_pool));
     }
   else
     {
@@ -334,7 +338,7 @@ get_node_revision_body(node_revision_t *
                                  &is_cached,
                                  ffd->node_revision_cache,
                                  &key,
-                                 pool));
+                                 result_pool));
           if (is_cached)
             return SVN_NO_ERROR;
         }
@@ -343,7 +347,7 @@ get_node_revision_body(node_revision_t *
       SVN_ERR(open_and_seek_revision(&revision_file, fs,
                                      rev_item->revision,
                                      rev_item->number,
-                                     pool));
+                                     scratch_pool));
 
       if (svn_fs_fs__use_log_addressing(fs, rev_item->revision))
         {
@@ -353,15 +357,16 @@ get_node_revision_body(node_revision_t *
                              rev_item->revision,
                              rev_item->number,
                              revision_file,
-                             pool,
-                             pool));
+                             result_pool,
+                             scratch_pool));
         }
       else
         {
           /* physical addressing mode reading, parsing and caching */
           SVN_ERR(svn_fs_fs__read_noderev(noderev_p,
                                           revision_file->stream,
-                                          pool));
+                                          result_pool,
+                                          scratch_pool));
 
           /* Workaround issue #4031: is-fresh-txn-root in revision files. */
           (*noderev_p)->is_fresh_txn_root = FALSE;
@@ -371,7 +376,7 @@ get_node_revision_body(node_revision_t *
             SVN_ERR(svn_cache__set(ffd->node_revision_cache,
                                    &key,
                                    *noderev_p,
-                                   pool));
+                                   scratch_pool));
         }
 
       SVN_ERR(svn_fs_fs__close_revision_file(revision_file));
@@ -384,14 +389,16 @@ svn_error_t *
 svn_fs_fs__get_node_revision(node_revision_t **noderev_p,
                              svn_fs_t *fs,
                              const svn_fs_id_t *id,
-                             apr_pool_t *pool)
+                             apr_pool_t *result_pool,
+                             apr_pool_t *scratch_pool)
 {
   const svn_fs_fs__id_part_t *rev_item = svn_fs_fs__id_rev_item(id);
 
-  svn_error_t *err = get_node_revision_body(noderev_p, fs, id, pool);
+  svn_error_t *err = get_node_revision_body(noderev_p, fs, id,
+                                            result_pool, scratch_pool);
   if (err && err->apr_err == SVN_ERR_FS_CORRUPT)
     {
-      svn_string_t *id_string = svn_fs_fs__id_unparse(id, pool);
+      svn_string_t *id_string = svn_fs_fs__id_unparse(id, scratch_pool);
       return svn_error_createf(SVN_ERR_FS_CORRUPT, err,
                                "Corrupt node-revision '%s'",
                                id_string->data);
@@ -402,7 +409,7 @@ svn_fs_fs__get_node_revision(node_revisi
                          rev_item->number,
                          *noderev_p,
                          SVN_FS_FS__ITEM_TYPE_NODEREV,
-                         pool));
+                         scratch_pool));
 
   return svn_error_trace(err);
 }
@@ -424,7 +431,7 @@ get_fs_id_at_offset(svn_fs_id_t **id_p,
   SVN_ERR(aligned_seek(fs, rev_file->file, NULL, offset, pool));
   SVN_ERR(svn_fs_fs__read_noderev(&noderev,
                                   rev_file->stream,
-                                  pool));
+                                  pool, pool));
 
   /* noderev->id is const, get rid of that */
   *id_p = svn_fs_fs__id_copy(noderev->id, pool);
@@ -537,14 +544,15 @@ svn_error_t *
 svn_fs_fs__rev_get_root(svn_fs_id_t **root_id_p,
                         svn_fs_t *fs,
                         svn_revnum_t rev,
-                        apr_pool_t *pool)
+                        apr_pool_t *result_pool,
+                        apr_pool_t *scratch_pool)
 {
   fs_fs_data_t *ffd = fs->fsap_data;
-  SVN_ERR(svn_fs_fs__ensure_revision_exists(rev, fs, pool));
+  SVN_ERR(svn_fs_fs__ensure_revision_exists(rev, fs, scratch_pool));
 
   if (svn_fs_fs__use_log_addressing(fs, rev))
     {
-      *root_id_p = svn_fs_fs__id_create_root(rev, pool);
+      *root_id_p = svn_fs_fs__id_create_root(rev, result_pool);
     }
   else
     {
@@ -554,20 +562,23 @@ svn_fs_fs__rev_get_root(svn_fs_id_t **ro
       svn_boolean_t is_cached;
 
       SVN_ERR(svn_cache__get((void **) root_id_p, &is_cached,
-                            ffd->rev_root_id_cache, &rev, pool));
+                            ffd->rev_root_id_cache, &rev, result_pool));
       if (is_cached)
         return SVN_NO_ERROR;
 
-      SVN_ERR(svn_fs_fs__open_pack_or_rev_file(&revision_file, fs, rev, pool));
+      SVN_ERR(svn_fs_fs__open_pack_or_rev_file(&revision_file, fs, rev,
+                                               scratch_pool));
       SVN_ERR(get_root_changes_offset(&root_offset, NULL,
-                                      revision_file->file, fs, rev, pool));
+                                      revision_file->file, fs, rev,
+                                      scratch_pool));
 
       SVN_ERR(get_fs_id_at_offset(&root_id, revision_file, fs, rev,
-                                  root_offset, pool));
+                                  root_offset, result_pool));
 
       SVN_ERR(svn_fs_fs__close_revision_file(revision_file));
 
-      SVN_ERR(svn_cache__set(ffd->rev_root_id_cache, &rev, root_id, pool));
+      SVN_ERR(svn_cache__set(ffd->rev_root_id_cache, &rev, root_id,
+                             scratch_pool));
 
       *root_id_p = root_id;
     }
@@ -711,10 +722,11 @@ create_rep_state_body(rep_state_t **rep_
                       shared_file_t **shared_file,
                       representation_t *rep,
                       svn_fs_t *fs,
-                      apr_pool_t *pool)
+                      apr_pool_t *result_pool,
+                      apr_pool_t *scratch_pool)
 {
   fs_fs_data_t *ffd = fs->fsap_data;
-  rep_state_t *rs = apr_pcalloc(pool, sizeof(*rs));
+  rep_state_t *rs = apr_pcalloc(result_pool, sizeof(*rs));
   svn_fs_fs__rep_header_t *rh;
   svn_boolean_t is_cached = FALSE;
   apr_uint64_t estimated_window_storage;
@@ -771,7 +783,7 @@ create_rep_state_body(rep_state_t **rep_
   /* cache lookup, i.e. skip reading the rep header if possible */
   if (ffd->rep_header_cache && !svn_fs_fs__id_txn_used(&rep->txn_id))
     SVN_ERR(svn_cache__get((void **) &rh, &is_cached,
-                           ffd->rep_header_cache, &key, pool));
+                           ffd->rep_header_cache, &key, result_pool));
 
   /* initialize the (shared) FILE member in RS */
   if (reuse_shared_file)
@@ -780,9 +792,9 @@ create_rep_state_body(rep_state_t **rep_
     }
   else
     {
-      shared_file_t *file = apr_pcalloc(pool, sizeof(*file));
+      shared_file_t *file = apr_pcalloc(result_pool, sizeof(*file));
       file->revision = rep->revision;
-      file->pool = pool;
+      file->pool = result_pool;
       file->fs = fs;
       rs->sfile = file;
 
@@ -806,8 +818,8 @@ create_rep_state_body(rep_state_t **rep_
           SVN_ERR(auto_open_shared_file(rs->sfile));
           SVN_ERR(svn_fs_fs__item_offset(&offset, fs, rs->sfile->rfile,
                                          rep->revision, NULL, rep->item_index,
-                                         pool));
-          SVN_ERR(rs_aligned_seek(rs, NULL, offset, pool));
+                                         scratch_pool));
+          SVN_ERR(rs_aligned_seek(rs, NULL, offset, scratch_pool));
         }
       else
         {
@@ -815,27 +827,29 @@ create_rep_state_body(rep_state_t **rep_
            * an in-txn file.
            */
           SVN_ERR(open_and_seek_representation(&rs->sfile->rfile, fs, rep,
-                                               pool));
+                                               result_pool));
         }
 
-      SVN_ERR(svn_fs_fs__read_rep_header(&rh, rs->sfile->rfile->stream, pool));
-      SVN_ERR(get_file_offset(&rs->start, rs, pool));
+      SVN_ERR(svn_fs_fs__read_rep_header(&rh, rs->sfile->rfile->stream,
+                                         result_pool, scratch_pool));
+      SVN_ERR(get_file_offset(&rs->start, rs, result_pool));
 
       /* populate the cache if appropriate */
       if (! svn_fs_fs__id_txn_used(&rep->txn_id))
         {
           if (svn_fs_fs__use_log_addressing(fs, rep->revision))
             SVN_ERR(block_read(NULL, fs, rep->revision, rep->item_index,
-                               rs->sfile->rfile, pool, pool));
+                               rs->sfile->rfile, result_pool, scratch_pool));
           else
             if (ffd->rep_header_cache)
-              SVN_ERR(svn_cache__set(ffd->rep_header_cache, &key, rh, pool));
+              SVN_ERR(svn_cache__set(ffd->rep_header_cache, &key, rh,
+                                     scratch_pool));
         }
     }
 
   /* finalize */
   SVN_ERR(dbg_log_access(fs, rep->revision, rep->item_index, rh,
-                         SVN_FS_FS__ITEM_TYPE_ANY_REP, pool));
+                         SVN_FS_FS__ITEM_TYPE_ANY_REP, scratch_pool));
 
   rs->header_size = rh->header_size;
   *rep_state = rs;
@@ -868,13 +882,16 @@ create_rep_state(rep_state_t **rep_state
                  shared_file_t **shared_file,
                  representation_t *rep,
                  svn_fs_t *fs,
-                 apr_pool_t *pool)
+                 apr_pool_t *result_pool,
+                 apr_pool_t *scratch_pool)
 {
   svn_error_t *err = create_rep_state_body(rep_state, rep_header,
-                                           shared_file, rep, fs, pool);
+                                           shared_file, rep, fs,
+                                           result_pool, scratch_pool);
   if (err && err->apr_err == SVN_ERR_FS_CORRUPT)
     {
       fs_fs_data_t *ffd = fs->fsap_data;
+      const char *rep_str;
 
       /* ### This always returns "-1" for transaction reps, because
          ### this particular bit of code doesn't know if the rep is
@@ -883,12 +900,14 @@ create_rep_state(rep_state_t **rep_state
          ### from the protorev file, though, so this is probably OK.
          ### And anyone going to debug corruption errors is probably
          ### going to jump straight to this comment anyway! */
+      rep_str = rep
+              ? svn_fs_fs__unparse_representation
+                  (rep, ffd->format, TRUE, scratch_pool, scratch_pool)->data
+              : "(null)";
+
       return svn_error_createf(SVN_ERR_FS_CORRUPT, err,
                                "Corrupt representation '%s'",
-                               rep
-                               ? svn_fs_fs__unparse_representation
-                                   (rep, ffd->format, TRUE, pool)->data
-                               : "(null)");
+                               rep_str);
     }
   /* ### Call representation_string() ? */
   return svn_error_trace(err);
@@ -898,7 +917,7 @@ svn_error_t *
 svn_fs_fs__check_rep(representation_t *rep,
                      svn_fs_t *fs,
                      void **hint,
-                     apr_pool_t *pool)
+                     apr_pool_t *scratch_pool)
 {
   if (svn_fs_fs__use_log_addressing(fs, rep->revision))
     {
@@ -906,32 +925,33 @@ svn_fs_fs__check_rep(representation_t *r
       apr_off_t offset;
       svn_fs_fs__p2l_entry_t *entry;
 
-      svn_fs_fs__revision_file_t rev_file;
-      svn_fs_fs__init_revision_file(&rev_file, fs, rep->revision, pool);
+      svn_fs_fs__revision_file_t *rev_file;
+      SVN_ERR(svn_fs_fs__open_pack_or_rev_file(&rev_file, fs, rep->revision,
+                                               scratch_pool));
 
       /* This will auto-retry if there was a background pack. */
-      SVN_ERR(svn_fs_fs__item_offset(&offset, fs, &rev_file, rep->revision,
-                                     NULL, rep->item_index, pool));
+      SVN_ERR(svn_fs_fs__item_offset(&offset, fs, rev_file, rep->revision,
+                                     NULL, rep->item_index, scratch_pool));
 
       /* This may fail if there is a background pack operation (can't auto-
          retry because the item offset lookup has to be redone as well). */
-      err = svn_fs_fs__p2l_entry_lookup(&entry, fs, &rev_file, rep->revision,
-                                        offset, pool);
+      err = svn_fs_fs__p2l_entry_lookup(&entry, fs, rev_file, rep->revision,
+                                        offset, scratch_pool);
 
       /* Retry if the packing state may have changed, i.e. if we got an
          error while opening the index for a non-packed rev file. */
-      if (err && !rev_file.is_packed)
+      if (err && !rev_file->is_packed)
         {
-          SVN_ERR(svn_fs_fs__close_revision_file(&rev_file));
+          SVN_ERR(svn_fs_fs__close_revision_file(rev_file));
 
           /* Be sure to know the latest pack status of REP. */
-          SVN_ERR(svn_fs_fs__update_min_unpacked_rev(fs, pool));
+          SVN_ERR(svn_fs_fs__update_min_unpacked_rev(fs, scratch_pool));
           if (svn_fs_fs__is_packed_rev(fs, rep->revision))
             {
               /* REP got actually packed. Retry (can happen at most once). */
               svn_error_clear(err);
               return svn_error_trace(svn_fs_fs__check_rep(rep, fs, hint,
-                                                          pool));
+                                                          scratch_pool));
             }
         }
 
@@ -943,12 +963,13 @@ svn_fs_fs__check_rep(representation_t *r
         return svn_error_createf(SVN_ERR_REPOS_CORRUPTED, NULL,
                                  _("No representation found at offset %s "
                                    "for item %s in revision %ld"),
-                                 apr_off_t_toa(pool, offset),
-                                 apr_psprintf(pool, "%" APR_UINT64_T_FMT,
+                                 apr_off_t_toa(scratch_pool, offset),
+                                 apr_psprintf(scratch_pool,
+                                              "%" APR_UINT64_T_FMT,
                                               rep->item_index),
                                  rep->revision);
 
-      SVN_ERR(svn_fs_fs__close_revision_file(&rev_file));
+      SVN_ERR(svn_fs_fs__close_revision_file(rev_file));
     }
   else
     {
@@ -957,7 +978,7 @@ svn_fs_fs__check_rep(representation_t *r
 
       /* ### Should this be using read_rep_line() directly? */
       SVN_ERR(create_rep_state(&rs, &rep_header, (shared_file_t**)hint,
-                               rep, fs, pool));
+                               rep, fs, scratch_pool, scratch_pool));
     }
 
   return SVN_NO_ERROR;
@@ -968,13 +989,14 @@ svn_fs_fs__rep_chain_length(int *chain_l
                             int *shard_count,
                             representation_t *rep,
                             svn_fs_t *fs,
-                            apr_pool_t *pool)
+                            apr_pool_t *scratch_pool)
 {
   fs_fs_data_t *ffd = fs->fsap_data;
   svn_revnum_t shard_size = ffd->max_files_per_dir
                           ? ffd->max_files_per_dir
                           : 1;
-  apr_pool_t *sub_pool = svn_pool_create(pool);
+  apr_pool_t *sub_pool = svn_pool_create(scratch_pool);
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
   svn_boolean_t is_delta = FALSE;
   int count = 0;
   int shards = 1;
@@ -995,6 +1017,9 @@ svn_fs_fs__rep_chain_length(int *chain_l
   do
     {
       rep_state_t *rep_state;
+
+      svn_pool_clear(iterpool);
+
       if (base_rep.revision / shard_size != last_shard)
         {
           last_shard = base_rep.revision / shard_size;
@@ -1006,7 +1031,8 @@ svn_fs_fs__rep_chain_length(int *chain_l
                                     &file_hint,
                                     &base_rep,
                                     fs,
-                                    sub_pool));
+                                    sub_pool,
+                                    iterpool));
 
       base_rep.revision = header->base_revision;
       base_rep.item_index = header->base_item_index;
@@ -1026,6 +1052,7 @@ svn_fs_fs__rep_chain_length(int *chain_l
   *chain_length = count;
   *shard_count = shards;
   svn_pool_destroy(sub_pool);
+  svn_pool_destroy(iterpool);
 
   return SVN_NO_ERROR;
 }
@@ -1148,8 +1175,8 @@ parse_raw_window(void **out,
  * rep state RS from the current FSFS session's cache.  This will be a
  * no-op and IS_CACHED will be set to FALSE if no cache has been given.
  * If a cache is available IS_CACHED will inform the caller about the
- * success of the lookup. Allocations (of the window in particualar) will
- * be made from POOL.
+ * success of the lookup. Allocations of the window in will be made
+ * from RESULT_POOL. Use SCRATCH_POOL for temporary allocations.
  *
  * If the information could be found, put RS to CHUNK_INDEX.
  */
@@ -1158,7 +1185,8 @@ get_cached_window(svn_txdelta_window_t *
                   rep_state_t *rs,
                   int chunk_index,
                   svn_boolean_t *is_cached,
-                  apr_pool_t *pool)
+                  apr_pool_t *result_pool,
+                  apr_pool_t *scratch_pool)
 {
   if (! rs->window_cache)
     {
@@ -1176,7 +1204,7 @@ get_cached_window(svn_txdelta_window_t *
                              is_cached,
                              rs->window_cache,
                              &key,
-                             pool));
+                             result_pool));
 
       /* If we did not find a parsed txdelta window, we might have a raw
          version of it in our cache.  If so, read, parse and re-cache it. */
@@ -1184,10 +1212,10 @@ get_cached_window(svn_txdelta_window_t *
         {
           SVN_ERR(svn_cache__get_partial((void **) &cached_window, is_cached,
                                          rs->raw_window_cache, &key,
-                                         parse_raw_window, NULL, pool));
+                                         parse_raw_window, NULL, result_pool));
           if (*is_cached)
             SVN_ERR(svn_cache__set(rs->window_cache, &key, cached_window,
-                                   pool));
+                                   scratch_pool));
         }
 
       /* Return cached information. */
@@ -1312,6 +1340,7 @@ build_rep_list(apr_array_header_t **list
   svn_fs_fs__rep_header_t *rep_header;
   svn_boolean_t is_cached = FALSE;
   shared_file_t *shared_file = NULL;
+  apr_pool_t *iterpool = svn_pool_create(pool);
 
   *list = apr_array_make(pool, 1, sizeof(rep_state_t *));
   rep = *first_rep;
@@ -1321,7 +1350,8 @@ build_rep_list(apr_array_header_t **list
   *expanded_size = first_rep->expanded_size;
 
   /* for the top-level rep, we need the rep_args */
-  SVN_ERR(create_rep_state(&rs, &rep_header, &shared_file, &rep, fs, pool));
+  SVN_ERR(create_rep_state(&rs, &rep_header, &shared_file, &rep, fs, pool,
+                           iterpool));
 
   /* Unknown size or empty representation?
      That implies the this being the first iteration.
@@ -1335,10 +1365,12 @@ build_rep_list(apr_array_header_t **list
 
   while (1)
     {
+      svn_pool_clear(iterpool);
+
       /* fetch state, if that has not been done already */
       if (!rs)
         SVN_ERR(create_rep_state(&rs, &rep_header, &shared_file,
-                                 &rep, fs, pool));
+                                 &rep, fs, pool, iterpool));
 
       /* for txn reps, there won't be a cached combined window */
       if (!svn_fs_fs__id_txn_used(&rep.txn_id))
@@ -1352,14 +1384,14 @@ build_rep_list(apr_array_header_t **list
           rs->current = 0;
           rs->size = (*window_p)->len;
           *src_state = rs;
-          return SVN_NO_ERROR;
+          break;
         }
 
       if (rep_header->type == svn_fs_fs__rep_plain)
         {
           /* This is a plaintext, so just return the current rep_state. */
           *src_state = rs;
-          return SVN_NO_ERROR;
+          break;
         }
 
       /* Push this rep onto the list.  If it's self-compressed, we're done. */
@@ -1367,7 +1399,7 @@ build_rep_list(apr_array_header_t **list
       if (rep_header->type == svn_fs_fs__rep_self_delta)
         {
           *src_state = NULL;
-          return SVN_NO_ERROR;
+          break;
         }
 
       rep.revision = rep_header->base_revision;
@@ -1377,6 +1409,9 @@ build_rep_list(apr_array_header_t **list
 
       rs = NULL;
     }
+  svn_pool_destroy(iterpool);
+
+  return SVN_NO_ERROR;
 }
 
 
@@ -1421,18 +1456,22 @@ rep_read_get_baton(struct rep_read_baton
    than THIS_CHUNK + 1 when this function returns. */
 static svn_error_t *
 read_delta_window(svn_txdelta_window_t **nwin, int this_chunk,
-                  rep_state_t *rs, apr_pool_t *pool)
+                  rep_state_t *rs, apr_pool_t *result_pool,
+                  apr_pool_t *scratch_pool)
 {
   svn_boolean_t is_cached;
   apr_off_t start_offset;
   apr_off_t end_offset;
+  apr_pool_t *iterpool;
+
   SVN_ERR_ASSERT(rs->chunk_index <= this_chunk);
 
   SVN_ERR(dbg_log_access(rs->sfile->fs, rs->revision, rs->item_index,
-                         NULL, SVN_FS_FS__ITEM_TYPE_ANY_REP, pool));
+                         NULL, SVN_FS_FS__ITEM_TYPE_ANY_REP, scratch_pool));
 
   /* Read the next window.  But first, try to find it in the cache. */
-  SVN_ERR(get_cached_window(nwin, rs, this_chunk, &is_cached, pool));
+  SVN_ERR(get_cached_window(nwin, rs, this_chunk, &is_cached,
+                            result_pool, scratch_pool));
   if (is_cached)
     return SVN_NO_ERROR;
 
@@ -1448,32 +1487,35 @@ read_delta_window(svn_txdelta_window_t *
       && rs->raw_window_cache)
     {
       SVN_ERR(block_read(NULL, rs->sfile->fs, rs->revision, rs->item_index,
-                         rs->sfile->rfile, pool, pool));
+                         rs->sfile->rfile, result_pool, scratch_pool));
 
       /* reading the whole block probably also provided us with the
          desired txdelta window */
-      SVN_ERR(get_cached_window(nwin, rs, this_chunk, &is_cached, pool));
+      SVN_ERR(get_cached_window(nwin, rs, this_chunk, &is_cached,
+                                result_pool, scratch_pool));
       if (is_cached)
         return SVN_NO_ERROR;
     }
 
   /* data is still not cached -> we need to read it.
      Make sure we have all the necessary info. */
-  SVN_ERR(auto_set_start_offset(rs, pool));
-  SVN_ERR(auto_read_diff_version(rs, pool));
+  SVN_ERR(auto_set_start_offset(rs, scratch_pool));
+  SVN_ERR(auto_read_diff_version(rs, scratch_pool));
 
   /* 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, pool));
+  SVN_ERR(rs_aligned_seek(rs, NULL, start_offset, scratch_pool));
 
   /* 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)
     {
+      svn_pool_clear(iterpool);
       SVN_ERR(svn_txdelta_skip_svndiff_window(rs->sfile->rfile->file,
-                                              rs->ver, pool));
+                                              rs->ver, iterpool));
       rs->chunk_index++;
-      SVN_ERR(get_file_offset(&start_offset, rs, pool));
+      SVN_ERR(get_file_offset(&start_offset, rs, iterpool));
       rs->current = start_offset - rs->start;
       if (rs->current >= rs->size)
         return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
@@ -1481,11 +1523,12 @@ read_delta_window(svn_txdelta_window_t *
                                   "beyond the end of the "
                                   "representation"));
     }
+  svn_pool_destroy(iterpool);
 
   /* Actually read the next window. */
   SVN_ERR(svn_txdelta_read_svndiff_window(nwin, rs->sfile->rfile->stream,
-                                          rs->ver, pool));
-  SVN_ERR(get_file_offset(&end_offset, rs, pool));
+                                          rs->ver, result_pool));
+  SVN_ERR(get_file_offset(&end_offset, rs, scratch_pool));
   rs->current = end_offset - rs->start;
   if (rs->current > rs->size)
     return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
@@ -1495,7 +1538,7 @@ read_delta_window(svn_txdelta_window_t *
   /* the window has not been cached before, thus cache it now
    * (if caching is used for them at all) */
   if (SVN_IS_VALID_REVNUM(rs->revision))
-    SVN_ERR(set_cached_window(*nwin, rs, pool));
+    SVN_ERR(set_cached_window(*nwin, rs, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -1503,22 +1546,23 @@ read_delta_window(svn_txdelta_window_t *
 /* Read SIZE bytes from the representation RS and return it in *NWIN. */
 static svn_error_t *
 read_plain_window(svn_stringbuf_t **nwin, rep_state_t *rs,
-                  apr_size_t size, apr_pool_t *pool)
+                  apr_size_t size, apr_pool_t *result_pool,
+                  apr_pool_t *scratch_pool)
 {
   apr_off_t offset;
   
   /* RS->FILE may be shared between RS instances -> make sure we point
    * to the right data. */
   SVN_ERR(auto_open_shared_file(rs->sfile));
-  SVN_ERR(auto_set_start_offset(rs, pool));
+  SVN_ERR(auto_set_start_offset(rs, scratch_pool));
 
   offset = rs->start + rs->current;
-  SVN_ERR(rs_aligned_seek(rs, NULL, offset, pool));
+  SVN_ERR(rs_aligned_seek(rs, NULL, offset, scratch_pool));
 
   /* Read the plain data. */
-  *nwin = svn_stringbuf_create_ensure(size, pool);
+  *nwin = svn_stringbuf_create_ensure(size, result_pool);
   SVN_ERR(svn_io_file_read_full2(rs->sfile->rfile->file, (*nwin)->data, size,
-                                 NULL, NULL, pool));
+                                 NULL, NULL, result_pool));
   (*nwin)->data[size] = 0;
 
   /* Update RS. */
@@ -1539,6 +1583,7 @@ get_combined_window(svn_stringbuf_t **re
   apr_array_header_t *windows;
   svn_stringbuf_t *source, *buf = rb->base_window;
   rep_state_t *rs;
+  apr_pool_t *iterpool;
 
   /* Read all windows that we need to combine. This is fine because
      the size of each window is relatively small (100kB) and skip-
@@ -1546,12 +1591,16 @@ get_combined_window(svn_stringbuf_t **re
      Stop early if one of them does not depend on its predecessors. */
   window_pool = svn_pool_create(rb->pool);
   windows = apr_array_make(window_pool, 0, sizeof(svn_txdelta_window_t *));
+  iterpool = svn_pool_create(rb->pool);
   for (i = 0; i < rb->rs_list->nelts; ++i)
     {
       svn_txdelta_window_t *window;
 
+      svn_pool_clear(iterpool);
+
       rs = APR_ARRAY_IDX(rb->rs_list, i, rep_state_t *);
-      SVN_ERR(read_delta_window(&window, rb->chunk_index, rs, window_pool));
+      SVN_ERR(read_delta_window(&window, rb->chunk_index, rs, window_pool,
+                                iterpool));
 
       APR_ARRAY_PUSH(windows, svn_txdelta_window_t *) = window;
       if (window->src_ops == 0)
@@ -1567,6 +1616,8 @@ get_combined_window(svn_stringbuf_t **re
     {
       svn_txdelta_window_t *window;
 
+      svn_pool_clear(iterpool);
+
       rs = APR_ARRAY_IDX(rb->rs_list, i, rep_state_t *);
       window = APR_ARRAY_IDX(windows, i, svn_txdelta_window_t *);
 
@@ -1577,7 +1628,7 @@ get_combined_window(svn_stringbuf_t **re
       source = buf;
       if (source == NULL && rb->src_state != NULL)
         SVN_ERR(read_plain_window(&source, rb->src_state, window->sview_len,
-                                  pool));
+                                  pool, iterpool));
 
       /* Combine this window with the current one. */
       new_pool = svn_pool_create(rb->pool);
@@ -1604,6 +1655,7 @@ get_combined_window(svn_stringbuf_t **re
       svn_pool_destroy(pool);
       pool = new_pool;
     }
+  svn_pool_destroy(iterpool);
 
   svn_pool_destroy(window_pool);
 
@@ -2132,14 +2184,18 @@ delta_read_next_window(svn_txdelta_windo
                        apr_pool_t *pool)
 {
   struct delta_read_baton *drb = baton;
+  apr_pool_t *scratch_pool = svn_pool_create(pool);
 
   *window = NULL;
   if (drb->rs->current < drb->rs->size)
     {
-      SVN_ERR(read_delta_window(window, drb->rs->chunk_index, drb->rs, pool));
+      SVN_ERR(read_delta_window(window, drb->rs->chunk_index, drb->rs, pool,
+                                scratch_pool));
       drb->rs->chunk_index++;
     }
 
+  svn_pool_destroy(scratch_pool);
+
   return SVN_NO_ERROR;
 }
 
@@ -2187,7 +2243,7 @@ svn_fs_fs__get_file_delta_stream(svn_txd
     {
       /* Read target's base rep if any. */
       SVN_ERR(create_rep_state(&rep_state, &rep_header, NULL,
-                                target->data_rep, fs, pool));
+                                target->data_rep, fs, pool, pool));
 
       if (source && source->data_rep && target->data_rep)
         {
@@ -2354,7 +2410,7 @@ read_dir_entries(apr_array_header_t *ent
                            _("Directory entry corrupt in '%s'"),
                            svn_fs_fs__id_unparse(id, scratch_pool)->data);
 
-      dirent->id = svn_fs_fs__id_parse(str, strlen(str), result_pool);
+      dirent->id = svn_fs_fs__id_parse(str, result_pool);
 
       /* In incremental mode, update the hash; otherwise, write to the
        * final array.  Be sure to use hash keys that survive this iteration.
@@ -2411,11 +2467,9 @@ get_dir_contents(apr_array_header_t **en
     }
   else if (noderev->data_rep)
     {
-      /* use a temporary pool for temp objects.
-       * Also undeltify content before parsing it. Otherwise, we could only
+      /* Undeltify content before parsing it. Otherwise, we could only
        * parse it byte-by-byte.
        */
-      apr_pool_t *text_pool = svn_pool_create(scratch_pool);
       apr_size_t len = noderev->data_rep->expanded_size
                      ? (apr_size_t)noderev->data_rep->expanded_size
                      : (apr_size_t)noderev->data_rep->size;
@@ -2423,16 +2477,14 @@ get_dir_contents(apr_array_header_t **en
 
       /* The representation is immutable.  Read it normally. */
       SVN_ERR(svn_fs_fs__get_contents(&contents, fs, noderev->data_rep,
-                                      FALSE, text_pool));
-      SVN_ERR(svn_stringbuf_from_stream(&text, contents, len, text_pool));
+                                      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, text_pool);
+      contents = svn_stream_from_stringbuf(text, scratch_pool);
       SVN_ERR(read_dir_entries(*entries, contents, FALSE,  noderev->id,
                                result_pool, scratch_pool));
-
-      svn_pool_destroy(text_pool);
     }
 
   return SVN_NO_ERROR;
@@ -2637,19 +2689,20 @@ svn_error_t *
 svn_fs_fs__get_changes(apr_array_header_t **changes,
                        svn_fs_t *fs,
                        svn_revnum_t rev,
-                       apr_pool_t *pool)
+                       apr_pool_t *result_pool)
 {
   apr_off_t changes_offset = SVN_FS_FS__ITEM_INDEX_CHANGES;
   svn_fs_fs__revision_file_t *revision_file;
   svn_boolean_t found;
   fs_fs_data_t *ffd = fs->fsap_data;
+  apr_pool_t *scratch_pool = svn_pool_create(result_pool);
 
   /* try cache lookup first */
 
   if (ffd->changes_cache)
     {
       SVN_ERR(svn_cache__get((void **) changes, &found, ffd->changes_cache,
-                             &rev, pool));
+                             &rev, result_pool));
     }
   else
     {
@@ -2660,47 +2713,59 @@ svn_fs_fs__get_changes(apr_array_header_
     {
       /* read changes from revision file */
 
-      SVN_ERR(svn_fs_fs__ensure_revision_exists(rev, fs, pool));
+      SVN_ERR(svn_fs_fs__ensure_revision_exists(rev, fs, scratch_pool));
       SVN_ERR(svn_fs_fs__open_pack_or_rev_file(&revision_file, fs, rev,
-                                               pool));
+                                               scratch_pool));
 
       if (svn_fs_fs__use_log_addressing(fs, rev))
         {
           /* 'block-read' will also provide us with the desired data */
           SVN_ERR(block_read((void **)changes, fs,
                              rev, SVN_FS_FS__ITEM_INDEX_CHANGES,
-                             revision_file, pool, pool));
+                             revision_file, result_pool, scratch_pool));
         }
       else
         {
           /* physical addressing mode code path */
           SVN_ERR(get_root_changes_offset(NULL, &changes_offset,
                                           revision_file->file, fs, rev,
-                                          pool));
+                                          scratch_pool));
 
           SVN_ERR(aligned_seek(fs, revision_file->file, NULL, changes_offset,
-                               pool));
+                               scratch_pool));
           SVN_ERR(svn_fs_fs__read_changes(changes, revision_file->stream,
-                                          pool));
+                                          result_pool, scratch_pool));
 
           /* cache for future reference */
 
           if (ffd->changes_cache)
-            SVN_ERR(svn_cache__set(ffd->changes_cache, &rev, *changes, pool));
+            {
+              /* Guesstimate for the size of the in-cache representation. */
+              apr_size_t 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, &rev, *changes,
+                                       scratch_pool));
+            }
         }
 
       SVN_ERR(svn_fs_fs__close_revision_file(revision_file));
     }
 
   SVN_ERR(dbg_log_access(fs, rev, changes_offset, *changes,
-                         SVN_FS_FS__ITEM_TYPE_CHANGES, pool));
+                         SVN_FS_FS__ITEM_TYPE_CHANGES, scratch_pool));
 
+  svn_pool_destroy(scratch_pool);
   return SVN_NO_ERROR;
 }
 
 /* Inialize the representation read state RS for the given REP_HEADER and
  * p2l index ENTRY.  If not NULL, assign FILE and STREAM to RS.
- * Use POOL for allocations.
+ * Use RESULT_POOL for allocations.
  */
 static svn_error_t *
 init_rep_state(rep_state_t *rs,
@@ -2708,10 +2773,10 @@ init_rep_state(rep_state_t *rs,
                svn_fs_t *fs,
                svn_fs_fs__revision_file_t *file,
                svn_fs_fs__p2l_entry_t* entry,
-               apr_pool_t *pool)
+               apr_pool_t *result_pool)
 {
   fs_fs_data_t *ffd = fs->fsap_data;
-  shared_file_t *shared_file = apr_pcalloc(pool, sizeof(*shared_file));
+  shared_file_t *shared_file = apr_pcalloc(result_pool, sizeof(*shared_file));
 
   /* this function does not apply to representation containers */
   SVN_ERR_ASSERT(entry->type >= SVN_FS_FS__ITEM_TYPE_FILE_REP
@@ -2720,7 +2785,7 @@ init_rep_state(rep_state_t *rs,
   shared_file->rfile = file;
   shared_file->fs = fs;
   shared_file->revision = entry->item.revision;
-  shared_file->pool = pool;
+  shared_file->pool = result_pool;
 
   rs->sfile = shared_file;
   rs->revision = entry->item.revision;
@@ -2868,7 +2933,7 @@ cache_windows(svn_fs_t *fs,
 /* Read all txdelta / plain windows following REP_HEADER in FS as described
  * by ENTRY.  Read the data from the already open FILE and the wrapping
  * STREAM object.  If MAX_OFFSET is not -1, don't read windows that start
- * at or beyond that offset.  Use POOL for allocations.
+ * at or beyond that offset.  Use SCRATCH_POOL for temporary allocations.
  * If caching is not enabled, this is a no-op.
  */
 static svn_error_t *
@@ -2877,7 +2942,8 @@ block_read_windows(svn_fs_fs__rep_header
                    svn_fs_fs__revision_file_t *rev_file,
                    svn_fs_fs__p2l_entry_t* entry,
                    apr_off_t max_offset,
-                   apr_pool_t *pool)
+                   apr_pool_t *result_pool,
+                   apr_pool_t *scratch_pool)
 {
   fs_fs_data_t *ffd = fs->fsap_data;
   rep_state_t rs = { 0 };
@@ -2890,7 +2956,8 @@ block_read_windows(svn_fs_fs__rep_header
           && !ffd->combined_window_cache))
     return SVN_NO_ERROR;
 
-  SVN_ERR(init_rep_state(&rs, rep_header, fs, rev_file, entry, pool));
+  SVN_ERR(init_rep_state(&rs, rep_header, fs, rev_file, entry,
+                         result_pool));
   
   /* RS->FILE may be shared between RS instances -> make sure we point
    * to the right data. */
@@ -2902,26 +2969,28 @@ block_read_windows(svn_fs_fs__rep_header
 
       /* already in cache? */
       SVN_ERR(svn_cache__has_key(&is_cached, rs.combined_cache,
-                                 get_window_key(&key, &rs), pool));
+                                 get_window_key(&key, &rs),
+                                 scratch_pool));
       if (is_cached)
         return SVN_NO_ERROR;
 
       /* for larger reps, the header may have crossed a block boundary.
        * make sure we still read blocks properly aligned, i.e. don't use
        * plain seek here. */
-      SVN_ERR(aligned_seek(fs, rev_file->file, NULL, offset, pool));
+      SVN_ERR(aligned_seek(fs, rev_file->file, NULL, offset, scratch_pool));
 
-      plaintext = svn_stringbuf_create_ensure(rs.size, pool);
+      plaintext = svn_stringbuf_create_ensure(rs.size, result_pool);
       SVN_ERR(svn_io_file_read_full2(rev_file->file, plaintext->data,
-                                     rs.size, &plaintext->len, NULL, pool));
+                                     rs.size, &plaintext->len, NULL,
+                                     result_pool));
       plaintext->data[plaintext->len] = 0;
       rs.current += rs.size;
 
-      SVN_ERR(set_cached_combined_window(plaintext, &rs, pool));
+      SVN_ERR(set_cached_combined_window(plaintext, &rs, scratch_pool));
     }
   else
     {
-      SVN_ERR(cache_windows(fs, &rs, max_offset, pool));
+      SVN_ERR(cache_windows(fs, &rs, max_offset, scratch_pool));
     }
 
   return SVN_NO_ERROR;
@@ -2937,7 +3006,8 @@ read_rep_header(svn_fs_fs__rep_header_t 
                 svn_fs_t *fs,
                 svn_stream_t *stream,
                 pair_cache_key_t *key,
-                apr_pool_t *pool)
+                apr_pool_t *result_pool,
+                apr_pool_t *scratch_pool)
 {
   fs_fs_data_t *ffd = fs->fsap_data;
   svn_boolean_t is_cached = FALSE;
@@ -2945,15 +3015,18 @@ read_rep_header(svn_fs_fs__rep_header_t 
   if (ffd->rep_header_cache)
     {
       SVN_ERR(svn_cache__get((void**)rep_header, &is_cached,
-                             ffd->rep_header_cache, key, pool));
+                             ffd->rep_header_cache, key,
+                             result_pool));
       if (is_cached)
         return SVN_NO_ERROR;
     }
 
-  SVN_ERR(svn_fs_fs__read_rep_header(rep_header, stream, pool));
+  SVN_ERR(svn_fs_fs__read_rep_header(rep_header, stream, result_pool,
+                                     scratch_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,
+                           scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -2962,14 +3035,16 @@ read_rep_header(svn_fs_fs__rep_header_t 
  * addressed by ENTRY->ITEM in FS and cache it if caches are enabled.
  * Read the data from the already open FILE and the wrapping
  * STREAM object.  If MAX_OFFSET is not -1, don't read windows that start
- * at or beyond that offset.  Use POOL for allocations.
+ * at or beyond that offset.
+ * Use SCRATCH_POOL for temporary allocations.
  */
 static svn_error_t *
 block_read_contents(svn_fs_t *fs,
                     svn_fs_fs__revision_file_t *rev_file,
                     svn_fs_fs__p2l_entry_t* entry,
                     apr_off_t max_offset,
-                    apr_pool_t *pool)
+                    apr_pool_t *result_pool,
+                    apr_pool_t *scratch_pool)
 {
   pair_cache_key_t header_key = { 0 };
   svn_fs_fs__rep_header_t *rep_header;
@@ -2978,9 +3053,9 @@ block_read_contents(svn_fs_t *fs,
   header_key.second = entry->item.number;
 
   SVN_ERR(read_rep_header(&rep_header, fs, rev_file->stream, &header_key,
-                          pool));
+                          result_pool, scratch_pool));
   SVN_ERR(block_read_windows(rep_header, fs, rev_file, entry, max_offset,
-                             pool));
+                             result_pool, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -3033,7 +3108,8 @@ block_read_changes(apr_array_header_t **
                    svn_fs_fs__revision_file_t *rev_file,
                    svn_fs_fs__p2l_entry_t *entry,
                    svn_boolean_t must_read,
-                   apr_pool_t *pool)
+                   apr_pool_t *result_pool,
+                   apr_pool_t *scratch_pool)
 {
   fs_fs_data_t *ffd = fs->fsap_data;
   svn_stream_t *stream;
@@ -3045,22 +3121,25 @@ block_read_changes(apr_array_header_t **
     {
       svn_boolean_t is_cached;
       SVN_ERR(svn_cache__has_key(&is_cached, ffd->changes_cache,
-                                 &entry->item.revision, pool));
+                                 &entry->item.revision,
+                                 scratch_pool));
       if (is_cached)
         return SVN_NO_ERROR;
     }
 
-  SVN_ERR(auto_select_stream(&stream, fs, rev_file, entry, pool));
+  SVN_ERR(auto_select_stream(&stream, fs, rev_file, entry,
+                             scratch_pool));
 
   /* read changes from revision file */
 
-  SVN_ERR(svn_fs_fs__read_changes(changes, stream, pool));
+  SVN_ERR(svn_fs_fs__read_changes(changes, stream, result_pool,
+                                  scratch_pool));
 
   /* cache for future reference */
 
   if (ffd->changes_cache)
     SVN_ERR(svn_cache__set(ffd->changes_cache, &entry->item.revision,
-                           *changes, pool));
+                           *changes, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -3068,7 +3147,7 @@ block_read_changes(apr_array_header_t **
 /* If not already cached or if MUST_READ is set, read the nod revision
  * addressed by ENTRY in FS and retúrn it in *NODEREV_P.  Cache the
  * result if caching is enabled.  Read the data from the already open
- * FILE and wrapping FILE_STREAM.  Use POOL for allocations.
+ * FILE and wrapping FILE_STREAM. Use SCRATCH_POOL for temporary allocations.
  */
 static svn_error_t *
 block_read_noderev(node_revision_t **noderev_p,
@@ -3076,7 +3155,8 @@ block_read_noderev(node_revision_t **nod
                    svn_fs_fs__revision_file_t *rev_file,
                    svn_fs_fs__p2l_entry_t *entry,
                    svn_boolean_t must_read,
-                   apr_pool_t *pool)
+                   apr_pool_t *result_pool,
+                   apr_pool_t *scratch_pool)
 {
   fs_fs_data_t *ffd = fs->fsap_data;
   svn_stream_t *stream;
@@ -3093,23 +3173,25 @@ block_read_noderev(node_revision_t **nod
     {
       svn_boolean_t is_cached;
       SVN_ERR(svn_cache__has_key(&is_cached, ffd->node_revision_cache,
-                                 &key, pool));
+                                 &key, scratch_pool));
       if (is_cached)
         return SVN_NO_ERROR;
     }
 
-  SVN_ERR(auto_select_stream(&stream, fs, rev_file, entry, pool));
+  SVN_ERR(auto_select_stream(&stream, fs, rev_file, entry,
+                             scratch_pool));
 
   /* read node rev from revision file */
 
-  SVN_ERR(svn_fs_fs__read_noderev(noderev_p, stream, pool));
+  SVN_ERR(svn_fs_fs__read_noderev(noderev_p, stream,
+                                  result_pool, scratch_pool));
 
   /* Workaround issue #4031: is-fresh-txn-root in revision files. */
   (*noderev_p)->is_fresh_txn_root = FALSE;
 
   if (ffd->node_revision_cache)
     SVN_ERR(svn_cache__set(ffd->node_revision_cache, &key, *noderev_p,
-                           pool));
+                           scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -3138,7 +3220,14 @@ block_read(void **result,
   apr_array_header_t *entries;
   int run_count = 0;
   int i;
-  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+  apr_pool_t *iterpool;
+
+  /* Block read is an optional feature. If the caller does not want anything
+   * specific we may not have to read anything. */
+  if (!result && !ffd->use_block_read)
+    return SVN_NO_ERROR;
+
+  iterpool = svn_pool_create(scratch_pool);
 
   /* don't try this on transaction protorev files */
   SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(revision));
@@ -3160,37 +3249,12 @@ block_read(void **result,
    */
   do
     {
-      svn_error_t *err;
-
       /* fetch list of items in the block surrounding OFFSET */
       block_start = offset - (offset % ffd->block_size);
-      err = svn_fs_fs__p2l_index_lookup(&entries, fs, revision_file,
-                                        revision, block_start,
-                                        ffd->block_size, scratch_pool);
-
-      /* if the revision got packed in the meantime and we still need
-       * to actually read some item, we retry the whole process */
-      if (err)
-        {
-          /* We failed for the first time. Refresh cache & retry. */
-          SVN_ERR(svn_fs_fs__update_min_unpacked_rev(fs, scratch_pool));
-          if (   revision_file->is_packed
-              != svn_fs_fs__is_packed_rev(fs, revision))
-            {
-              if (result && !*result)
-                {
-                  SVN_ERR(svn_fs_fs__reopen_revision_file(revision_file, fs, 
-                                                          revision));
-                  SVN_ERR(block_read(result, fs, revision, item_index,
-                                     revision_file, result_pool,
-                                     scratch_pool));
-                }
+      SVN_ERR(svn_fs_fs__p2l_index_lookup(&entries, fs, revision_file,
+                                          revision, block_start,
+                                          ffd->block_size, scratch_pool));
 
-              return SVN_NO_ERROR;
-            }
-        }
-
-      SVN_ERR(err);
       SVN_ERR(aligned_seek(fs, revision_file->file, &block_start, offset,
                            iterpool));
 
@@ -3220,7 +3284,8 @@ block_read(void **result,
           /* handle all items that start within this block and are relatively
            * small (i.e. < block size).  Always read the item we need to return.
            */
-          if (is_result || (   entry->offset >= block_start
+          if (is_result || (   ffd->use_block_read
+                            && entry->offset >= block_start
                             && entry->size < ffd->block_size))
             {
               void *item = NULL;
@@ -3236,20 +3301,22 @@ block_read(void **result,
                                                 is_wanted
                                                   ? -1
                                                   : block_start + ffd->block_size,
-                                                pool));
+                                                pool, iterpool));
                     break;
 
                   case SVN_FS_FS__ITEM_TYPE_NODEREV:
                     if (ffd->node_revision_cache || is_result)
                       SVN_ERR(block_read_noderev((node_revision_t **)&item,
                                                  fs, revision_file,
-                                                 entry, is_result, pool));
+                                                 entry, is_result, pool,
+                                                 iterpool));
                     break;
 
                   case SVN_FS_FS__ITEM_TYPE_CHANGES:
                     SVN_ERR(block_read_changes((apr_array_header_t **)&item,
                                                fs, revision_file,
-                                               entry, is_result, pool));
+                                               entry, is_result,
+                                               pool, iterpool));
                     break;
 
                   default:

Modified: subversion/branches/svn-auth-x509/subversion/libsvn_fs_fs/cached_data.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/libsvn_fs_fs/cached_data.h?rev=1605201&r1=1605200&r2=1605201&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/libsvn_fs_fs/cached_data.h (original)
+++ subversion/branches/svn-auth-x509/subversion/libsvn_fs_fs/cached_data.h Tue Jun 24 21:29:59 2014
@@ -36,7 +36,8 @@ svn_error_t *
 svn_fs_fs__get_node_revision(node_revision_t **noderev_p,
                              svn_fs_t *fs,
                              const svn_fs_id_t *id,
-                             apr_pool_t *pool);
+                             apr_pool_t *result_pool,
+                             apr_pool_t *scratch_pool);
 
 /* Set *ROOT_ID to the node-id for the root of revision REV in
    filesystem FS.  Do any allocations in POOL. */
@@ -44,28 +45,29 @@ svn_error_t *
 svn_fs_fs__rev_get_root(svn_fs_id_t **root_id,
                         svn_fs_t *fs,
                         svn_revnum_t rev,
-                        apr_pool_t *pool);
+                        apr_pool_t *result_pool,
+                        apr_pool_t *scratch_pool);
 
 /* Verify that representation REP in FS can be accessed.  Successive calls
    to this function should pass a non-NULL value to HINT.  In that case,
    many file open / close operations can be eliminated.
-   Do any allocations in POOL. */
+   Do any allocations in SCRATCH_POOL. */
 svn_error_t *
 svn_fs_fs__check_rep(representation_t *rep,
                      svn_fs_t *fs,
                      void **hint,
-                     apr_pool_t *pool);
+                     apr_pool_t *scratch_pool);
 
 /* Follow the representation delta chain in FS starting with REP.  The
    number of reps (including REP) in the chain will be returned in
    *CHAIN_LENGTH.  *SHARD_COUNT will be set to the number of shards
-   accessed.  Do any allocations in POOL. */
+   accessed.  Do any allocations in SCRATCH_POOL. */
 svn_error_t *
 svn_fs_fs__rep_chain_length(int *chain_length,
                             int *shard_count,
                             representation_t *rep,
                             svn_fs_t *fs,
-                            apr_pool_t *pool);
+                            apr_pool_t *scratch_pool);
 
 /* Set *CONTENTS to be a readable svn_stream_t that receives the text
    representation REP as seen in filesystem FS.  If CACHE_FULLTEXT is

Modified: subversion/branches/svn-auth-x509/subversion/libsvn_fs_fs/dag.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/libsvn_fs_fs/dag.c?rev=1605201&r1=1605200&r2=1605201&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/libsvn_fs_fs/dag.c (original)
+++ subversion/branches/svn-auth-x509/subversion/libsvn_fs_fs/dag.c Tue Jun 24 21:29:59 2014
@@ -160,10 +160,13 @@ get_node_revision(node_revision_t **node
   if (! node->node_revision)
     {
       node_revision_t *noderev;
+      apr_pool_t *scratch_pool = svn_pool_create(node->node_pool);
 
       SVN_ERR(svn_fs_fs__get_node_revision(&noderev, node->fs,
-                                           node->id, node->node_pool));
+                                           node->id, node->node_pool,
+                                           scratch_pool));
       node->node_revision = noderev;
+      svn_pool_destroy(scratch_pool);
     }
 
   /* Now NODE->node_revision is set.  */
@@ -614,7 +617,7 @@ svn_fs_fs__dag_revision_root(dag_node_t 
   /* Construct the node. */
   new_node = apr_pcalloc(pool, sizeof(*new_node));
   new_node->fs = fs;
-  SVN_ERR(svn_fs_fs__rev_get_root(&new_node->id, fs, rev, pool));
+  SVN_ERR(svn_fs_fs__rev_get_root(&new_node->id, fs, rev, pool, pool));
 
   /* Grab the contents so we can inspect the node's kind and created path. */
   new_node->node_pool = pool;

Modified: subversion/branches/svn-auth-x509/subversion/libsvn_fs_fs/fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/libsvn_fs_fs/fs.h?rev=1605201&r1=1605200&r2=1605201&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/libsvn_fs_fs/fs.h (original)
+++ subversion/branches/svn-auth-x509/subversion/libsvn_fs_fs/fs.h Tue Jun 24 21:29:59 2014
@@ -303,7 +303,11 @@ typedef struct fs_fs_data_t
 
   /* Rev / pack file granularity covered by phys-to-log index pages */
   apr_int64_t p2l_page_size;
-  
+
+  /* If set, parse and cache *all* data of each block that we read
+   * (not just the one bit that we need, atm). */
+  svn_boolean_t use_block_read;
+
   /* The revision that was youngest, last time we checked. */
   svn_revnum_t youngest_rev_cache;
 

Modified: subversion/branches/svn-auth-x509/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/libsvn_fs_fs/fs_fs.c?rev=1605201&r1=1605200&r2=1605201&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/branches/svn-auth-x509/subversion/libsvn_fs_fs/fs_fs.c Tue Jun 24 21:29:59 2014
@@ -43,6 +43,7 @@
 
 #include "private/svn_fs_util.h"
 #include "private/svn_string_private.h"
+#include "private/svn_subr_private.h"
 #include "../libsvn_fs/fs-loader.h"
 
 /* The default maximum number of files per directory to store in the
@@ -722,7 +723,7 @@ read_config(fs_fs_data_t *ffd,
       SVN_ERR(svn_config_get_bool(config, &ffd->compress_packed_revprops,
                                   CONFIG_SECTION_PACKED_REVPROPS,
                                   CONFIG_OPTION_COMPRESS_PACKED_REVPROPS,
-                                  TRUE));
+                                  FALSE));
       SVN_ERR(svn_config_get_int64(config, &ffd->revprop_pack_size,
                                    CONFIG_SECTION_PACKED_REVPROPS,
                                    CONFIG_OPTION_REVPROP_PACK_SIZE,
@@ -927,15 +928,15 @@ write_config(svn_fs_t *fs,
 "### ineffective."                                                           NL
 "### revprop-pack-size is 64 kBytes by default for non-compressed revprop"   NL
 "### pack files and 256 kBytes when compression has been enabled."           NL
-"# " CONFIG_OPTION_REVPROP_PACK_SIZE " = 256"                                NL
+"# " CONFIG_OPTION_REVPROP_PACK_SIZE " = 64"                                 NL
 "###"                                                                        NL
 "### To save disk space, packed revprop files may be compressed.  Standard"  NL
 "### revprops tend to allow for very effective compression.  Reading and"    NL
 "### even more so writing, become significantly more CPU intensive.  With"   NL
 "### revprop caching enabled, the overhead can be offset by reduced I/O"     NL
 "### unless you often modify revprops after packing."                        NL
-"### Compressing packed revprops is enabled by default."                     NL
-"# " CONFIG_OPTION_COMPRESS_PACKED_REVPROPS " = true"                        NL
+"### Compressing packed revprops is disabled by default."                    NL
+"# " CONFIG_OPTION_COMPRESS_PACKED_REVPROPS " = false"                       NL
 ""                                                                           NL
 "[" CONFIG_SECTION_IO "]"                                                    NL
 "### Parameters in this section control the data access granularity in"      NL
@@ -993,6 +994,18 @@ write_config(svn_fs_t *fs,
                             fsfs_conf_contents, pool);
 }
 
+/* Read / Evaluate the global configuration in FS->CONFIG to set up
+ * parameters in FS. */
+static svn_error_t *
+read_global_config(svn_fs_t *fs)
+{
+  fs_fs_data_t *ffd = fs->fsap_data;
+  ffd->use_block_read 
+    = svn_hash__get_bool(fs->config, SVN_FS_CONFIG_FSFS_BLOCK_READ, TRUE);
+
+  return SVN_NO_ERROR;
+}
+
 svn_error_t *
 svn_fs_fs__open(svn_fs_t *fs, const char *path, apr_pool_t *pool)
 {
@@ -1031,6 +1044,9 @@ svn_fs_fs__open(svn_fs_t *fs, const char
   /* Read the configuration file. */
   SVN_ERR(read_config(ffd, fs->path, fs->pool, pool));
 
+  /* Global configuration options. */
+  SVN_ERR(read_global_config(fs));
+
   return get_youngest(&(ffd->youngest_rev_cache), path, pool);
 }
 
@@ -1449,15 +1465,35 @@ write_revision_zero(svn_fs_t *fs)
 
   /* Write out a rev file for revision 0. */
   if (svn_fs_fs__use_log_addressing(fs, 0))
-    SVN_ERR(svn_io_file_create(path_revision_zero,
-                               "PLAIN\nEND\nENDREP\n"
-                               "id: 0.0.r0/2\n"
-                               "type: dir\n"
-                               "count: 0\n"
-                               "text: 0 3 4 4 "
-                               "2d2977d1c96f487abe4a1e202dd03b4e\n"
-                               "cpath: /\n"
-                               "\n\n", fs->pool));
+    SVN_ERR(svn_io_file_create_binary(path_revision_zero,
+                  "PLAIN\nEND\nENDREP\n"
+                  "id: 0.0.r0/2\n"
+                  "type: dir\n"
+                  "count: 0\n"
+                  "text: 0 3 4 4 "
+                  "2d2977d1c96f487abe4a1e202dd03b4e\n"
+                  "cpath: /\n"
+                  "\n\n"
+
+                  /* L2P index */
+                  "\0\x80\x40"          /* rev 0, 8k entries per page */
+                  "\1\1\1"              /* 1 rev, 1 page, 1 page in 1st rev */
+                  "\6\4"                /* page size: bytes, count */
+                  "\0\xd6\1\xb1\1\x21"  /* phys offsets + 1 */
+
+                  /* P2L index */
+                  "\0\x6b"              /* start rev, rev file size */
+                  "\x80\x80\4\1\x1D"    /* 64k pages, 1 page using 29 bytes */
+                  "\0"                  /* offset entry 0 page 1 */
+                                        /* len, item & type, rev, checksum */
+                  "\x11\x34\0\xf5\xd6\x8c\x81\x06"
+                  "\x59\x09\0\xc8\xfc\xf6\x81\x04"
+                  "\1\x0d\0\x9d\x9e\xa9\x94\x0f" 
+                  "\x95\xff\3\x1b\0\0"  /* last entry fills up 64k page */
+
+                  /* Footer */
+                  "107 121\7",
+                  107 + 14 + 38 + 7 + 1, fs->pool));
   else
     SVN_ERR(svn_io_file_create(path_revision_zero,
                                "PLAIN\nEND\nENDREP\n"
@@ -1471,35 +1507,6 @@ write_revision_zero(svn_fs_t *fs)
 
   SVN_ERR(svn_io_set_file_read_only(path_revision_zero, FALSE, fs->pool));
 
-  if (svn_fs_fs__use_log_addressing(fs, 0))
-    {
-      const char *path = svn_fs_fs__path_l2p_index(fs, 0, FALSE, fs->pool);
-      SVN_ERR(svn_io_file_create_binary
-                 (path,
-                  "\0\x80\x40"       /* rev 0, 8k entries per page */
-                  "\1\1\1"           /* 1 rev, 1 page, 1 page in 1st rev */
-                  "\6\4"             /* page size: bytes, count */
-                  "\0\xd6\1\xb1\1\x21",  /* phys offsets + 1 */
-                  14,
-                  fs->pool));
-      SVN_ERR(svn_io_set_file_read_only(path, FALSE, fs->pool));
-
-      path = svn_fs_fs__path_p2l_index(fs, 0, FALSE, fs->pool);
-      SVN_ERR(svn_io_file_create_binary
-                 (path,
-                  "\0\x6b"              /* start rev, rev file size */
-                  "\x80\x80\4\1\x1D"    /* 64k pages, 1 page using 29 bytes */
-                  "\0"                  /* offset entry 0 page 1 */
-                                        /* len, item & type, rev, checksum */
-                  "\x11\x34\0\xf5\xd6\x8c\x81\x06"
-                  "\x59\x09\0\xc8\xfc\xf6\x81\x04"
-                  "\1\x0d\0\x9d\x9e\xa9\x94\x0f" 
-                  "\x95\xff\3\x1b\0\0", /* last entry fills up 64k page */
-                  38,
-                  fs->pool));
-      SVN_ERR(svn_io_set_file_read_only(path, FALSE, fs->pool));
-    }
-
   /* Set a date on revision 0. */
   date.data = svn_time_to_cstring(apr_time_now(), fs->pool);
   date.len = strlen(date.data);
@@ -1614,6 +1621,9 @@ svn_fs_fs__create(svn_fs_t *fs,
 
   SVN_ERR(read_config(ffd, fs->path, fs->pool, pool));
 
+  /* Global configuration options. */
+  SVN_ERR(read_global_config(fs));
+
   /* Create the min unpacked rev file. */
   if (ffd->format >= SVN_FS_FS__MIN_PACKED_FORMAT)
     SVN_ERR(svn_io_file_create(svn_fs_fs__path_min_unpacked_rev(fs, pool),
@@ -1737,8 +1747,9 @@ svn_fs_fs__get_node_origin(const svn_fs_
         = apr_hash_get(node_origins, node_id_ptr, len);
 
       if (origin_id_str)
-        *origin_id = svn_fs_fs__id_parse(origin_id_str->data,
-                                         origin_id_str->len, pool);
+        *origin_id = svn_fs_fs__id_parse(apr_pstrdup(pool,
+                                                     origin_id_str->data),
+                                         pool);
     }
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/svn-auth-x509/subversion/libsvn_fs_fs/hotcopy.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/libsvn_fs_fs/hotcopy.c?rev=1605201&r1=1605200&r2=1605201&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/libsvn_fs_fs/hotcopy.c (original)
+++ subversion/branches/svn-auth-x509/subversion/libsvn_fs_fs/hotcopy.c Tue Jun 24 21:29:59 2014
@@ -228,14 +228,12 @@ hotcopy_io_copy_dir_recursively(const ch
 
 /* Copy an un-packed revision or revprop file for revision REV from SRC_SUBDIR
  * to DST_SUBDIR. Assume a sharding layout based on MAX_FILES_PER_DIR.
- * If INCLUDE_INDEXES is set, copy rev index files as well.
  * Use SCRATCH_POOL for temporary allocations. */
 static svn_error_t *
 hotcopy_copy_shard_file(const char *src_subdir,
                         const char *dst_subdir,
                         svn_revnum_t rev,
                         int max_files_per_dir,
-                        svn_boolean_t include_indexes,
                         apr_pool_t *scratch_pool)
 {
   const char *src_subdir_shard = src_subdir,
@@ -260,18 +258,6 @@ hotcopy_copy_shard_file(const char *src_
                                    apr_psprintf(scratch_pool, "%ld", rev),
                                    scratch_pool));
 
-  if (include_indexes)
-    {
-      SVN_ERR(hotcopy_io_dir_file_copy(src_subdir_shard, dst_subdir_shard,
-                                       apr_psprintf(scratch_pool, "%ld.l2p",
-                                                    rev),
-                                       scratch_pool));
-      SVN_ERR(hotcopy_io_dir_file_copy(src_subdir_shard, dst_subdir_shard,
-                                       apr_psprintf(scratch_pool, "%ld.p2l",
-                                                    rev),
-                                       scratch_pool));
-    }
-
   return SVN_NO_ERROR;
 }
 
@@ -327,7 +313,7 @@ hotcopy_copy_packed_shard(svn_revnum_t *
 
           SVN_ERR(hotcopy_copy_shard_file(src_subdir, dst_subdir,
                                           revprop_rev, max_files_per_dir,
-                                          FALSE, iterpool));
+                                          iterpool));
         }
       svn_pool_destroy(iterpool);
     }
@@ -336,7 +322,7 @@ hotcopy_copy_packed_shard(svn_revnum_t *
       /* revprop for revision 0 will never be packed */
       if (rev == 0)
         SVN_ERR(hotcopy_copy_shard_file(src_subdir, dst_subdir,
-                                        0, max_files_per_dir, FALSE,
+                                        0, max_files_per_dir,
                                         scratch_pool));
 
       /* packed revprops folder */
@@ -717,7 +703,6 @@ hotcopy_revisions(svn_revnum_t *dst_youn
       /* Copy the rev file. */
       err = hotcopy_copy_shard_file(src_revs_dir, dst_revs_dir,
                                     rev, max_files_per_dir,
-                                    svn_fs_fs__use_log_addressing(src_fs, rev),
                                     iterpool);
       if (err)
         {
@@ -768,7 +753,7 @@ hotcopy_revisions(svn_revnum_t *dst_youn
       /* Copy the revprop file. */
       SVN_ERR(hotcopy_copy_shard_file(src_revprops_dir,
                                       dst_revprops_dir,
-                                      rev, max_files_per_dir, FALSE,
+                                      rev, max_files_per_dir, 
                                       iterpool));
 
       /* After completing a full shard, update 'current'. */

Modified: subversion/branches/svn-auth-x509/subversion/libsvn_fs_fs/id.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/libsvn_fs_fs/id.c?rev=1605201&r1=1605200&r2=1605201&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/libsvn_fs_fs/id.c (original)
+++ subversion/branches/svn-auth-x509/subversion/libsvn_fs_fs/id.c Tue Jun 24 21:29:59 2014
@@ -78,7 +78,10 @@ part_parse(svn_fs_fs__id_part_t *part,
       return *data == '\0';
     }
 
-  part->revision = SVN_STR_TO_REV(++data);
+  {
+    const char *end;
+    part->revision = svn__strtol(data+1, &end);
+  }
 
   return TRUE;
 }
@@ -90,8 +93,9 @@ static svn_boolean_t
 txn_id_parse(svn_fs_fs__id_part_t *txn_id,
              const char *data)
 {
-  txn_id->revision = SVN_STR_TO_REV(data);
-  data = strchr(data, '-');
+  const char *end;
+  txn_id->revision = svn__strtol(data, &end);
+  data = strchr(end, '-');
   if (data == NULL)
     return FALSE;
 
@@ -435,16 +439,11 @@ svn_fs_fs__id_copy(const svn_fs_id_t *so
 
 
 svn_fs_id_t *
-svn_fs_fs__id_parse(const char *data,
-                    apr_size_t len,
+svn_fs_fs__id_parse(char *data,
                     apr_pool_t *pool)
 {
   fs_fs__id_t *id;
-  char *data_copy, *str;
-
-  /* Dup the ID data into POOL.  Our returned ID will have references
-     into this memory. */
-  data_copy = apr_pstrmemdup(pool, data, len);
+  char *str;
 
   /* Alloc a new svn_fs_id_t structure. */
   id = apr_pcalloc(pool, sizeof(*id));
@@ -458,40 +457,41 @@ svn_fs_fs__id_parse(const char *data,
      string.*/
 
   /* Node Id */
-  str = svn_cstring_tokenize(".", &data_copy);
+  str = svn_cstring_tokenize(".", &data);
   if (str == NULL)
     return NULL;
   if (! part_parse(&id->private_id.node_id, str))
     return NULL;
 
   /* Copy Id */
-  str = svn_cstring_tokenize(".", &data_copy);
+  str = svn_cstring_tokenize(".", &data);
   if (str == NULL)
     return NULL;
   if (! part_parse(&id->private_id.copy_id, str))
     return NULL;
 
   /* Txn/Rev Id */
-  str = svn_cstring_tokenize(".", &data_copy);
+  str = svn_cstring_tokenize(".", &data);
   if (str == NULL)
     return NULL;
 
   if (str[0] == 'r')
     {
       apr_int64_t val;
+      const char *tmp;
       svn_error_t *err;
 
       /* This is a revision type ID */
       id->private_id.txn_id.revision = SVN_INVALID_REVNUM;
       id->private_id.txn_id.number = 0;
 
-      data_copy = str + 1;
-      str = svn_cstring_tokenize("/", &data_copy);
+      data = str + 1;
+      str = svn_cstring_tokenize("/", &data);
       if (str == NULL)
         return NULL;
-      id->private_id.rev_item.revision = SVN_STR_TO_REV(str);
+      id->private_id.rev_item.revision = svn__strtol(str, &tmp);
 
-      err = svn_cstring_atoi64(&val, data_copy);
+      err = svn_cstring_atoi64(&val, data);
       if (err)
         {
           svn_error_clear(err);

Modified: subversion/branches/svn-auth-x509/subversion/libsvn_fs_fs/id.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/libsvn_fs_fs/id.h?rev=1605201&r1=1605200&r2=1605201&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/libsvn_fs_fs/id.h (original)
+++ subversion/branches/svn-auth-x509/subversion/libsvn_fs_fs/id.h Tue Jun 24 21:29:59 2014
@@ -149,10 +149,9 @@ svn_fs_id_t *svn_fs_fs__id_rev_create(co
 svn_fs_id_t *svn_fs_fs__id_copy(const svn_fs_id_t *id,
                                 apr_pool_t *pool);
 
-/* Return an ID resulting from parsing the string DATA (with length
-   LEN), or NULL if DATA is an invalid ID string. */
-svn_fs_id_t *svn_fs_fs__id_parse(const char *data,
-                                 apr_size_t len,
+/* Return an ID resulting from parsing the string DATA, or NULL if DATA is
+   an invalid ID string. *DATA will be modified / invalidated by this call. */
+svn_fs_id_t *svn_fs_fs__id_parse(char *data,
                                  apr_pool_t *pool);
 
 

Modified: subversion/branches/svn-auth-x509/subversion/libsvn_fs_fs/index.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/libsvn_fs_fs/index.c?rev=1605201&r1=1605200&r2=1605201&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/libsvn_fs_fs/index.c (original)
+++ subversion/branches/svn-auth-x509/subversion/libsvn_fs_fs/index.c Tue Jun 24 21:29:59 2014
@@ -159,6 +159,15 @@ struct svn_fs_fs__packed_number_stream_t
   /* underlying data file containing the packed values */
   apr_file_t *file;
 
+  /* Offset within FILE at which the stream data starts
+   * (i.e. which offset will reported as offset 0 by packed_stream_offset). */
+  apr_off_t stream_start;
+
+  /* First offset within FILE after the stream data.
+   * Attempts to read beyond this will cause an "Unexpected End Of Stream"
+   * error. */
+  apr_off_t stream_end;
+
   /* number of used entries in BUFFER (starting at index 0) */
   apr_size_t used;
 
@@ -240,6 +249,10 @@ packed_stream_read(svn_fs_fs__packed_num
   if (block_left >= 10 && block_left < read)
     read = block_left;
 
+  /* Don't read beyond the end of the file section that belongs to this
+   * index / stream. */
+  read = MIN(read, stream->stream_end - stream->next_offset);
+
   err = apr_file_read(stream->file, buffer, &read);
   if (err && !APR_STATUS_IS_EOF(err))
     return stream_error_create(stream, err,
@@ -300,45 +313,33 @@ packed_stream_read(svn_fs_fs__packed_num
   return SVN_NO_ERROR;
 }
 
-/* Create and open a packed number stream reading from FILE_NAME and
- * return it in *STREAM.  Access the file in chunks of BLOCK_SIZE bytes.
- * Use POOL for allocations.
+/* Create and open a packed number stream reading from offsets START to
+ * END in FILE and return it in *STREAM.  Access the file in chunks of
+ * BLOCK_SIZE bytes.  Use POOL for allocations.
  */
 static svn_error_t *
 packed_stream_open(svn_fs_fs__packed_number_stream_t **stream,
-                   const char *file_name,
+                   apr_file_t *file,
+                   apr_off_t start,
+                   apr_off_t end,
                    apr_size_t block_size,
                    apr_pool_t *pool)
 {
   svn_fs_fs__packed_number_stream_t *result
     = apr_palloc(pool, sizeof(*result));
-  result->pool = svn_pool_create(pool);
 
-  SVN_ERR(svn_io_file_open(&result->file, file_name,
-                           APR_READ | APR_BUFFERED, APR_OS_DEFAULT,
-                           result->pool));
+  result->pool = pool;
+  result->file = file;
+  result->stream_start = start;
+  result->stream_end = end;
 
   result->used = 0;
   result->current = 0;
-  result->start_offset = 0;
-  result->next_offset = 0;
+  result->start_offset = result->stream_start;
+  result->next_offset = result->stream_start;
   result->block_size = block_size;
 
   *stream = result;
-  
-  return SVN_NO_ERROR;
-}
-
-/* Close STREAM which may be NULL.
- */
-svn_error_t *
-svn_fs_fs__packed_stream_close(svn_fs_fs__packed_number_stream_t *stream)
-{
-  if (stream)
-    {
-      SVN_ERR(svn_io_file_close(stream->file, stream->pool));
-      svn_pool_destroy(stream->pool);
-    }
 
   return SVN_NO_ERROR;
 }
@@ -363,20 +364,22 @@ packed_stream_get(apr_uint64_t *value,
   return SVN_NO_ERROR;
 }
 
-/* Navigate STREAM to packed file offset OFFSET.  There will be no checks
+/* Navigate STREAM to packed stream offset OFFSET.  There will be no checks
  * whether the given OFFSET is valid.
  */
 static void
 packed_stream_seek(svn_fs_fs__packed_number_stream_t *stream,
                    apr_off_t offset)
 {
+  apr_off_t file_offset = offset + stream->stream_start;
+
   if (   stream->used == 0
       || offset < stream->start_offset
       || offset >= stream->next_offset)
     {
       /* outside buffered data.  Next get() will read() from OFFSET. */
-      stream->start_offset = offset;
-      stream->next_offset = offset;
+      stream->start_offset = file_offset;
+      stream->next_offset = file_offset;
       stream->current = 0;
       stream->used = 0;
     }
@@ -387,22 +390,25 @@ packed_stream_seek(svn_fs_fs__packed_num
        * it for the desired position. */
       apr_size_t i;
       for (i = 0; i < stream->used; ++i)
-        if (stream->buffer[i].total_len > offset - stream->start_offset)
+        if (stream->buffer[i].total_len > file_offset - stream->start_offset)
           break;
 
       stream->current = i;
     }
 }
 
-/* Return the packed file offset of at which the next number in the stream
+/* Return the packed stream offset of at which the next number in the stream
  * can be found.
  */
 static apr_off_t
 packed_stream_offset(svn_fs_fs__packed_number_stream_t *stream)
 {
-  return stream->current == 0
+  apr_off_t file_offset
+       = stream->current == 0
        ? stream->start_offset
        : stream->buffer[stream->current-1].total_len + stream->start_offset;
+
+  return file_offset - stream->stream_start;
 }
 
 /* Encode VALUE as 7/8b into P and return the number of bytes written.
@@ -537,25 +543,9 @@ svn_fs_fs__l2p_proto_index_add_entry(apr
                                                     pool));
 }
 
-static svn_error_t *
-index_create(apr_file_t **index_file, const char *file_name, apr_pool_t *pool)
-{
-  /* remove any old index file
-   * (it would probably be r/o and simply re-writing it would fail) */
-  SVN_ERR(svn_io_remove_file2(file_name, TRUE, pool));
-
-  /* We most likely own the write lock to the repo, so this should
-   * either just work or fail indicating a serious problem. */
-  SVN_ERR(svn_io_file_open(index_file, file_name,
-                           APR_WRITE | APR_CREATE | APR_BUFFERED,
-                           APR_OS_DEFAULT, pool));
-
-  return SVN_NO_ERROR;
-}
-
 svn_error_t *
-svn_fs_fs__l2p_index_create(svn_fs_t *fs,
-                            const char *file_name,
+svn_fs_fs__l2p_index_append(svn_fs_t *fs,
+                            apr_file_t *index_file,
                             const char *proto_file_name,
                             svn_revnum_t revision,
                             apr_pool_t *pool)
@@ -565,7 +555,6 @@ svn_fs_fs__l2p_index_create(svn_fs_t *fs
   int i;
   apr_uint64_t entry;
   svn_boolean_t eof = FALSE;
-  apr_file_t *index_file;
   unsigned char encoded[ENCODED_INT_LENGTH];
 
   int last_page_count = 0;          /* total page count at the start of
@@ -672,9 +661,6 @@ svn_fs_fs__l2p_index_create(svn_fs_t *fs
   /* close the source file */
   SVN_ERR(svn_io_file_close(proto_index, local_pool));
 
-  /* create the target file */
-  SVN_ERR(index_create(&index_file, file_name, local_pool));
-
   /* Paranoia check that makes later casting to int32 safe.
    * The current implementation is limited to 2G pages per index. */
   if (page_counts->nelts > APR_INT32_MAX)
@@ -725,45 +711,13 @@ svn_fs_fs__l2p_index_create(svn_fs_t *fs
                                                     local_pool),
                            NULL, NULL, local_pool));
 
-  /* finalize the index file */
-  SVN_ERR(svn_io_file_close(index_file, local_pool));
-  SVN_ERR(svn_io_set_file_read_only(file_name, FALSE, local_pool));
-
   svn_pool_destroy(local_pool);
 
   return SVN_NO_ERROR;
 }
 
-/* Reopen the rev / pack file in REV_FILE and attempt to open the L2P
- * index for REVISION in FS.
- */
-static svn_error_t *
-retry_open_l2p_index(svn_fs_fs__revision_file_t *rev_file,
-                     svn_fs_t *fs,
-                     svn_revnum_t revision)
-{
-  fs_fs_data_t *ffd = fs->fsap_data;
-
-  /* reopen rep file if necessary */
-  if (rev_file->file)
-    SVN_ERR(svn_fs_fs__reopen_revision_file(rev_file, fs, revision));
-  else
-    rev_file->is_packed = svn_fs_fs__is_packed_rev(fs, revision);
-
-  /* re-try opening this index (keep the p2l closed) */
-  SVN_ERR(packed_stream_open(&rev_file->l2p_stream,
-                             svn_fs_fs__path_l2p_index(fs, revision,
-                                                       rev_file->is_packed,
-                                                       rev_file->pool),
-                             ffd->block_size,
-                             rev_file->pool));
-
-  return SVN_NO_ERROR;
-}
-
 /* If REV_FILE->L2P_STREAM is NULL, create a new stream for the log-to-phys
- * index for REVISION in FS and return it in REV_FILE.  May fail if pack
- * status changed.
+ * index for REVISION in FS and return it in REV_FILE.
  */
 static svn_error_t *
 auto_open_l2p_index(svn_fs_fs__revision_file_t *rev_file,
@@ -773,10 +727,12 @@ auto_open_l2p_index(svn_fs_fs__revision_
   if (rev_file->l2p_stream == NULL)
     {
       fs_fs_data_t *ffd = fs->fsap_data;
+
+      SVN_ERR(svn_fs_fs__auto_read_footer(rev_file));
       SVN_ERR(packed_stream_open(&rev_file->l2p_stream,
-                                 svn_fs_fs__path_l2p_index(fs, revision,
-                                                           rev_file->is_packed,
-                                                           rev_file->pool),
+                                 rev_file->file,
+                                 rev_file->l2p_offset,
+                                 rev_file->p2l_offset,
                                  ffd->block_size,
                                  rev_file->pool));
     }
@@ -1471,13 +1427,14 @@ svn_fs_fs__l2p_get_max_ids(apr_array_hea
   l2p_header_t *header = NULL;
   svn_revnum_t revision;
   svn_revnum_t last_rev = (svn_revnum_t)(start_rev + count);
-  svn_fs_fs__revision_file_t rev_file;
+  svn_fs_fs__revision_file_t *rev_file;
   apr_pool_t *header_pool = svn_pool_create(pool);
 
   /* read index master data structure for the index covering START_REV */
-  svn_fs_fs__init_revision_file(&rev_file, fs, start_rev, header_pool);
-  SVN_ERR(get_l2p_header(&header, &rev_file, fs, start_rev, header_pool));
-  SVN_ERR(svn_fs_fs__close_revision_file(&rev_file));
+  SVN_ERR(svn_fs_fs__open_pack_or_rev_file(&rev_file, fs, start_rev,
+                                           header_pool));
+  SVN_ERR(get_l2p_header(&header, rev_file, fs, start_rev, header_pool));
+  SVN_ERR(svn_fs_fs__close_revision_file(rev_file));
 
   /* Determine the length of the item index list for each rev.
    * Read new index headers as required. */
@@ -1495,10 +1452,11 @@ svn_fs_fs__l2p_get_max_ids(apr_array_hea
            * the number of items in a revision, i.e. there is no consistency
            * issue here. */
           svn_pool_clear(header_pool);
-          rev_file.start_revision = revision;
-          SVN_ERR(get_l2p_header(&header, &rev_file, fs, revision,
+          SVN_ERR(svn_fs_fs__open_pack_or_rev_file(&rev_file, fs, revision,
+                                                  header_pool));
+          SVN_ERR(get_l2p_header(&header, rev_file, fs, revision,
                                  header_pool));
-          SVN_ERR(svn_fs_fs__close_revision_file(&rev_file));
+          SVN_ERR(svn_fs_fs__close_revision_file(rev_file));
         }
 
       /* in a revision with N index pages, the first N-1 index pages are
@@ -1546,26 +1504,8 @@ svn_fs_fs__item_offset(apr_off_t *absolu
   else if (svn_fs_fs__use_log_addressing(fs, revision))
     {
       /* ordinary index lookup */
-      err = l2p_index_lookup(absolute_position, fs, rev_file, revision,
-                             item_index, pool);
-
-      if (err && !rev_file->is_packed)
-        {
-          /* REVISION might have been packed in the meantime.
-             Refresh cache & retry. */
-          err = svn_error_compose_create(err,
-                                         svn_fs_fs__update_min_unpacked_rev
-                                            (fs, pool));
-
-          /* retry upon intermittent pack */
-          if (svn_fs_fs__is_packed_rev(fs, revision) != rev_file->is_packed)
-            {
-              svn_error_clear(err);
-              SVN_ERR(retry_open_l2p_index(rev_file, fs, revision));
-              err = l2p_index_lookup(absolute_position, fs, rev_file,
-                                     revision, item_index, pool);
-            }
-        }
+      SVN_ERR(l2p_index_lookup(absolute_position, fs, rev_file, revision,
+                               item_index, pool));
     }
   else if (rev_file->is_packed)
     {
@@ -1645,8 +1585,8 @@ svn_fs_fs__p2l_proto_index_next_offset(a
 }
 
 svn_error_t *
-svn_fs_fs__p2l_index_create(svn_fs_t *fs,
-                            const char *file_name,
+svn_fs_fs__p2l_index_append(svn_fs_t *fs,
+                            apr_file_t *index_file,
                             const char *proto_file_name,
                             svn_revnum_t revision,
                             apr_pool_t *pool)
@@ -1656,7 +1596,6 @@ svn_fs_fs__p2l_index_create(svn_fs_t *fs
   apr_file_t *proto_index = NULL;
   int i;
   svn_boolean_t eof = FALSE;
-  apr_file_t *index_file;
   unsigned char encoded[ENCODED_INT_LENGTH];
   svn_revnum_t last_revision = revision;
   apr_uint64_t last_compound = 0;
@@ -1777,9 +1716,6 @@ svn_fs_fs__p2l_index_create(svn_fs_t *fs
   APR_ARRAY_PUSH(table_sizes, apr_uint64_t)
       = svn_spillbuf__get_size(buffer) - last_buffer_size;
 
-  /* create the target file */
-  SVN_ERR(index_create(&index_file, file_name, local_pool));
-
   /* write the start revision, file size and page size */
   SVN_ERR(svn_io_file_write_full(index_file, encoded,
                                  encode_uint(encoded, revision),
@@ -1809,44 +1745,14 @@ svn_fs_fs__p2l_index_create(svn_fs_t *fs
                                                     local_pool),
                            NULL, NULL, local_pool));
 
-  /* finalize the index file */
-  SVN_ERR(svn_io_file_close(index_file, local_pool));
-  SVN_ERR(svn_io_set_file_read_only(file_name, FALSE, local_pool));
-
   svn_pool_destroy(iter_pool);
   svn_pool_destroy(local_pool);
 
   return SVN_NO_ERROR;
 }
 
-/* Reopen the rev / pack file in REV_FILE (if previously opened) using
- * the current pack status of REVISION in FS and open the suitable
- * P2L index.  Close the L2P index.
- */
-static svn_error_t *
-retry_open_p2l_index(svn_fs_fs__revision_file_t *rev_file,
-                     svn_fs_t *fs,
-                     svn_revnum_t revision)
-{
-  fs_fs_data_t *ffd = fs->fsap_data;
-
-  /* reopen rep file if necessary */
-  if (rev_file->file)
-    SVN_ERR(svn_fs_fs__reopen_revision_file(rev_file, fs, revision));
-
-  /* re-try opening this index (keep the l2p closed) */
-  SVN_ERR(packed_stream_open(&rev_file->p2l_stream,
-                             svn_fs_fs__path_p2l_index(fs, revision,
-                                                       rev_file->is_packed,
-                                                       rev_file->pool),
-                             ffd->block_size,
-                             rev_file->pool));
-
-  return SVN_NO_ERROR;
-}
-
 /* If REV_FILE->P2L_STREAM is NULL, create a new stream for the phys-to-log
- * index for REVISION in FS using the rev / pack status provided by REV_FILE.
+ * index for REVISION in FS using the rev / pack file provided by REV_FILE.
  */
 static svn_error_t *
 auto_open_p2l_index(svn_fs_fs__revision_file_t *rev_file,
@@ -1856,10 +1762,12 @@ auto_open_p2l_index(svn_fs_fs__revision_
   if (rev_file->p2l_stream == NULL)
     {
       fs_fs_data_t *ffd = fs->fsap_data;
+
+      SVN_ERR(svn_fs_fs__auto_read_footer(rev_file));
       SVN_ERR(packed_stream_open(&rev_file->p2l_stream,
-                                 svn_fs_fs__path_p2l_index(fs, revision,
-                                                           rev_file->is_packed,
-                                                           rev_file->pool),
+                                 rev_file->file,
+                                 rev_file->p2l_offset,
+                                 rev_file->footer_offset,
                                  ffd->block_size, rev_file->pool));
     }
 
@@ -2699,17 +2607,8 @@ svn_fs_fs__p2l_get_max_offset(apr_off_t 
                               svn_revnum_t revision,
                               apr_pool_t *pool)
 {
-  svn_error_t *err = p2l_get_max_offset(offset, fs, rev_file, revision, pool);
-
-  /* retry upon intermittent pack */
-  if (err && svn_fs_fs__is_packed_rev(fs, revision) != rev_file->is_packed)
-    {
-      svn_error_clear(err);
-      SVN_ERR(retry_open_p2l_index(rev_file, fs, revision));
-      err = p2l_get_max_offset(offset, fs, rev_file, revision, pool);
-    }
-
-  return svn_error_trace(err);
+  return svn_error_trace(p2l_get_max_offset(offset, fs, rev_file, revision,
+                                            pool));
 }
 
 /*