Modified: subversion/branches/ra-git/subversion/libsvn_fs_x/batch_fsync.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_x/batch_fsync.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_x/batch_fsync.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_x/batch_fsync.c Tue Oct 11 
09:11:50 2016
@@ -203,6 +203,9 @@ struct svn_fs_x__batch_fsync_t
 
   /* Counts the number of completed fsync tasks. */
   waitable_counter_t *counter;
+
+  /* Perform fsyncs only if this flag has been set. */
+  svn_boolean_t flush_to_disk;
 };
 
 /* Data structures for concurrent fsync execution are only available if
@@ -299,10 +302,12 @@ fsync_batch_cleanup(void *data)
 
 svn_error_t *
 svn_fs_x__batch_fsync_create(svn_fs_x__batch_fsync_t **result_p,
+                             svn_boolean_t flush_to_disk,
                              apr_pool_t *result_pool)
 {
   svn_fs_x__batch_fsync_t *result = apr_pcalloc(result_pool, sizeof(*result));
   result->files = svn_hash__make(result_pool);
+  result->flush_to_disk = flush_to_disk;
 
   SVN_ERR(waitable_counter__create(&result->counter, result_pool));
   apr_pool_cleanup_register(result_pool, result, fsync_batch_cleanup,
@@ -493,33 +498,38 @@ svn_fs_x__batch_fsync_run(svn_fs_x__batc
                                    waitable_counter__reset(batch->counter));
 
   /* Start the actual fsyncing process. */
-  for (hi = apr_hash_first(scratch_pool, batch->files);
-       hi;
-       hi = apr_hash_next(hi))
+  if (batch->flush_to_disk)
     {
-      to_sync_t *to_sync = apr_hash_this_val(hi);
+      for (hi = apr_hash_first(scratch_pool, batch->files);
+           hi;
+           hi = apr_hash_next(hi))
+        {
+          to_sync_t *to_sync = apr_hash_this_val(hi);
 
 #if APR_HAS_THREADS
 
-      /* If there are multiple fsyncs to perform, run them in parallel.
-       * Otherwise, skip the thread-pool and synchronization overhead. */
-      if (apr_hash_count(batch->files) > 1)
-        {
-          apr_status_t status = APR_SUCCESS;
-          status = apr_thread_pool_push(thread_pool, flush_task, to_sync,
-                                        0, NULL);
-          if (status)
-            to_sync->result = svn_error_wrap_apr(status, _("Can't push task"));
+          /* If there are multiple fsyncs to perform, run them in parallel.
+           * Otherwise, skip the thread-pool and synchronization overhead. */
+          if (apr_hash_count(batch->files) > 1)
+            {
+              apr_status_t status = APR_SUCCESS;
+              status = apr_thread_pool_push(thread_pool, flush_task, to_sync,
+                                            0, NULL);
+              if (status)
+                to_sync->result = svn_error_wrap_apr(status,
+                                                     _("Can't push task"));
+              else
+                tasks++;
+            }
           else
-            tasks++;
-        }
-      else
 
 #endif
 
-        {
-          to_sync->result = svn_error_trace(svn_io_file_flush_to_disk
-                                              (to_sync->file, to_sync->pool));
+            {
+              to_sync->result = svn_error_trace(svn_io_file_flush_to_disk
+                                                  (to_sync->file,
+                                                   to_sync->pool));
+            }
         }
     }
 
@@ -534,7 +544,9 @@ svn_fs_x__batch_fsync_run(svn_fs_x__batc
        hi = apr_hash_next(hi))
     {
       to_sync_t *to_sync = apr_hash_this_val(hi);
-      chain = svn_error_compose_create(chain, to_sync->result);
+      if (batch->flush_to_disk)
+        chain = svn_error_compose_create(chain, to_sync->result);
+
       chain = svn_error_compose_create(chain,
                                        svn_io_file_close(to_sync->file,
                                                          scratch_pool));

Modified: subversion/branches/ra-git/subversion/libsvn_fs_x/batch_fsync.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_x/batch_fsync.h?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_x/batch_fsync.h (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_x/batch_fsync.h Tue Oct 11 
09:11:50 2016
@@ -52,9 +52,12 @@ typedef struct svn_fs_x__batch_fsync_t s
 svn_error_t *
 svn_fs_x__batch_fsync_init(void);
 
-/* Set *RESULT_P to a new batch fsync structure, allocated in RESULT_POOL. */
+/* Set *RESULT_P to a new batch fsync structure, allocated in RESULT_POOL.
+ * If FLUSH_TO_DISK is not set, the resulting struct will not actually use
+ * fsync. */
 svn_error_t *
 svn_fs_x__batch_fsync_create(svn_fs_x__batch_fsync_t **result_p,
+                             svn_boolean_t flush_to_disk,
                              apr_pool_t *result_pool);
 
 /* Open the file at FILENAME for read and write access.  Return it in *FILE

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=1764214&r1=1764213&r2=1764214&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 Tue Oct 11 
09:11:50 2016
@@ -55,6 +55,7 @@ block_read(void **result,
            svn_fs_t *fs,
            const svn_fs_x__id_t *id,
            svn_fs_x__revision_file_t *revision_file,
+           void *baton,
            apr_pool_t *result_pool,
            apr_pool_t *scratch_pool);
 
@@ -352,6 +353,7 @@ get_node_revision_body(svn_fs_x__noderev
       SVN_ERR(block_read((void **)noderev_p, fs,
                          id,
                          revision_file,
+                         NULL,
                          result_pool,
                          scratch_pool));
       SVN_ERR(svn_fs_x__close_revision_file(revision_file));
@@ -698,7 +700,7 @@ create_rep_state_body(rep_state_t **rep_
       /* populate the cache if appropriate */
       if (SVN_IS_VALID_REVNUM(revision))
         {
-          SVN_ERR(block_read(NULL, fs, &rs->rep_id, rs->sfile->rfile,
+          SVN_ERR(block_read(NULL, fs, &rs->rep_id, rs->sfile->rfile, NULL,
                              result_pool, scratch_pool));
           SVN_ERR(svn_cache__set(ffd->rep_header_cache, &key, rh,
                                  scratch_pool));
@@ -1310,7 +1312,7 @@ 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, file,
+      SVN_ERR(block_read(NULL, rs->sfile->fs, &rs->rep_id, file, NULL,
                          result_pool, scratch_pool));
 
       /* reading the whole block probably also provided us with the
@@ -1341,7 +1343,7 @@ read_delta_window(svn_txdelta_window_t *
       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, apr_file, iterpool));
+      SVN_ERR(svn_io_file_get_offset(&start_offset, apr_file, iterpool));
 
       rs->current = start_offset - rs->start;
       if (rs->current >= rs->size)
@@ -1405,7 +1407,8 @@ read_container_window(svn_stringbuf_t **
     {
       SVN_ERR(auto_open_shared_file(rs->sfile));
       SVN_ERR(block_read((void **)&extractor, fs, &rs->rep_id,
-                         rs->sfile->rfile, result_pool, scratch_pool));
+                         rs->sfile->rfile, NULL,
+                         result_pool, scratch_pool));
     }
 
   SVN_ERR(svn_fs_x__extractor_drive(nwin, extractor, rs->current, size,
@@ -2646,8 +2649,13 @@ svn_fs_x__rep_contents_dir(apr_array_hea
   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. */
-  SVN_ERR(svn_cache__set(cache, &key, dir, scratch_pool));
+  /* Update the cache, if we are to use one.
+   *
+   * Don't even attempt to serialize very large directories; it would cause
+   * an unnecessary memory allocation peak.  100 bytes/entry is about right.
+   */
+  if (svn_cache__is_cachable(cache, 100 * dir->entries->nelts))
+    SVN_ERR(svn_cache__set(cache, &key, dir, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -2699,7 +2707,7 @@ svn_fs_x__rep_contents_dir_entry(svn_fs_
     *hint = baton.hint;
 
   /* fetch data from disk if we did not find it in the cache */
-  if (! found)
+  if (! found || baton.out_of_date)
     {
       svn_fs_x__dirent_t *entry;
       svn_fs_x__dirent_t *entry_copy = NULL;
@@ -2709,8 +2717,12 @@ svn_fs_x__rep_contents_dir_entry(svn_fs_
       SVN_ERR(get_dir_contents(&dir, fs, noderev, scratch_pool,
                                scratch_pool));
 
-      /* Update the cache, if we are to use one. */
-      if (cache)
+      /* Update the cache, if we are to use one.
+       *
+       * Don't even attempt to serialize very large directories; it would
+       * cause an unnecessary memory allocation peak.  150 bytes / entry is
+       * about right. */
+      if (cache && svn_cache__is_cachable(cache, 150 * dir.entries->nelts))
         SVN_ERR(svn_cache__set(cache, &key, &dir, scratch_pool));
 
       /* find desired entry and return a copy in POOL, if found */
@@ -2792,72 +2804,104 @@ svn_fs_x__get_proplist(apr_hash_t **prop
   return SVN_NO_ERROR;
 }
 
+svn_error_t *
+svn_fs_x__create_changes_context(svn_fs_x__changes_context_t **context,
+                                 svn_fs_t *fs,
+                                 svn_revnum_t rev,
+                                 apr_pool_t *result_pool,
+                                 apr_pool_t *scratch_pool)
+{
+  svn_fs_x__changes_context_t *result = apr_pcalloc(result_pool,
+                                                    sizeof(*result));
+  result->fs = fs;
+  result->revision = rev;
+
+  SVN_ERR(svn_fs_x__ensure_revision_exists(rev, fs, scratch_pool));
+  SVN_ERR(svn_fs_x__rev_file_init(&result->revision_file, fs, rev,
+                                  result_pool));
 
+  *context = result;
+  return SVN_NO_ERROR;
+}
 
 svn_error_t *
 svn_fs_x__get_changes(apr_array_header_t **changes,
-                      svn_fs_t *fs,
-                      svn_revnum_t rev,
-                      apr_pool_t *result_pool)
+                      svn_fs_x__changes_context_t *context,
+                      apr_pool_t *result_pool,
+                      apr_pool_t *scratch_pool)
 {
-  svn_fs_x__revision_file_t *revision_file;
   svn_boolean_t found;
-  svn_fs_x__data_t *ffd = fs->fsap_data;
-  apr_pool_t *scratch_pool = svn_pool_create(result_pool);
+  svn_fs_x__data_t *ffd = context->fs->fsap_data;
 
   svn_fs_x__id_t id;
-  id.change_set = svn_fs_x__change_set_by_rev(rev);
+  id.change_set = svn_fs_x__change_set_by_rev(context->revision);
   id.number = SVN_FS_X__ITEM_INDEX_CHANGES;
 
-  /* Provide revision file. */
-
-  SVN_ERR(svn_fs_x__ensure_revision_exists(rev, fs, scratch_pool));
-  SVN_ERR(svn_fs_x__rev_file_init(&revision_file, fs, rev, scratch_pool));
-
   /* try cache lookup first */
 
-  if (svn_fs_x__is_packed_rev(fs, rev))
+  if (svn_fs_x__is_packed_rev(context->fs, context->revision))
     {
       apr_off_t offset;
-      apr_uint32_t sub_item;
       svn_fs_x__pair_cache_key_t key;
+      svn_fs_x__changes_get_list_baton_t baton;
+      baton.start = (int)context->next;
+      baton.eol = &context->eol;
 
-      SVN_ERR(svn_fs_x__item_offset(&offset, &sub_item, fs, revision_file,
+      SVN_ERR(svn_fs_x__item_offset(&offset, &baton.sub_item, context->fs,
+                                    context->revision_file,
                                     &id, scratch_pool));
-      key.revision = svn_fs_x__packed_base_rev(fs, rev);
+      key.revision = svn_fs_x__packed_base_rev(context->fs,
+                                               context->revision);
       key.second = offset;
 
       SVN_ERR(svn_cache__get_partial((void **)changes, &found,
                                      ffd->changes_container_cache, &key,
                                      svn_fs_x__changes_get_list_func,
-                                     &sub_item, result_pool));
+                                     &baton, result_pool));
     }
   else
     {
-      SVN_ERR(svn_cache__get((void **) changes, &found, ffd->changes_cache,
-                             &rev, result_pool));
+      svn_fs_x__changes_list_t *changes_list;
+      svn_fs_x__pair_cache_key_t key;
+      key.revision = context->revision;
+      key.second = context->next;
+
+      SVN_ERR(svn_cache__get((void **)&changes_list, &found,
+                             ffd->changes_cache, &key, result_pool));
+
+      if (found)
+        {
+          /* Where to look next - if there is more data. */
+          context->eol = changes_list->eol;
+          context->next_offset = changes_list->end_offset;
+
+          /* Return the block as a "proper" APR array. */
+          (*changes) = apr_array_make(result_pool, 0, sizeof(void *));
+          (*changes)->elts = (char *)changes_list->changes;
+          (*changes)->nelts = changes_list->count;
+          (*changes)->nalloc = changes_list->count;
+        }
     }
 
   if (!found)
     {
       /* 'block-read' will also provide us with the desired data */
-      SVN_ERR(block_read((void **)changes, fs, &id, revision_file,
+      SVN_ERR(block_read((void **)changes, context->fs, &id,
+                         context->revision_file, context,
                          result_pool, scratch_pool));
-
-      SVN_ERR(svn_fs_x__close_revision_file(revision_file));
     }
 
-  SVN_ERR(dgb__log_access(fs, &id, *changes, SVN_FS_X__ITEM_TYPE_CHANGES,
-                          scratch_pool));
+  context->next += (*changes)->nelts;
+
+  SVN_ERR(dgb__log_access(context->fs, &id, *changes,
+                          SVN_FS_X__ITEM_TYPE_CHANGES, scratch_pool));
 
-  svn_pool_destroy(scratch_pool);
   return SVN_NO_ERROR;
 }
 
 /* Fetch the representation data (header, txdelta / plain windows)
- * 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
+ * addressed by ENTRY->ITEM in FS and cache it under KEY.  Read the data
+ * from REV_FILE.  If MAX_OFFSET is not -1, don't read windows that start
  * at or beyond that offset.  Use SCRATCH_POOL for temporary allocations.
  */
 static svn_error_t *
@@ -2887,27 +2931,28 @@ block_read_contents(svn_fs_t *fs,
 
 /* For the given REV_FILE in FS, in *STREAM return a stream covering the
  * item specified by ENTRY.  Also, verify the item's content by low-level
- * checksum.  Allocate the result in POOL.
+ * checksum.  Allocate the result in RESULT_POOL.
  */
 static svn_error_t *
 read_item(svn_stream_t **stream,
           svn_fs_t *fs,
           svn_fs_x__revision_file_t *rev_file,
           svn_fs_x__p2l_entry_t* entry,
-          apr_pool_t *pool)
+          apr_pool_t *result_pool)
 {
   apr_uint32_t digest;
   svn_checksum_t *expected, *actual;
   apr_uint32_t plain_digest;
+  svn_stringbuf_t *text;
 
   /* Read item into string buffer. */
-  svn_stringbuf_t *text = svn_stringbuf_create_ensure(entry->size, pool);
+  text = svn_stringbuf_create_ensure(entry->size, result_pool);
   text->len = entry->size;
   text->data[text->len] = 0;
   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);
+  *stream = svn_stream_from_stringbuf(text, result_pool);
   digest = svn__fnv1a_32x4(text->data, text->len);
 
   /* Checksums will match most of the time. */
@@ -2918,79 +2963,114 @@ read_item(svn_stream_t **stream,
    * nice error messages. */
   plain_digest = htonl(entry->fnv1_checksum);
   expected = svn_checksum__from_digest_fnv1a_32x4(
-                (const unsigned char *)&plain_digest, pool);
+                (const unsigned char *)&plain_digest, result_pool);
   plain_digest = htonl(digest);
   actual = svn_checksum__from_digest_fnv1a_32x4(
-                (const unsigned char *)&plain_digest, pool);
+                (const unsigned char *)&plain_digest, result_pool);
 
   /* Construct the full error message with all the info we have. */
-  return svn_checksum_mismatch_err(expected, actual, pool,
+  return svn_checksum_mismatch_err(expected, actual, result_pool,
                  _("Low-level checksum mismatch while reading\n"
                    "%s bytes of meta data at offset %s "),
-                 apr_psprintf(pool, "%" APR_OFF_T_FMT, entry->size),
-                 apr_psprintf(pool, "%" APR_OFF_T_FMT, entry->offset));
+                 apr_psprintf(result_pool, "%" APR_OFF_T_FMT, entry->size),
+                 apr_psprintf(result_pool, "%" APR_OFF_T_FMT, entry->offset));
 }
 
-/* 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 SCRATCH_POOL for temporary allocations.
- * If caching is not enabled, this is a no-op.
+/* If not already cached or if MUST_READ is set, read the changed paths
+ * list addressed by ENTRY in FS and retúrn it in *CHANGES.  Cache the
+ * result if caching is enabled.  Read the data from REV_FILE.  Trim the
+ * data in *CHANGES to the range given by CONTEXT.  Allocate *CHANGES in
+ * RESUSLT_POOL and allocate temporaries in SCRATCH_POOL.
  */
 static svn_error_t *
 block_read_changes(apr_array_header_t **changes,
                    svn_fs_t *fs,
                    svn_fs_x__revision_file_t *rev_file,
                    svn_fs_x__p2l_entry_t* entry,
+                   svn_fs_x__changes_context_t *context,
                    svn_boolean_t must_read,
                    apr_pool_t *result_pool,
                    apr_pool_t *scratch_pool)
 {
   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);
-  apr_size_t estimated_size;
+  svn_fs_x__pair_cache_key_t key;
+  svn_fs_x__changes_list_t changes_list;
+
+  /* If we don't have to return any data, just read and cache the first
+     block.  This means we won't cache the remaining blocks from longer
+     lists right away but only if they are actually needed. */
+  apr_size_t next = must_read ? context->next : 0;
+  apr_size_t next_offset = must_read ? context->next_offset : 0;
 
   /* we don't support containers, yet */
   SVN_ERR_ASSERT(entry->item_count == 1);
 
+  /* The item to read / write. */
+  key.revision = svn_fs_x__get_revnum(entry->items[0].change_set);
+  key.second = next;
+
   /* already in cache? */
   if (!must_read)
     {
       svn_boolean_t is_cached = FALSE;
-      SVN_ERR(svn_cache__has_key(&is_cached, ffd->changes_cache, &revision,
+      SVN_ERR(svn_cache__has_key(&is_cached, ffd->changes_cache, &key,
                                  scratch_pool));
       if (is_cached)
         return SVN_NO_ERROR;
     }
 
-  SVN_ERR(read_item(&stream, fs, rev_file, entry, scratch_pool));
+  /* Verify the whole list only once.  We don't use the STREAM any further. */
+  if (!must_read || next == 0)
+    SVN_ERR(read_item(&stream, fs, rev_file, entry, scratch_pool));
+
+  /* Seek to the block to read within the changes list. */
+  SVN_ERR(svn_fs_x__rev_file_seek(rev_file, NULL,
+                                  entry->offset + next_offset));
+  SVN_ERR(svn_fs_x__rev_file_stream(&stream, rev_file));
 
   /* read changes from revision file */
-  SVN_ERR(svn_fs_x__read_changes(changes, stream, result_pool, scratch_pool));
+  SVN_ERR(svn_fs_x__read_changes(changes, stream, SVN_FS_X__CHANGES_BLOCK_SIZE,
+                                 result_pool, scratch_pool));
+
+  SVN_ERR(svn_fs_x__rev_file_offset(&changes_list.end_offset, rev_file));
+  changes_list.end_offset -= entry->offset;
+  changes_list.start_offset = next_offset;
+  changes_list.count = (*changes)->nelts;
+  changes_list.changes = (svn_fs_x__change_t **)(*changes)->elts;
+  changes_list.eol =    (changes_list.count < SVN_FS_X__CHANGES_BLOCK_SIZE)
+                     || (changes_list.end_offset + 1 >= entry->size);
 
   /* cache for future reference */
 
-  /* Guesstimate for the size of the in-cache representation. */
-  estimated_size = (apr_size_t)250 * (*changes)->nelts;
+  SVN_ERR(svn_cache__set(ffd->changes_cache, &key, &changes_list,
+                         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));
+  /* Trim the result:
+   * Remove the entries that already been reported. */
+  if (must_read)
+    {
+      context->next_offset = changes_list.end_offset;
+      context->eol = changes_list.eol;
+    }
 
   return SVN_NO_ERROR;
 }
 
+/* If not already cached or if MUST_READ is set, read the changed paths
+ * list container addressed by ENTRY in FS.  Return the changes list
+ * identified by SUB_ITEM in *CHANGES, using CONTEXT to select a sub-range
+ * within that list.  Read the data from REV_FILE and cache the result.
+ *
+ * Allocate *CHANGES in RESUSLT_POOL and everything else in SCRATCH_POOL.
+ */
 static svn_error_t *
 block_read_changes_container(apr_array_header_t **changes,
                              svn_fs_t *fs,
                              svn_fs_x__revision_file_t *rev_file,
                              svn_fs_x__p2l_entry_t* entry,
                              apr_uint32_t sub_item,
+                             svn_fs_x__changes_context_t *context,
                              svn_boolean_t must_read,
                              apr_pool_t *result_pool,
                              apr_pool_t *scratch_pool)
@@ -3025,13 +3105,19 @@ block_read_changes_container(apr_array_h
 
   if (must_read)
     SVN_ERR(svn_fs_x__changes_get_list(changes, container, sub_item,
-                                       result_pool));
+                                       context, result_pool));
   SVN_ERR(svn_cache__set(ffd->changes_container_cache, &key, container,
                          scratch_pool));
 
   return SVN_NO_ERROR;
 }
 
+/* If not already cached or if MUST_READ is set, read the node revision
+ * addressed by ENTRY in FS and return it in *NODEREV_P.  Cache the
+ * result under KEY if caching is enabled.  Read the data from REV_FILE.
+ * Allocate *NODEREV_P in RESUSLT_POOL and allocate temporaries in
+ * SCRATCH_POOL.
+ */
 static svn_error_t *
 block_read_noderev(svn_fs_x__noderev_t **noderev_p,
                    svn_fs_t *fs,
@@ -3070,6 +3156,12 @@ block_read_noderev(svn_fs_x__noderev_t *
   return SVN_NO_ERROR;
 }
 
+/* If not already cached or if MUST_READ is set, read the node revision
+ * container addressed by ENTRY in FS.  Return the item identified by
+ * SUB_ITEM in *NODEREV_P.  Read the data from REV_FILE and cache it.
+ * Allocate *NODEREV_P in RESUSLT_POOL and allocate temporaries in
+ * SCRATCH_POOL.
+ */
 static svn_error_t *
 block_read_noderevs_container(svn_fs_x__noderev_t **noderev_p,
                               svn_fs_t *fs,
@@ -3116,6 +3208,12 @@ block_read_noderevs_container(svn_fs_x__
   return SVN_NO_ERROR;
 }
 
+/* If not already cached or if MUST_READ is set, read the representation
+ * container addressed by ENTRY in FS.  Return an extractor object for the
+ * item identified by SUB_ITEM in *EXTRACTOR.  Read the data from REV_FILE
+ * and cache it.  Allocate *EXTRACTOR in RESUSLT_POOL and all temporaries
+ * in SCRATCH_POOL.
+ */
 static svn_error_t *
 block_read_reps_container(svn_fs_x__rep_extractor_t **extractor,
                           svn_fs_t *fs,
@@ -3163,11 +3261,24 @@ block_read_reps_container(svn_fs_x__rep_
   return SVN_NO_ERROR;
 }
 
+/* Read the whole (e.g. 64kB) block containing the item identified by ID in
+ * FS and put all data into cache.  If necessary and depending on heuristics,
+ * neighboring blocks may also get read.  The data is being read from
+ * already open REVISION_FILE, which must be the correct rev / pack file
+ * w.r.t. ID->CHANGE_SET.
+ *
+ * For noderevs and changed path lists, the item fetched can be allocated
+ * RESULT_POOL and returned in *RESULT.  Otherwise, RESULT must be NULL.
+ * The BATON is passed along to the extractor sub-functions and will be
+ * used only when constructing the *RESULT.  SCRATCH_POOL will be used for
+ * all temporary allocations.
+ */
 static svn_error_t *
 block_read(void **result,
            svn_fs_t *fs,
            const svn_fs_x__id_t *id,
            svn_fs_x__revision_file_t *revision_file,
+           void *baton,
            apr_pool_t *result_pool,
            apr_pool_t *scratch_pool)
 {
@@ -3258,7 +3369,7 @@ block_read(void **result,
                   case SVN_FS_X__ITEM_TYPE_CHANGES:
                     SVN_ERR(block_read_changes((apr_array_header_t **)&item,
                                                fs, revision_file,
-                                               entry, is_result,
+                                               entry, baton, is_result,
                                                pool, iterpool));
                     break;
 
@@ -3267,7 +3378,8 @@ block_read(void **result,
                                             ((apr_array_header_t **)&item,
                                              fs, revision_file,
                                              entry, wanted_sub_item,
-                                             is_result, pool, iterpool));
+                                             baton, is_result,
+                                             pool, iterpool));
                     break;
 
                   case SVN_FS_X__ITEM_TYPE_NODEREVS_CONT:

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=1764214&r1=1764213&r2=1764214&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 Tue Oct 11 
09:11:50 2016
@@ -168,13 +168,24 @@ svn_fs_x__get_proplist(apr_hash_t **prop
                        apr_pool_t *result_pool,
                        apr_pool_t *scratch_pool);
 
-/* Fetch the list of change in revision REV in FS and return it in *CHANGES.
- * Allocate the result in POOL.
+/* Create a changes retrieval context object in *RESULT_POOL and return it
+ * in *CONTEXT.  It will allow svn_fs_x__get_changes to fetch consecutive
+ * blocks (one per invocation) from REV's changed paths list in FS.
+ * Use SCRATCH_POOL for temporary allocations. */
+svn_error_t *
+svn_fs_x__create_changes_context(svn_fs_x__changes_context_t **context,
+                                 svn_fs_t *fs,
+                                 svn_revnum_t rev,
+                                 apr_pool_t *result_pool,
+                                 apr_pool_t *scratch_pool);
+
+/* Fetch the block of changes from the CONTEXT and return it in *CHANGES.
+ * Allocate the result in RESULT_POOL and use SCRATCH_POOL for temporaries.
  */
 svn_error_t *
 svn_fs_x__get_changes(apr_array_header_t **changes,
-                      svn_fs_t *fs,
-                      svn_revnum_t rev,
-                      apr_pool_t *pool);
+                      svn_fs_x__changes_context_t *context,
+                      apr_pool_t *result_pool,
+                      apr_pool_t *scratch_pool);
 
 #endif

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=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_x/caching.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_x/caching.c Tue Oct 11 
09:11:50 2016
@@ -69,9 +69,9 @@ normalize_key_part(const char *original,
   return normalized->data;
 }
 
-/* *CACHE_TXDELTAS, *CACHE_FULLTEXTS and *CACHE_REVPROPS flags will be set
-   according to FS->CONFIG.  *CACHE_NAMESPACE receives the cache prefix
-   to use.
+/* *CACHE_TXDELTAS, *CACHE_FULLTEXTS, *CACHE_REVPROPS and *CACHE_NODEPROPS
+   flags will be set according to FS->CONFIG.  *CACHE_NAMESPACE receives
+   the cache prefix to use.
 
    Allocate CACHE_NAMESPACE in RESULT_POOL. */
 static svn_error_t *
@@ -79,6 +79,7 @@ read_config(const char **cache_namespace
             svn_boolean_t *cache_txdeltas,
             svn_boolean_t *cache_fulltexts,
             svn_boolean_t *cache_revprops,
+            svn_boolean_t *cache_nodeprops,
             svn_fs_t *fs,
             apr_pool_t *result_pool)
 {
@@ -137,6 +138,15 @@ read_config(const char **cache_namespace
   else
     *cache_revprops = TRUE;
 
+  /* by default, cache nodeprops: this will match pre-1.10
+   * behavior where node properties caching was controlled
+   * by SVN_FS_CONFIG_FSFS_CACHE_FULLTEXTS configuration option.
+   */
+  *cache_nodeprops
+    = svn_hash__get_bool(fs->config,
+                         SVN_FS_CONFIG_FSFS_CACHE_NODEPROPS,
+                         TRUE);
+
   return SVN_NO_ERROR;
 }
 
@@ -380,6 +390,7 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
   svn_boolean_t cache_txdeltas;
   svn_boolean_t cache_fulltexts;
   svn_boolean_t cache_revprops;
+  svn_boolean_t cache_nodeprops;
   const char *cache_namespace;
   svn_boolean_t has_namespace;
 
@@ -388,6 +399,7 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
                       &cache_txdeltas,
                       &cache_fulltexts,
                       &cache_revprops,
+                      &cache_nodeprops,
                       fs,
                       scratch_pool));
 
@@ -430,7 +442,7 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
                        svn_fs_x__deserialize_dir_entries,
                        sizeof(svn_fs_x__id_t),
                        apr_pstrcat(scratch_pool, prefix, "DIR", SVN_VA_NULL),
-                       SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
+                       SVN_CACHE__MEMBUFFER_HIGH_PRIORITY,
                        has_namespace,
                        fs,
                        no_handler, FALSE,
@@ -475,7 +487,7 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
                        1, 8, /* 1k / entry; 8 entries total, rarely used */
                        svn_fs_x__serialize_changes,
                        svn_fs_x__deserialize_changes,
-                       sizeof(svn_revnum_t),
+                       sizeof(svn_fs_x__pair_cache_key_t),
                        apr_pstrcat(scratch_pool, prefix, "CHANGES",
                                    SVN_VA_NULL),
                        0,
@@ -512,7 +524,7 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
                        SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
                        has_namespace,
                        fs,
-                       no_handler, !cache_fulltexts,
+                       no_handler, !cache_nodeprops,
                        fs->pool, scratch_pool));
 
   /* if enabled, cache revprops */

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=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_x/changes.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_x/changes.c Tue Oct 11 
09:11:50 2016
@@ -21,6 +21,7 @@
  */
 
 #include "svn_private_config.h"
+#include "svn_sorts.h"
 
 #include "private/svn_packed_data.h"
 
@@ -37,8 +38,8 @@
 /* the change contains a property modification */
 #define CHANGE_PROP_MOD     0x00002
 
-/* the last part (rev_id) of node revision ID is a transaction ID */
-#define CHANGE_TXN_NODE     0x00004
+/* the change contains a mergeinfo modification */
+#define CHANGE_MERGEINFO_MOD 0x00004
 
 /* (flags & CHANGE_NODE_MASK) >> CHANGE_NODE_SHIFT extracts the node type */
 #define CHANGE_NODE_SHIFT   0x00003
@@ -52,16 +53,13 @@
 
 /* (flags & CHANGE_KIND_MASK) >> CHANGE_KIND_SHIFT extracts the change type */
 #define CHANGE_KIND_SHIFT   0x00005
-#define CHANGE_KIND_MASK    0x000E0
+#define CHANGE_KIND_MASK    0x00060
 
 /* node types according to svn_fs_path_change_kind_t */
 #define CHANGE_KIND_MODIFY  0x00000
 #define CHANGE_KIND_ADD     0x00020
 #define CHANGE_KIND_DELETE  0x00040
 #define CHANGE_KIND_REPLACE 0x00060
-#define CHANGE_KIND_RESET   0x00080
-#define CHANGE_KIND_MOVE    0x000A0
-#define CHANGE_KIND_MOVEREPLACE 0x000C0
 
 /* Our internal representation of a change */
 typedef struct binary_change_t
@@ -77,10 +75,6 @@ typedef struct binary_change_t
   svn_revnum_t copyfrom_rev;
   apr_size_t copyfrom_path;
 
-  /* Relevant parts of the node revision ID of the change.
-   * Empty, if REV_ID is not "used". */
-  svn_fs_x__id_t noderev_id;
-
 } binary_change_t;
 
 /* The actual container object.  Change lists are concatenated into CHANGES
@@ -138,20 +132,16 @@ append_change(svn_fs_x__changes_t *chang
               svn_fs_x__change_t *change)
 {
   binary_change_t binary_change = { 0 };
-  svn_boolean_t is_txn_id;
 
   /* CHANGE must be sufficiently complete */
   SVN_ERR_ASSERT(change);
   SVN_ERR_ASSERT(change->path.data);
 
-  /* Relevant parts of the revision ID of the change. */
-  binary_change.noderev_id = change->noderev_id;
-
   /* define the kind of change and what specific information is present */
-  is_txn_id = svn_fs_x__is_txn(binary_change.noderev_id.change_set);
   binary_change.flags = (change->text_mod ? CHANGE_TEXT_MOD : 0)
                       | (change->prop_mod ? CHANGE_PROP_MOD : 0)
-                      | (is_txn_id ? CHANGE_TXN_NODE : 0)
+                      | (change->mergeinfo_mod == svn_tristate_true
+                                          ? CHANGE_MERGEINFO_MOD : 0)
                       | ((int)change->change_kind << CHANGE_KIND_SHIFT)
                       | ((int)change->node_kind << CHANGE_NODE_SHIFT);
 
@@ -222,8 +212,11 @@ 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,
+                           svn_fs_x__changes_context_t *context,
                            apr_pool_t *result_pool)
 {
+  int list_first;
+  int list_last;
   int first;
   int last;
   int i;
@@ -242,8 +235,16 @@ svn_fs_x__changes_get_list(apr_array_hea
                              idx, changes->offsets->nelts - 1);
 
   /* range of changes to return */
-  first = APR_ARRAY_IDX(changes->offsets, (int)idx, int);
-  last = APR_ARRAY_IDX(changes->offsets, (int)idx + 1, int);
+  list_first = APR_ARRAY_IDX(changes->offsets, (int)idx, int);
+  list_last = APR_ARRAY_IDX(changes->offsets, (int)idx + 1, int);
+
+  /* Restrict it to the sub-range requested by the caller.
+   * Clip the range to never exceed the list's content. */
+  first = MIN(context->next + list_first, list_last);
+  last = MIN(first + SVN_FS_X__CHANGES_BLOCK_SIZE, list_last);
+
+  /* Indicate to the caller whether the end of the list has been reached. */
+  context->eol = last == list_last;
 
   /* construct result */
   *list = apr_array_make(result_pool, last - first,
@@ -260,13 +261,13 @@ svn_fs_x__changes_get_list(apr_array_hea
                                                      &change->path.len,
                                                      result_pool);
 
-      if (binary_change->noderev_id.change_set != SVN_FS_X__INVALID_CHANGE_SET)
-        change->noderev_id = binary_change->noderev_id;
-
       change->change_kind = (svn_fs_path_change_kind_t)
         ((binary_change->flags & CHANGE_KIND_MASK) >> CHANGE_KIND_SHIFT);
       change->text_mod = (binary_change->flags & CHANGE_TEXT_MOD) != 0;
       change->prop_mod = (binary_change->flags & CHANGE_PROP_MOD) != 0;
+      change->mergeinfo_mod = (binary_change->flags & CHANGE_MERGEINFO_MOD)
+                            ? svn_tristate_true
+                            : svn_tristate_false;
       change->node_kind = (svn_node_kind_t)
         ((binary_change->flags & CHANGE_NODE_MASK) >> CHANGE_NODE_SHIFT);
 
@@ -312,8 +313,6 @@ svn_fs_x__write_changes_container(svn_st
   svn_packed__create_int_substream(changes_stream, TRUE, FALSE);
   svn_packed__create_int_substream(changes_stream, TRUE, TRUE);
   svn_packed__create_int_substream(changes_stream, TRUE, FALSE);
-  svn_packed__create_int_substream(changes_stream, TRUE, TRUE);
-  svn_packed__create_int_substream(changes_stream, TRUE, FALSE);
 
   /* serialize offsets array */
   for (i = 0; i < changes->offsets->nelts; ++i)
@@ -331,9 +330,6 @@ svn_fs_x__write_changes_container(svn_st
 
       svn_packed__add_int(changes_stream, change->copyfrom_rev);
       svn_packed__add_uint(changes_stream, change->copyfrom_path);
-
-      svn_packed__add_int(changes_stream, change->noderev_id.change_set);
-      svn_packed__add_uint(changes_stream, change->noderev_id.number);
     }
 
   /* write to disk */
@@ -388,9 +384,6 @@ svn_fs_x__read_changes_container(svn_fs_
       change.copyfrom_rev = (svn_revnum_t)svn_packed__get_int(changes_stream);
       change.copyfrom_path = (apr_size_t)svn_packed__get_uint(changes_stream);
 
-      change.noderev_id.change_set = svn_packed__get_int(changes_stream);
-      change.noderev_id.number = svn_packed__get_uint(changes_stream);
-
       APR_ARRAY_PUSH(changes->changes, binary_change_t) = change;
     }
 
@@ -465,7 +458,8 @@ svn_fs_x__changes_get_list_func(void **o
   int i;
   apr_array_header_t *list;
 
-  apr_uint32_t idx = *(apr_uint32_t *)baton;
+  svn_fs_x__changes_get_list_baton_t *b = baton;
+  apr_uint32_t idx = b->sub_item;
   const svn_fs_x__changes_t *container = data;
 
   /* resolve all the sub-container pointers we need */
@@ -496,6 +490,12 @@ svn_fs_x__changes_get_list_func(void **o
   first = offsets[idx];
   last = offsets[idx+1];
 
+  /* Restrict range to the block requested by the BATON.
+   * Tell the caller whether we reached the end of the list. */
+  first = MIN(first + b->start, last);
+  last = MIN(first + SVN_FS_X__CHANGES_BLOCK_SIZE, last);
+  *b->eol = last == offsets[idx+1];
+
   /* construct result */
   list = apr_array_make(pool, last - first, sizeof(svn_fs_x__change_t*));
 
@@ -509,8 +509,6 @@ svn_fs_x__changes_get_list_func(void **o
         = svn_fs_x__string_table_get_func(paths, binary_change->path,
                                           &change->path.len, pool);
 
-      change->noderev_id = binary_change->noderev_id;
-
       change->change_kind = (svn_fs_path_change_kind_t)
         ((binary_change->flags & CHANGE_KIND_MASK) >> CHANGE_KIND_SHIFT);
       change->text_mod = (binary_change->flags & CHANGE_TEXT_MOD) != 0;

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=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_x/changes.h (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_x/changes.h Tue Oct 11 
09:11:50 2016
@@ -71,13 +71,15 @@ svn_fs_x__changes_estimate_size(const sv
 
 /* Read changes containers. */
 
-/* From CHANGES, extract the change list with the given IDX.  Allocate
- * the result in POOL and return it in *LIST.
+/* From CHANGES, access the change list with the given IDX and extract the
+ * next entries according to CONTEXT.  Allocate the result in RESULT_POOL
+ * and return it in *LIST.
  */
 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,
+                           svn_fs_x__changes_context_t *context,
                            apr_pool_t *result_pool);
 
 /* I/O interface. */
@@ -116,11 +118,25 @@ svn_fs_x__deserialize_changes_container(
                                         apr_size_t data_len,
                                         apr_pool_t *result_pool);
 
+/* Baton type to be used with svn_fs_x__changes_get_list_func. */
+typedef struct svn_fs_x__changes_get_list_baton_t
+{
+  /* Sub-item to query */
+  apr_uint32_t sub_item;
+
+  /* Deliver data starting from this index within the changes list. */
+  int start;
+
+  /* To be set by svn_fs_x__changes_get_list_func:
+     Did we deliver the last change in that list? */
+  svn_boolean_t *eol;
+} svn_fs_x__changes_get_list_baton_t;
+
 /* 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
- * the apr_uint32_t index passed in as *BATON.  This function is similar
- * to svn_fs_x__changes_get_list but operates on the cache serialized
- * representation of the container.
+ * the svn_fs_x__changes_get_list_baton_t passed in as *BATON.  This
+ * function is similar to svn_fs_x__changes_get_list but operates on
+ * the cache serialized representation of the container.
  */
 svn_error_t *
 svn_fs_x__changes_get_list_func(void **out,

Modified: subversion/branches/ra-git/subversion/libsvn_fs_x/fs.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_x/fs.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_x/fs.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_x/fs.c Tue Oct 11 09:11:50 
2016
@@ -322,6 +322,7 @@ initialize_fs_struct(svn_fs_t *fs)
 {
   svn_fs_x__data_t *ffd = apr_pcalloc(fs->pool, sizeof(*ffd));
   ffd->revprop_generation = -1;
+  ffd->flush_to_disk = TRUE;
 
   fs->vtable = &fs_vtable;
   fs->fsap_data = ffd;

Modified: subversion/branches/ra-git/subversion/libsvn_fs_x/fs.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_x/fs.h?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_x/fs.h (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_x/fs.h Tue Oct 11 09:11:50 
2016
@@ -37,7 +37,7 @@
 #include "private/svn_sqlite.h"
 #include "private/svn_mutex.h"
 
-#include "id.h"
+#include "rev_file.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -137,6 +137,11 @@ extern "C" {
 #define SVN_FS_X__USE_LOCK_MUTEX 0
 #endif
 
+/* Maximum number of changes we deliver per request when listing the
+   changed paths for a given revision.   Anything > 0 will do.
+   At 100..300 bytes per entry, this limits the allocation to ~30kB. */
+#define SVN_FS_X__CHANGES_BLOCK_SIZE 100
+
 /* Private FSX-specific data shared between all svn_txn_t objects that
    relate to a particular transaction in a filesystem (as identified
    by transaction id and filesystem UUID).  Objects of this type are
@@ -319,8 +324,8 @@ typedef struct svn_fs_x__data_t
      the key is a (pack file revision, file offset) pair */
   svn_cache__t *noderevs_container_cache;
 
-  /* Cache for change lists as APR arrays of svn_fs_x__change_t * objects;
-     the key is the revision */
+  /* Cache for change lists n blocks as svn_fs_x__changes_list_t * objects;
+     the key is the (revision, first-element-in-block) pair. */
   svn_cache__t *changes_cache;
 
   /* Cache for change_list_t containers;
@@ -398,6 +403,9 @@ typedef struct svn_fs_x__data_t
      or dump / load cycles). */
   const char *instance_id;
 
+  /* Ensure that all filesystem changes are written to disk. */
+  svn_boolean_t flush_to_disk;
+
   /* Pointer to svn_fs_open. */
   svn_error_t *(*svn_fs_open_)(svn_fs_t **, const char *, apr_hash_t *,
                                apr_pool_t *, apr_pool_t *);
@@ -481,7 +489,8 @@ typedef struct svn_fs_x__noderev_t
   /* node kind */
   svn_node_kind_t kind;
 
-  /* number of predecessors this node revision has (recursively). */
+  /* Number of predecessors this node revision has (recursively).
+     A difference from the BDB backend is that it cannot be -1. */
   int predecessor_count;
 
   /* representation key for this node's properties.  may be NULL if
@@ -521,29 +530,31 @@ typedef struct svn_fs_x__dirent_t
 
 
 /*** Change ***/
-typedef struct svn_fs_x__change_t
+typedef svn_fs_path_change3_t svn_fs_x__change_t;
+
+/*** Context for reading changed paths lists iteratively. */
+typedef struct svn_fs_x__changes_context_t
 {
-  /* Path of the change. */
-  svn_string_t path;
+  /* Repository to fetch from. */
+  svn_fs_t *fs;
 
-  /* node revision id of changed path */
-  svn_fs_x__id_t noderev_id;
+  /* Revision that we read from. */
+  svn_revnum_t revision;
 
-  /* See svn_fs_path_change2_t for a description for the remaining elements.
-   */
-  svn_fs_path_change_kind_t change_kind;
-
-  svn_boolean_t text_mod;
-  svn_boolean_t prop_mod;
-  svn_node_kind_t node_kind;
+  /* Revision file object to use when needed. */
+  svn_fs_x__revision_file_t *revision_file;
 
-  svn_boolean_t copyfrom_known;
-  svn_revnum_t copyfrom_rev;
-  const char *copyfrom_path;
+  /* Index of the next change to fetch. */
+  apr_size_t next;
+
+  /* Offset, within the changed paths list on disk, of the next change to
+     fetch. */
+  apr_off_t next_offset;
 
-  svn_tristate_t mergeinfo_mod;
-} svn_fs_x__change_t;
+  /* Has the end of the list been reached? */
+  svn_boolean_t eol;
 
+} svn_fs_x__changes_context_t;
 
 /*** Directory (only used at the cache interface) ***/
 typedef struct svn_fs_x__dir_data_t

Modified: subversion/branches/ra-git/subversion/libsvn_fs_x/fs_x.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_x/fs_x.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_x/fs_x.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_x/fs_x.c Tue Oct 11 
09:11:50 2016
@@ -201,7 +201,7 @@ svn_fs_x__write_format(svn_fs_t *fs,
     {
       SVN_ERR(svn_io_write_atomic2(path, sb->data, sb->len,
                                    NULL /* copy_perms_path */,
-                                   TRUE, scratch_pool));
+                                   ffd->flush_to_disk, scratch_pool));
     }
 
   /* And set the perms to make it read only */
@@ -535,6 +535,20 @@ write_config(svn_fs_t *fs,
                             fsx_conf_contents, scratch_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)
+{
+  svn_fs_x__data_t *ffd = fs->fsap_data;
+
+  ffd->flush_to_disk = !svn_hash__get_bool(fs->config,
+                                           SVN_FS_CONFIG_NO_FLUSH_TO_DISK,
+                                           FALSE);
+
+  return SVN_NO_ERROR;
+}
+
 /* Read FS's UUID file and store the data in the FS struct. */
 static svn_error_t *
 read_uuid(svn_fs_t *fs,
@@ -603,6 +617,9 @@ svn_fs_x__open(svn_fs_t *fs,
   /* Read the configuration file. */
   SVN_ERR(read_config(ffd, fs->path, fs->pool, scratch_pool));
 
+  /* Global configuration options. */
+  SVN_ERR(read_global_config(fs));
+
   ffd->youngest_rev_cache = 0;
 
   return SVN_NO_ERROR;
@@ -860,8 +877,6 @@ write_revision_zero(svn_fs_t *fs,
   const char *path_revision_zero = svn_fs_x__path_rev(fs, 0, scratch_pool);
   apr_hash_t *proplist;
   svn_string_t date;
-  svn_stream_t *stream;
-  svn_stringbuf_t *revprops;
 
   apr_array_header_t *index_entries;
   svn_fs_x__p2l_entry_t *entry;
@@ -934,15 +949,13 @@ write_revision_zero(svn_fs_t *fs,
   proplist = apr_hash_make(scratch_pool);
   svn_hash_sets(proplist, SVN_PROP_REVISION_DATE, &date);
 
-  revprops = svn_stringbuf_create_empty(scratch_pool);
-  stream = svn_stream_from_stringbuf(revprops, scratch_pool);
-  SVN_ERR(svn_fs_x__write_properties(stream, proplist, scratch_pool));
-  SVN_ERR(svn_stream_close(stream));
-
-  SVN_ERR(svn_io_file_create_bytes(svn_fs_x__path_revprops(fs, 0,
-                                                           scratch_pool),
-                                   revprops->data, revprops->len,
-                                   scratch_pool));
+  SVN_ERR(svn_io_file_open(&apr_file,
+                           svn_fs_x__path_revprops(fs, 0, scratch_pool),
+                           APR_WRITE | APR_CREATE, APR_OS_DEFAULT, 
+                           scratch_pool));
+  SVN_ERR(svn_fs_x__write_non_packed_revprops(apr_file, proplist,
+                                              scratch_pool));
+  SVN_ERR(svn_io_file_close(apr_file, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -990,6 +1003,9 @@ svn_fs_x__create_file_tree(svn_fs_t *fs,
   SVN_ERR(write_config(fs, scratch_pool));
   SVN_ERR(read_config(ffd, fs->path, fs->pool, scratch_pool));
 
+  /* Global configuration options. */
+  SVN_ERR(read_global_config(fs));
+
   /* Add revision 0. */
   SVN_ERR(write_revision_zero(fs, scratch_pool));
 
@@ -1100,7 +1116,7 @@ svn_fs_x__set_uuid(svn_fs_t *fs,
       SVN_ERR(svn_io_write_atomic2(uuid_path, contents->data, contents->len,
                                    /* perms */
                                    svn_fs_x__path_current(fs, scratch_pool),
-                                   TRUE, scratch_pool));
+                                   ffd->flush_to_disk, scratch_pool));
     }
 
   fs->uuid = apr_pstrdup(fs->pool, uuid);

Modified: subversion/branches/ra-git/subversion/libsvn_fs_x/hotcopy.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_x/hotcopy.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_x/hotcopy.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_x/hotcopy.c Tue Oct 11 
09:11:50 2016
@@ -555,7 +555,7 @@ typedef struct hotcopy_body_baton_t {
  * An incremental hotcopy copies only changed or new files to the destination,
  * and removes files from the destination no longer present in the source.
  * While the incremental hotcopy is running, readers should still be able
- * to access the destintation repository without error and should not see
+ * to access the destination repository without error and should not see
  * revisions currently in progress of being copied. Readers are able to see
  * new fully copied revisions even if the entire incremental hotcopy procedure
  * has not yet completed.

Modified: subversion/branches/ra-git/subversion/libsvn_fs_x/index.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_x/index.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_x/index.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_x/index.c Tue Oct 11 
09:11:50 2016
@@ -57,7 +57,7 @@ const apr_uint64_t off_t_max = (sizeof(a
                              : APR_INT32_MAX;
 
 /* We store P2L proto-index entries as 6 values, 64 bits each on disk.
- * See also svn_fs_fs__p2l_proto_index_add_entry().
+ * See also svn_fs_x__p2l_proto_index_add_entry().
  */
 #define P2L_PROTO_INDEX_ENTRY_SIZE (6 * sizeof(apr_uint64_t))
 
@@ -231,7 +231,7 @@ stream_error_create(svn_fs_x__packed_num
   apr_off_t offset;
   SVN_ERR(svn_io_file_name_get(&file_name, stream->file,
                                stream->pool));
-  SVN_ERR(svn_fs_x__get_file_offset(&offset, stream->file, stream->pool));
+  SVN_ERR(svn_io_file_get_offset(&offset, stream->file, stream->pool));
 
   return svn_error_createf(err, NULL, message, file_name,
                            apr_psprintf(stream->pool,
@@ -3166,7 +3166,7 @@ compare_p2l_entry_offsets(const void *lh
 }
 
 /* Cached data extraction utility.  DATA is a P2L index page, e.g. an APR
- * array of svn_fs_fs__p2l_entry_t elements.  Return the entry for the item,
+ * array of svn_fs_x__p2l_entry_t elements.  Return the entry for the item,
  * allocated in RESULT_POOL, starting at OFFSET or NULL if that's not an
  * the start offset of any item. Use SCRATCH_POOL for temporary allocations.
  */

Modified: subversion/branches/ra-git/subversion/libsvn_fs_x/index.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_x/index.h?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_x/index.h (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_x/index.h Tue Oct 11 
09:11:50 2016
@@ -206,7 +206,7 @@ svn_fs_x__p2l_index_append(svn_checksum_
 /* Use the phys-to-log mapping files in FS to build a list of entries
  * that (at least partly) overlap with the range given by BLOCK_START
  * offset and BLOCK_SIZE in the rep / pack file containing REVISION.
- * Return the array in *ENTRIES with svn_fs_fs__p2l_entry_t as elements,
+ * Return the array in *ENTRIES with svn_fs_x__p2l_entry_t as elements,
  * allocated in RESULT_POOL.  REV_FILE determines whether to access single
  * rev or pack file data.  If that is not available anymore (neither in
  * cache nor on disk), return an error.  Use SCRATCH_POOL for temporary
@@ -309,7 +309,7 @@ svn_fs_x__p2l_get_max_offset(apr_off_t *
 
 /* For FS, create a new L2P auto-deleting proto index file in POOL and return
  * its name in *PROTONAME.  All entries to write are given in ENTRIES and
- * entries are of type svn_fs_fs__p2l_entry_t* (sic!).  The ENTRIES array
+ * entries are of type svn_fs_x__p2l_entry_t* (sic!).  The ENTRIES array
  * will be reordered.  Give the proto index file the lifetime of RESULT_POOL
  * and use SCRATCH_POOL for temporary allocations.
  */
@@ -322,7 +322,7 @@ svn_fs_x__l2p_index_from_p2l_entries(con
 
 /* For FS, create a new P2L auto-deleting proto index file in POOL and return
  * its name in *PROTONAME.  All entries to write are given in ENTRIES and
- * of type svn_fs_fs__p2l_entry_t*.  The FVN1 checksums are not taken from
+ * of type svn_fs_x__p2l_entry_t*.  The FVN1 checksums are not taken from
  * ENTRIES but are begin calculated from the current contents of REV_FILE
  * as we go.  Give the proto index file the lifetime of RESULT_POOL and use
  * SCRATCH_POOL for temporary allocations.

Modified: subversion/branches/ra-git/subversion/libsvn_fs_x/lock.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_x/lock.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_x/lock.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_x/lock.c Tue Oct 11 
09:11:50 2016
@@ -937,7 +937,7 @@ lock_body(void *baton,
                                                   lb->result_pool));
 
           /* The INFO->PATH is already allocated in LB->RESULT_POOL as a result
-             of svn_fspath__canonicalize() (see svn_fs_fs__lock()). */
+             of svn_fspath__canonicalize() (see svn_fs_x__lock()). */
           info->lock->path = info->path;
           info->lock->owner = apr_pstrdup(lb->result_pool,
                                           lb->fs->access_ctx->username);

Modified: subversion/branches/ra-git/subversion/libsvn_fs_x/low_level.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_x/low_level.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_x/low_level.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_x/low_level.c Tue Oct 11 
09:11:50 2016
@@ -829,14 +829,6 @@ read_change(svn_fs_x__change_t **change_
   change = apr_pcalloc(result_pool, sizeof(*change));
   last_str = line->data;
 
-  /* Get the node-id of the change. */
-  str = svn_cstring_tokenize(" ", &last_str);
-  if (str == NULL)
-    return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
-                            _("Invalid changes line in rev-file"));
-
-  SVN_ERR(svn_fs_x__id_parse(&change->noderev_id, str));
-
   /* Get the change type. */
   str = svn_cstring_tokenize(" ", &last_str);
   if (str == NULL)
@@ -982,10 +974,10 @@ read_change(svn_fs_x__change_t **change_
 svn_error_t *
 svn_fs_x__read_changes(apr_array_header_t **changes,
                        svn_stream_t *stream,
+                       int max_count,
                        apr_pool_t *result_pool,
                        apr_pool_t *scratch_pool)
 {
-  svn_fs_x__change_t *change;
   apr_pool_t *iterpool;
 
   /* Pre-allocate enough room for most change lists.
@@ -998,13 +990,16 @@ svn_fs_x__read_changes(apr_array_header_
    */
   *changes = apr_array_make(result_pool, 63, sizeof(svn_fs_x__change_t *));
 
-  SVN_ERR(read_change(&change, stream, result_pool, scratch_pool));
   iterpool = svn_pool_create(scratch_pool);
-  while (change)
+  for (; max_count > 0; --max_count)
     {
-      APR_ARRAY_PUSH(*changes, svn_fs_x__change_t*) = change;
-      SVN_ERR(read_change(&change, stream, result_pool, iterpool));
+      svn_fs_x__change_t *change;
       svn_pool_clear(iterpool);
+      SVN_ERR(read_change(&change, stream, result_pool, iterpool));
+      if (!change)
+        break;
+ 
+      APR_ARRAY_PUSH(*changes, svn_fs_x__change_t*) = change;
     }
   svn_pool_destroy(iterpool);
 
@@ -1044,7 +1039,6 @@ write_change_entry(svn_stream_t *stream,
                    svn_fs_x__change_t *change,
                    apr_pool_t *scratch_pool)
 {
-  const char *idstr;
   const char *change_string = NULL;
   const char *kind_string = "";
   svn_stringbuf_t *buf;
@@ -1070,8 +1064,6 @@ write_change_entry(svn_stream_t *stream,
                                change->change_kind);
     }
 
-  idstr = svn_fs_x__id_unparse(&change->noderev_id, scratch_pool)->data;
-
   SVN_ERR_ASSERT(change->node_kind == svn_node_dir
                  || change->node_kind == svn_node_file);
   kind_string = apr_psprintf(scratch_pool, "-%s",
@@ -1079,8 +1071,8 @@ write_change_entry(svn_stream_t *stream,
                              ? SVN_FS_X__KIND_DIR
                              : SVN_FS_X__KIND_FILE);
 
-  buf = svn_stringbuf_createf(scratch_pool, "%s %s%s %s %s %s %s\n",
-                              idstr, change_string, kind_string,
+  buf = svn_stringbuf_createf(scratch_pool, "%s%s %s %s %s %s\n",
+                              change_string, kind_string,
                               change->text_mod ? FLAG_TRUE : FLAG_FALSE,
                               change->prop_mod ? FLAG_TRUE : FLAG_FALSE,
                               change->mergeinfo_mod == svn_tristate_true

Modified: subversion/branches/ra-git/subversion/libsvn_fs_x/low_level.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_x/low_level.h?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_x/low_level.h (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_x/low_level.h Tue Oct 11 
09:11:50 2016
@@ -170,15 +170,17 @@ svn_fs_x__write_rep_header(svn_fs_x__rep
                            svn_stream_t *stream,
                            apr_pool_t *scratch_pool);
 
-/* Read all the changes from STREAM and store them in *CHANGES,
-   allocated in RESULT_POOL. Do temporary allocations in SCRATCH_POOL. */
+/* Read up to MAX_COUNT of the changes from STREAM and store them in
+   *CHANGES, allocated in RESULT_POOL.  Do temporary allocations in
+   SCRATCH_POOL. */
 svn_error_t *
 svn_fs_x__read_changes(apr_array_header_t **changes,
                        svn_stream_t *stream,
+                       int max_count,
                        apr_pool_t *result_pool,
                        apr_pool_t *scratch_pool);
 
-/* Callback function used by svn_fs_fs__read_changes_incrementally(),
+/* Callback function used by svn_fs_x__read_changes_incrementally(),
  * asking the receiver to process to process CHANGE using BATON.  CHANGE
  * and SCRATCH_POOL will not be valid beyond the current callback invocation.
  */

Modified: subversion/branches/ra-git/subversion/libsvn_fs_x/pack.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_x/pack.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_x/pack.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_x/pack.c Tue Oct 11 
09:11:50 2016
@@ -391,7 +391,7 @@ static svn_error_t *
 copy_file_data(pack_context_t *context,
                apr_file_t *dest,
                apr_file_t *source,
-               apr_off_t size,
+               svn_filesize_t size,
                apr_pool_t *scratch_pool)
 {
   /* most non-representation items will be small.  Minimize the buffer
@@ -478,8 +478,8 @@ copy_item_to_temp(pack_context_t *contex
   svn_fs_x__p2l_entry_t *new_entry
     = svn_fs_x__p2l_entry_dup(entry, context->info_pool);
 
-  SVN_ERR(svn_fs_x__get_file_offset(&new_entry->offset, temp_file,
-                                    scratch_pool));
+  SVN_ERR(svn_io_file_get_offset(&new_entry->offset, temp_file,
+                                 scratch_pool));
   APR_ARRAY_PUSH(entries, svn_fs_x__p2l_entry_t *) = new_entry;
 
   SVN_ERR(svn_fs_x__rev_file_get(&file, rev_file));
@@ -572,8 +572,8 @@ copy_rep_to_temp(pack_context_t *context
   /* create a copy of ENTRY, make it point to the copy destination and
    * store it in CONTEXT */
   entry = svn_fs_x__p2l_entry_dup(entry, context->info_pool);
-  SVN_ERR(svn_fs_x__get_file_offset(&entry->offset, context->reps_file,
-                                    scratch_pool));
+  SVN_ERR(svn_io_file_get_offset(&entry->offset, context->reps_file,
+                                 scratch_pool));
   add_item_rep_mapping(context, entry);
 
   /* read & parse the representation header */
@@ -698,8 +698,8 @@ copy_node_to_temp(pack_context_t *contex
   /* create a copy of ENTRY, make it point to the copy destination and
    * store it in CONTEXT */
   entry = svn_fs_x__p2l_entry_dup(entry, context->info_pool);
-  SVN_ERR(svn_fs_x__get_file_offset(&entry->offset, context->reps_file,
-                                    scratch_pool));
+  SVN_ERR(svn_io_file_get_offset(&entry->offset, context->reps_file,
+                                 scratch_pool));
   add_item_rep_mapping(context, entry);
 
   /* copy the noderev to our temp file */
@@ -821,7 +821,7 @@ sort_reps(pack_context_t *context)
 /* Return the remaining unused bytes in the current block in CONTEXT's
  * pack file.
  */
-static apr_ssize_t
+static apr_off_t
 get_block_left(pack_context_t *context)
 {
   svn_fs_x__data_t *ffd = context->fs->fsap_data;
@@ -1603,8 +1603,8 @@ write_changes_containers(pack_context_t
        * the container */
       SVN_ERR(svn_io_file_seek(temp_file, APR_SET, &entry->offset,
                                iterpool));
-      SVN_ERR(svn_fs_x__read_changes(&changes, temp_stream, scratch_pool,
-                                     iterpool));
+      SVN_ERR(svn_fs_x__read_changes(&changes, temp_stream, INT_MAX,
+                                     scratch_pool, iterpool));
       SVN_ERR(svn_fs_x__changes_append_list(&list_index, container, changes));
       SVN_ERR_ASSERT(list_index == sub_items->nelts);
       block_left -= estimated_size;
@@ -1839,20 +1839,15 @@ append_revision(pack_context_t *context,
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
   svn_fs_x__revision_file_t *rev_file;
   apr_file_t *file;
-  apr_finfo_t finfo;
-
-  /* Get the size of the file. */
-  const char *path = svn_dirent_join(context->shard_dir,
-                                     apr_psprintf(iterpool, "%ld",
-                                                  context->start_rev),
-                                     scratch_pool);
-  SVN_ERR(svn_io_stat(&finfo, path, APR_FINFO_SIZE, scratch_pool));
+  svn_filesize_t revfile_size;
 
   /* Copy all the bits from the rev file to the end of the pack file. */
   SVN_ERR(svn_fs_x__rev_file_init(&rev_file, context->fs, context->start_rev,
                                   scratch_pool));
   SVN_ERR(svn_fs_x__rev_file_get(&file, rev_file));
-  SVN_ERR(copy_file_data(context, context->pack_file, file, finfo.size,
+
+  SVN_ERR(svn_io_file_size_get(&revfile_size, file, scratch_pool));
+  SVN_ERR(copy_file_data(context, context->pack_file, file, revfile_size,
                          iterpool));
 
   /* mark the start of a new revision */
@@ -1861,7 +1856,7 @@ append_revision(pack_context_t *context,
 
   /* read the phys-to-log index file until we covered the whole rev file.
    * That index contains enough info to build both target indexes from it. */
-  while (offset < finfo.size)
+  while (offset < revfile_size)
     {
       /* read one cluster */
       int i;
@@ -1883,7 +1878,7 @@ append_revision(pack_context_t *context,
 
           /* process entry while inside the rev file */
           offset = entry->offset;
-          if (offset < finfo.size)
+          if (offset < revfile_size)
             {
               /* there should be true containers */
               SVN_ERR_ASSERT(entry->item_count == 1);
@@ -1902,7 +1897,7 @@ append_revision(pack_context_t *context,
     }
 
   svn_pool_destroy(iterpool);
-  context->pack_offset += finfo.size;
+  context->pack_offset += revfile_size;
 
   return SVN_NO_ERROR;
 }
@@ -2083,7 +2078,8 @@ pack_shard(const char *dir,
                         scratch_pool));
 
   /* Perform all fsyncs through this instance. */
-  SVN_ERR(svn_fs_x__batch_fsync_create(&batch, scratch_pool));
+  SVN_ERR(svn_fs_x__batch_fsync_create(&batch, ffd->flush_to_disk,
+                                       scratch_pool));
 
   /* Some useful paths. */
   pack_file_dir = svn_dirent_join(dir,

Modified: subversion/branches/ra-git/subversion/libsvn_fs_x/rep-cache.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_x/rep-cache.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_x/rep-cache.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_x/rep-cache.c Tue Oct 11 
09:11:50 2016
@@ -100,12 +100,16 @@ open_rep_cache(void *baton,
                            0, NULL, 0,
                            fs->pool, scratch_pool));
 
-  SVN_ERR(svn_sqlite__read_schema_version(&version, sdb, scratch_pool));
+  SVN_SQLITE__ERR_CLOSE(svn_sqlite__read_schema_version(&version, sdb,
+                                                        scratch_pool),
+                        sdb);
   if (version < REP_CACHE_SCHEMA_FORMAT)
     {
       /* Must be 0 -- an uninitialized (no schema) database. Create
          the schema. Results in schema version of 1.  */
-      SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_CREATE_SCHEMA));
+      SVN_SQLITE__ERR_CLOSE(svn_sqlite__exec_statements(sdb,
+                                                        STMT_CREATE_SCHEMA),
+                            sdb);
     }
 
   /* This is used as a flag that the database is available so don't
@@ -126,6 +130,21 @@ svn_fs_x__open_rep_cache(svn_fs_t *fs,
 }
 
 svn_error_t *
+svn_fs_x__close_rep_cache(svn_fs_t *fs)
+{
+  svn_fs_x__data_t *ffd = fs->fsap_data;
+
+  if (ffd->rep_cache_db)
+    {
+      SVN_ERR(svn_sqlite__close(ffd->rep_cache_db));
+      ffd->rep_cache_db = NULL;
+      ffd->rep_cache_db_opened = 0;
+    }
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
 svn_fs_x__exists_rep_cache(svn_boolean_t *exists,
                            svn_fs_t *fs,
                            apr_pool_t *scratch_pool)
@@ -236,7 +255,7 @@ svn_fs_x__walk_rep_reference(svn_fs_t *f
    If you extend this function, check the callsite to see if you have
    to make it not-ignore additional error codes.  */
 svn_error_t *
-svn_fs_x__get_rep_reference(svn_fs_x__representation_t **rep,
+svn_fs_x__get_rep_reference(svn_fs_x__representation_t **rep_p,
                             svn_fs_t *fs,
                             svn_checksum_t *checksum,
                             apr_pool_t *result_pool,
@@ -245,6 +264,7 @@ svn_fs_x__get_rep_reference(svn_fs_x__re
   svn_fs_x__data_t *ffd = fs->fsap_data;
   svn_sqlite__stmt_t *stmt;
   svn_boolean_t have_row;
+  svn_fs_x__representation_t *rep;
 
   SVN_ERR_ASSERT(ffd->rep_sharing_allowed);
   if (! ffd->rep_cache_db)
@@ -263,24 +283,23 @@ svn_fs_x__get_rep_reference(svn_fs_x__re
   SVN_ERR(svn_sqlite__step(&have_row, stmt));
   if (have_row)
     {
-      *rep = apr_pcalloc(result_pool, sizeof(**rep));
-      memcpy((*rep)->sha1_digest, checksum->digest,
-             sizeof((*rep)->sha1_digest));
-      (*rep)->has_sha1 = TRUE;
-      (*rep)->id.change_set = svn_sqlite__column_revnum(stmt, 0);
-      (*rep)->id.number = svn_sqlite__column_int64(stmt, 1);
-      (*rep)->size = svn_sqlite__column_int64(stmt, 2);
-      (*rep)->expanded_size = svn_sqlite__column_int64(stmt, 3);
+      rep = apr_pcalloc(result_pool, sizeof(*rep));
+      memcpy(rep->sha1_digest, checksum->digest, sizeof(rep->sha1_digest));
+      rep->has_sha1 = TRUE;
+      rep->id.change_set = svn_sqlite__column_revnum(stmt, 0);
+      rep->id.number = svn_sqlite__column_int64(stmt, 1);
+      rep->size = svn_sqlite__column_int64(stmt, 2);
+      rep->expanded_size = svn_sqlite__column_int64(stmt, 3);
     }
   else
-    *rep = NULL;
+    rep = NULL;
 
   SVN_ERR(svn_sqlite__reset(stmt));
 
-  if (*rep)
+  if (rep)
     {
       /* Check that REP refers to a revision that exists in FS. */
-      svn_revnum_t revision = svn_fs_x__get_revnum((*rep)->id.change_set);
+      svn_revnum_t revision = svn_fs_x__get_revnum(rep->id.change_set);
       svn_error_t *err = svn_fs_x__ensure_revision_exists(revision, fs,
                                                           scratch_pool);
       if (err)
@@ -289,6 +308,7 @@ svn_fs_x__get_rep_reference(svn_fs_x__re
                    svn_checksum_to_cstring_display(checksum, scratch_pool));
     }
 
+  *rep_p = rep;
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/ra-git/subversion/libsvn_fs_x/rep-cache.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_x/rep-cache.h?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_x/rep-cache.h (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_x/rep-cache.h Tue Oct 11 
09:11:50 2016
@@ -40,6 +40,10 @@ svn_error_t *
 svn_fs_x__open_rep_cache(svn_fs_t *fs,
                          apr_pool_t *scratch_pool);
 
+/* Close the rep cache database associated with FS. */
+svn_error_t *
+svn_fs_x__close_rep_cache(svn_fs_t *fs);
+
 /* Set *EXISTS to TRUE iff the rep-cache DB file exists. */
 svn_error_t *
 svn_fs_x__exists_rep_cache(svn_boolean_t *exists,
@@ -61,11 +65,12 @@ svn_fs_x__walk_rep_reference(svn_fs_t *f
                              apr_pool_t *scratch_pool);
 
 /* Return the representation REP in FS which has fulltext CHECKSUM.
-   REP is allocated in RESULT_POOL.  If the rep cache database has not been
-   opened, just set *REP to NULL.  Returns SVN_ERR_FS_CORRUPT if a reference
-   beyond HEAD is detected.  Uses SCRATCH_POOL for temporary allocations. */
+   *REP_P is allocated in RESULT_POOL.  If the rep cache database has not
+   been opened, just set *REP_P to NULL.  Returns SVN_ERR_FS_CORRUPT if
+   a reference beyond HEAD is detected.  Uses SCRATCH_POOL for temporary
+   allocations.*/
 svn_error_t *
-svn_fs_x__get_rep_reference(svn_fs_x__representation_t **rep,
+svn_fs_x__get_rep_reference(svn_fs_x__representation_t **rep_p,
                             svn_fs_t *fs,
                             svn_checksum_t *checksum,
                             apr_pool_t *result_pool,

Modified: subversion/branches/ra-git/subversion/libsvn_fs_x/rev_file.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_x/rev_file.c?rev=1764214&r1=1764213&r2=1764214&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_x/rev_file.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_x/rev_file.c Tue Oct 11 
09:11:50 2016
@@ -192,7 +192,7 @@ get_file_pool(svn_fs_x__revision_file_t
   return file->pool;
 }
 
-/* Core implementation of svn_fs_fs__open_pack_or_rev_file working on an
+/* Core implementation of svn_fs_x__open_pack_or_rev_file working on an
  * existing, initialized FILE structure.  If WRITABLE is TRUE, give write
  * access to the file - temporarily resetting the r/o state if necessary.
  */
@@ -490,8 +490,8 @@ svn_fs_x__rev_file_offset(apr_off_t *off
                           svn_fs_x__revision_file_t *file)
 {
   SVN_ERR(auto_open(file));
-  return svn_error_trace(svn_fs_x__get_file_offset(offset, file->file,
-                                                   file->pool));
+  return svn_error_trace(svn_io_file_get_offset(offset, file->file,
+                                                file->pool));
 }
 
 svn_error_t *


Reply via email to