Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/fs.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/fs.h?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_fs/fs.h (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_fs/fs.h Sat May 23 
14:16:56 2020
@@ -188,6 +188,18 @@ extern "C" {
 /* The minimum format number that supports svndiff version 2. */
 #define SVN_FS_FS__MIN_SVNDIFF2_FORMAT 8
 
+/* The minimum format number that supports the special notation ("-")
+   for optional values that are not present in the representation strings,
+   such as SHA1 or the uniquifier.  For example:
+
+     15 0 563 7809 28ef320a82e7bd11eebdf3502d69e608 - 14-g/_5
+ */
+#define SVN_FS_FS__MIN_REP_STRING_OPTIONAL_VALUES_FORMAT 8
+
+ /* The minimum format number that supports V2 schema of the rep-cache.db
+    database. */
+#define SVN_FS_FS__MIN_REP_CACHE_SCHEMA_V2_FORMAT 8
+
 /* On most operating systems apr implements file locks per process, not
    per file.  On Windows apr implements the locking as per file handle
    locks, so we don't have to add our own mutex for just in-process

Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/fs_fs.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/fs_fs.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_fs/fs_fs.c Sat May 23 
14:16:56 2020
@@ -37,6 +37,7 @@
 #include "cached_data.h"
 #include "id.h"
 #include "index.h"
+#include "low_level.h"
 #include "rep-cache.h"
 #include "revprops.h"
 #include "transaction.h"
@@ -1151,8 +1152,8 @@ write_config(svn_fs_t *fs,
 "[" CONFIG_SECTION_DEBUG "]"                                                 NL
 "###"                                                                        NL
 "### Whether to verify each new revision immediately before finalizing"      NL
-"### the commit. The default is false in release-mode builds, and true"      NL
-"### in debug-mode builds."                                                  NL
+"### the commit.  This is disabled by default except in maintainer-mode"     NL
+"### builds."                                                                NL
 "# " CONFIG_OPTION_VERIFY_BEFORE_COMMIT " = false"                           NL
 ;
 #undef NL
@@ -1470,7 +1471,10 @@ svn_fs_fs__min_unpacked_rev(svn_revnum_t
 {
   fs_fs_data_t *ffd = fs->fsap_data;
 
-  SVN_ERR(svn_fs_fs__update_min_unpacked_rev(fs, pool));
+  /* Calling this for pre-v4 repos is illegal. */
+  if (ffd->format >= SVN_FS_FS__MIN_PACKED_FORMAT)
+    SVN_ERR(svn_fs_fs__update_min_unpacked_rev(fs, pool));
+
   *min_unpacked = ffd->min_unpacked_rev;
 
   return SVN_NO_ERROR;
@@ -2340,3 +2344,181 @@ svn_fs_fs__info_config_files(apr_array_h
                                                          result_pool);
   return SVN_NO_ERROR;
 }
+
+/* If no SHA1 checksum is stored in REP->SHA1_DIGEST yet, compute the
+ * SHA1 checksum and fill it in. Use POOL for temporary allocations. */
+static svn_error_t *
+ensure_representation_sha1(svn_fs_t *fs,
+                           representation_t *rep,
+                           apr_pool_t *pool)
+{
+  if (!rep->has_sha1)
+    {
+      svn_stream_t *contents;
+      svn_checksum_t *checksum;
+
+      SVN_ERR(svn_fs_fs__get_contents(&contents, fs, rep, FALSE, pool));
+      SVN_ERR(svn_stream_contents_checksum(&checksum, contents,
+                                           svn_checksum_sha1, pool, pool));
+
+      memcpy(rep->sha1_digest, checksum->digest, APR_SHA1_DIGESTSIZE);
+      rep->has_sha1 = TRUE;
+    }
+
+  return SVN_NO_ERROR;
+}
+
+/* Recursively index (in the rep-cache) the filesystem node with the
+ * given ID, located in revision REV and its matching REV_FILE (if the
+ * node ID cannot be found in this revision, do nothing).
+ * Compute the SHA1 checksum of the node's representation and add
+ * a corresponding entry to the repository's rep-cache.
+ * If the node represents a directory this function will recurse and
+ * index all children of this directory as well. */
+static svn_error_t *
+reindex_node(svn_fs_t *fs,
+             const svn_fs_id_t *id,
+             svn_revnum_t rev,
+             svn_fs_fs__revision_file_t *rev_file,
+             svn_cancel_func_t cancel_func,
+             void *cancel_baton,
+             apr_pool_t *pool)
+{
+  node_revision_t *noderev;
+  apr_off_t offset;
+
+  if (svn_fs_fs__id_rev(id) != rev)
+    {
+      return SVN_NO_ERROR;
+    }
+
+  if (cancel_func)
+    SVN_ERR(cancel_func(cancel_baton));
+
+  SVN_ERR(svn_fs_fs__item_offset(&offset, fs, rev_file, rev, NULL,
+                                 svn_fs_fs__id_item(id), pool));
+
+  SVN_ERR(svn_io_file_seek(rev_file->file, APR_SET, &offset, pool));
+  SVN_ERR(svn_fs_fs__read_noderev(&noderev, rev_file->stream,
+                                  pool, pool));
+
+  /* Make sure EXPANDED_SIZE has the correct value for every rep. */
+  SVN_ERR(svn_fs_fs__fixup_expanded_size(fs, noderev->data_rep, pool));
+  SVN_ERR(svn_fs_fs__fixup_expanded_size(fs, noderev->prop_rep, pool));
+
+  /* First reindex sub-directory to match write_final_rev() behavior. */
+  if (noderev->kind == svn_node_dir)
+    {
+      apr_array_header_t *entries;
+
+      SVN_ERR(svn_fs_fs__rep_contents_dir(&entries, fs, noderev, pool, pool));
+
+      if (entries->nelts > 0)
+        {
+          int i;
+          apr_pool_t *iterpool;
+
+          iterpool = svn_pool_create(pool);
+          for (i = 0; i < entries->nelts; i++)
+            {
+              const svn_fs_dirent_t *dirent;
+
+              svn_pool_clear(iterpool);
+
+              dirent = APR_ARRAY_IDX(entries, i, svn_fs_dirent_t *);
+
+              SVN_ERR(reindex_node(fs, dirent->id, rev, rev_file,
+                                   cancel_func, cancel_baton, iterpool));
+            }
+          svn_pool_destroy(iterpool);
+        }
+    }
+
+  if (noderev->data_rep && noderev->data_rep->revision == rev &&
+      noderev->kind == svn_node_file)
+    {
+      SVN_ERR(ensure_representation_sha1(fs, noderev->data_rep, pool));
+      SVN_ERR(svn_fs_fs__set_rep_reference(fs, noderev->data_rep, pool));
+    }
+
+  if (noderev->prop_rep && noderev->prop_rep->revision == rev)
+    {
+      SVN_ERR(ensure_representation_sha1(fs, noderev->prop_rep, pool));
+      SVN_ERR(svn_fs_fs__set_rep_reference(fs, noderev->prop_rep, pool));
+    }
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_fs_fs__build_rep_cache(svn_fs_t *fs,
+                           svn_revnum_t start_rev,
+                           svn_revnum_t end_rev,
+                           svn_fs_progress_notify_func_t progress_func,
+                           void *progress_baton,
+                           svn_cancel_func_t cancel_func,
+                           void *cancel_baton,
+                           apr_pool_t *pool)
+{
+  fs_fs_data_t *ffd = fs->fsap_data;
+  apr_pool_t *iterpool;
+  svn_revnum_t rev;
+
+  if (ffd->format < SVN_FS_FS__MIN_REP_SHARING_FORMAT)
+    {
+      return svn_error_createf(SVN_ERR_FS_REP_SHARING_NOT_SUPPORTED, NULL,
+                               _("FSFS format (%d) too old for rep-sharing; "
+                                 "please upgrade the filesystem."),
+                               ffd->format);
+    }
+
+  if (!ffd->rep_sharing_allowed)
+    {
+      return svn_error_create(SVN_ERR_FS_REP_SHARING_NOT_ALLOWED, NULL,
+                              _("Filesystem does not allow rep-sharing."));
+    }
+
+  /* Do not build rep-cache for revision zero to match
+   * svn_fs_fs__create() behavior. */
+  if (start_rev == SVN_INVALID_REVNUM)
+    start_rev = 1;
+
+  if (end_rev == SVN_INVALID_REVNUM)
+    SVN_ERR(svn_fs_fs__youngest_rev(&end_rev, fs, pool));
+
+  /* Do nothing for empty FS. */
+  if (start_rev > end_rev)
+    {
+      return SVN_NO_ERROR;
+    }
+
+  if (!ffd->rep_cache_db)
+    SVN_ERR(svn_fs_fs__open_rep_cache(fs, pool));
+
+  iterpool = svn_pool_create(pool);
+  for (rev = start_rev; rev <= end_rev; rev++)
+    {
+      svn_fs_id_t *root_id;
+      svn_fs_fs__revision_file_t *file;
+      svn_error_t *err;
+
+      svn_pool_clear(iterpool);
+
+      if (progress_func)
+        progress_func(rev, progress_baton, iterpool);
+
+      SVN_ERR(svn_fs_fs__open_pack_or_rev_file(&file, fs, rev,
+                                               iterpool, iterpool));
+      SVN_ERR(svn_fs_fs__rev_get_root(&root_id, fs, rev, iterpool, iterpool));
+
+      SVN_ERR(svn_sqlite__begin_transaction(ffd->rep_cache_db));
+      err = reindex_node(fs, root_id, rev, file, cancel_func, cancel_baton, 
iterpool);
+      SVN_ERR(svn_sqlite__finish_transaction(ffd->rep_cache_db, err));
+
+      SVN_ERR(svn_fs_fs__close_revision_file(file));
+    }
+
+  svn_pool_destroy(iterpool);
+
+  return SVN_NO_ERROR;
+}

Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/fs_fs.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/fs_fs.h?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_fs/fs_fs.h (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_fs/fs_fs.h Sat May 23 
14:16:56 2020
@@ -304,4 +304,75 @@ svn_fs_fs__initialize_txn_caches(svn_fs_
 void
 svn_fs_fs__reset_txn_caches(svn_fs_t *fs);
 
+/* Scan all contents of the repository FS and return statistics in *STATS,
+ * allocated in RESULT_POOL.  Report progress through PROGRESS_FUNC with
+ * PROGRESS_BATON, if PROGRESS_FUNC is not NULL.
+ * Use SCRATCH_POOL for temporary allocations.
+ */
+svn_error_t *
+svn_fs_fs__get_stats(svn_fs_fs__stats_t **stats,
+                     svn_fs_t *fs,
+                     svn_fs_progress_notify_func_t progress_func,
+                     void *progress_baton,
+                     svn_cancel_func_t cancel_func,
+                     void *cancel_baton,
+                     apr_pool_t *result_pool,
+                     apr_pool_t *scratch_pool);
+
+/* Read the P2L index for the rev / pack file containing REVISION in FS.
+ * For each index entry, invoke CALLBACK_FUNC with CALLBACK_BATON.
+ * If not NULL, call CANCEL_FUNC with CANCEL_BATON from time to time.
+ * Use SCRATCH_POOL for temporary allocations.
+ */
+svn_error_t *
+svn_fs_fs__dump_index(svn_fs_t *fs,
+                      svn_revnum_t revision,
+                      svn_fs_fs__dump_index_func_t callback_func,
+                      void *callback_baton,
+                      svn_cancel_func_t cancel_func,
+                      void *cancel_baton,
+                      apr_pool_t *scratch_pool);
+
+
+/* Rewrite the respective index information of the rev / pack file in FS
+ * containing REVISION and use the svn_fs_fs__p2l_entry_t * array ENTRIES
+ * as the new index contents.  Allocate temporaries from SCRATCH_POOL.
+ *
+ * Note that this becomes a no-op if ENTRIES is empty.  You may use a zero-
+ * sized empty entry instead.
+ */
+svn_error_t *
+svn_fs_fs__load_index(svn_fs_t *fs,
+                      svn_revnum_t revision,
+                      apr_array_header_t *entries,
+                      apr_pool_t *scratch_pool);
+
+/* Set *REV_SIZE to the total size of objects belonging to revision REVISION
+ * in FS. The size includes revision properties and excludes indexes.
+ */
+svn_error_t *
+svn_fs_fs__revision_size(apr_off_t *rev_size,
+                         svn_fs_t *fs,
+                         svn_revnum_t revision,
+                         apr_pool_t *scratch_pool);
+
+/* Add missing entries to the rep-cache on the filesystem FS. Process data
+ * in revisions START_REV through END_REV inclusive. If START_REV is
+ * SVN_INVALID_REVNUM, start at revision 1; if END_REV is SVN_INVALID_REVNUM,
+ * end at the head revision. If the rep-cache does not exist, then create it.
+ *
+ * Indicate progress via the optional PROGRESS_FUNC callback using
+ * PROGRESS_BATON. The optional CANCEL_FUNC will periodically be called with
+ * CANCEL_BATON to allow cancellation. Use POOL for temporary allocations.
+ */
+svn_error_t *
+svn_fs_fs__build_rep_cache(svn_fs_t *fs,
+                           svn_revnum_t start_rev,
+                           svn_revnum_t end_rev,
+                           svn_fs_progress_notify_func_t progress_func,
+                           void *progress_baton,
+                           svn_cancel_func_t cancel_func,
+                           void *cancel_baton,
+                           apr_pool_t *pool);
+
 #endif

Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/hotcopy.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/hotcopy.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_fs/hotcopy.c (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_fs/hotcopy.c Sat May 23 
14:16:56 2020
@@ -922,7 +922,7 @@ hotcopy_body(void *baton, apr_pool_t *po
     SVN_ERR(cancel_func(cancel_baton));
 
   /* Split the logic for new and old FS formats. The latter is much simpler
-   * due to the absense of sharding and packing. However, it requires special
+   * due to the absence of sharding and packing. However, it requires special
    * care when updating the 'current' file (which contains not just the
    * revision number, but also the next-ID counters). */
   if (src_ffd->format >= SVN_FS_FS__MIN_NO_GLOBAL_IDS_FORMAT)

Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/id.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/id.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_fs/id.c (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_fs/id.c Sat May 23 
14:16:56 2020
@@ -591,7 +591,8 @@ svn_fs_fs__id_parse(const svn_fs_id_t **
   svn_fs_id_t *id = id_parse(data, pool);
   if (id == NULL)
     return svn_error_createf(SVN_ERR_FS_MALFORMED_NODEREV_ID, NULL,
-                             "Malformed node revision ID string");
+                             "Malformed node revision ID string '%s'",
+                             data);
 
   *id_p = id;
 

Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/index.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/index.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_fs/index.c (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_fs/index.c Sat May 23 
14:16:56 2020
@@ -2522,8 +2522,8 @@ get_p2l_page(apr_array_header_t **entrie
  * MIN_OFFSET.  Set *END to TRUE if the caller should stop refeching.
  *
  * *BATON will be updated with the selected page's info and SCRATCH_POOL
- * will be used for temporary allocations.  If the data is alread in the
- * cache, descrease *LEAKING_BUCKET and increase it otherwise.  With that
+ * will be used for temporary allocations.  If the data is already in the
+ * cache, decrease *LEAKING_BUCKET and increase it otherwise.  With that
  * pattern we will still read all pages from the block even if some of
  * them survived in the cached.
  */
@@ -2681,7 +2681,7 @@ append_p2l_entries(apr_array_header_t *e
     }
 }
 
-/* Auxilliary struct passed to p2l_entries_func selecting the relevant
+/* Auxiliary struct passed to p2l_entries_func selecting the relevant
  * data range. */
 typedef struct p2l_entries_baton_t
 {
@@ -3191,9 +3191,9 @@ compare_p2l_entry_revision(const void *l
                            const void *rhs)
 {
   const svn_fs_fs__p2l_entry_t *lhs_entry
-    =*(const svn_fs_fs__p2l_entry_t **)lhs;
+    =*(const svn_fs_fs__p2l_entry_t *const *)lhs;
   const svn_fs_fs__p2l_entry_t *rhs_entry
-    =*(const svn_fs_fs__p2l_entry_t **)rhs;
+    =*(const svn_fs_fs__p2l_entry_t *const *)rhs;
 
   if (lhs_entry->item.revision < rhs_entry->item.revision)
     return -1;

Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/load-index.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/load-index.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_fs/load-index.c 
(original)
+++ subversion/branches/addremove/subversion/libsvn_fs_fs/load-index.c Sat May 
23 14:16:56 2020
@@ -22,9 +22,9 @@
 
 #include "svn_pools.h"
 
-#include "private/svn_fs_fs_private.h"
 #include "private/svn_sorts_private.h"
 
+#include "fs_fs.h"
 #include "index.h"
 #include "util.h"
 #include "transaction.h"
@@ -83,9 +83,9 @@ compare_p2l_entry_revision(const void *l
                            const void *rhs)
 {
   const svn_fs_fs__p2l_entry_t *lhs_entry
-    =*(const svn_fs_fs__p2l_entry_t **)lhs;
+    =*(const svn_fs_fs__p2l_entry_t *const *)lhs;
   const svn_fs_fs__p2l_entry_t *rhs_entry
-    =*(const svn_fs_fs__p2l_entry_t **)rhs;
+    =*(const svn_fs_fs__p2l_entry_t *const *)rhs;
 
   if (lhs_entry->offset < rhs_entry->offset)
     return -1;

Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/low_level.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/low_level.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_fs/low_level.c (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_fs/low_level.c Sat May 
23 14:16:56 2020
@@ -248,16 +248,16 @@ svn_fs_fs__parse_footer(apr_off_t *l2p_o
                             rev));
   *p2l_offset = (apr_off_t)val;
 
-  /* The P2L indes follows the L2P index */
+  /* The P2L index follows the L2P index */
   if (*p2l_offset <= *l2p_offset)
     return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
                              "P2L offset %s must be larger than L2P offset %s"
                              " in r%ld footer",
                              apr_psprintf(result_pool,
-                                          "%" APR_UINT64_T_HEX_FMT,
+                                          "0x%" APR_UINT64_T_HEX_FMT,
                                           (apr_uint64_t)*p2l_offset),
                              apr_psprintf(result_pool,
-                                          "%" APR_UINT64_T_HEX_FMT,
+                                          "0x%" APR_UINT64_T_HEX_FMT,
                                           (apr_uint64_t)*l2p_offset),
                              rev);
 
@@ -506,7 +506,7 @@ svn_fs_fs__read_changes(apr_array_header
       SVN_ERR(read_change(&change, stream, result_pool, iterpool));
       if (!change)
         break;
- 
+
       APR_ARRAY_PUSH(*changes, change_t*) = change;
     }
   svn_pool_destroy(iterpool);
@@ -670,7 +670,7 @@ svn_fs_fs__write_changes(svn_stream_t *s
     }
 
   if (terminate_list)
-    svn_stream_puts(stream, "\n");
+    SVN_ERR(svn_stream_puts(stream, "\n"));
 
   svn_pool_destroy(iterpool);
 
@@ -741,6 +741,9 @@ read_header_block(apr_hash_t **headers,
   return SVN_NO_ERROR;
 }
 
+/* ### Ouch!  The implementation of this function currently modifies
+   ### the input string when tokenizing it (so the input cannot be
+   ### used after that). */
 svn_error_t *
 svn_fs_fs__parse_representation(representation_t **rep_p,
                                 svn_stringbuf_t *text,
@@ -811,13 +814,21 @@ svn_fs_fs__parse_representation(represen
   if (str == NULL)
     return SVN_NO_ERROR;
 
-  /* Read the SHA1 hash. */
-  if (strlen(str) != (APR_SHA1_DIGESTSIZE * 2))
-    return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
-                            _("Malformed text representation offset line in 
node-rev"));
+  /* Is the SHA1 hash present? */
+  if (str[0] == '-' && str[1] == 0)
+    {
+      checksum = NULL;
+    }
+  else
+    {
+      /* Read the SHA1 hash. */
+      if (strlen(str) != (APR_SHA1_DIGESTSIZE * 2))
+        return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
+                                _("Malformed text representation offset line 
in node-rev"));
 
-  SVN_ERR(svn_checksum_parse_hex(&checksum, svn_checksum_sha1, str,
-                                 scratch_pool));
+      SVN_ERR(svn_checksum_parse_hex(&checksum, svn_checksum_sha1, str,
+                                     scratch_pool));
+    }
 
   /* We do have a valid SHA1 but it might be all 0.
      We cannot be sure where that came from (Alas! legacy), so let's not
@@ -829,21 +840,36 @@ svn_fs_fs__parse_representation(represen
   if (checksum)
     memcpy(rep->sha1_digest, checksum->digest, sizeof(rep->sha1_digest));
 
-  /* Read the uniquifier. */
-  str = svn_cstring_tokenize("/", &string);
+  str = svn_cstring_tokenize(" ", &string);
   if (str == NULL)
     return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
                             _("Malformed text representation offset line in 
node-rev"));
 
-  SVN_ERR(svn_fs_fs__id_txn_parse(&rep->uniquifier.noderev_txn_id, str));
+  /* Is the uniquifier present? */
+  if (str[0] == '-' && str[1] == 0)
+    {
+      end = string;
+    }
+  else
+    {
+      char *substring = str;
 
-  str = svn_cstring_tokenize(" ", &string);
-  if (str == NULL || *str != '_')
-    return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
-                            _("Malformed text representation offset line in 
node-rev"));
+      /* Read the uniquifier. */
+      str = svn_cstring_tokenize("/", &substring);
+      if (str == NULL)
+        return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
+                                _("Malformed text representation offset line 
in node-rev"));
+
+      SVN_ERR(svn_fs_fs__id_txn_parse(&rep->uniquifier.noderev_txn_id, str));
+
+      str = svn_cstring_tokenize(" ", &substring);
+      if (str == NULL || *str != '_')
+        return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
+                                _("Malformed text representation offset line 
in node-rev"));
 
-  ++str;
-  rep->uniquifier.number = svn__base36toui64(&end, str);
+      ++str;
+      rep->uniquifier.number = svn__base36toui64(&end, str);
+    }
 
   if (*end)
     return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
@@ -1034,25 +1060,37 @@ svn_fs_fs__read_noderev(node_revision_t
 }
 
 /* Return a textual representation of the DIGEST of given KIND.
- * If IS_NULL is TRUE, no digest is available.
  * Allocate the result in RESULT_POOL.
  */
 static const char *
 format_digest(const unsigned char *digest,
               svn_checksum_kind_t kind,
-              svn_boolean_t is_null,
               apr_pool_t *result_pool)
 {
   svn_checksum_t checksum;
   checksum.digest = digest;
   checksum.kind = kind;
 
-  if (is_null)
-    return "(null)";
-
   return svn_checksum_to_cstring_display(&checksum, result_pool);
 }
 
+/* Return a textual representation of the uniquifier represented
+ * by NODEREV_TXN_ID and NUMBER.  Use POOL for the allocations.
+ */
+static const char *
+format_uniquifier(const svn_fs_fs__id_part_t *noderev_txn_id,
+                  apr_uint64_t number,
+                  apr_pool_t *pool)
+{
+  char buf[SVN_INT64_BUFFER_SIZE];
+  const char *txn_id_str;
+
+  txn_id_str = svn_fs_fs__id_txn_unparse(noderev_txn_id, pool);
+  svn__ui64tobase36(buf, number);
+
+  return apr_psprintf(pool, "%s/_%s", txn_id_str, buf);
+}
+
 svn_stringbuf_t *
 svn_fs_fs__unparse_representation(representation_t *rep,
                                   int format,
@@ -1060,32 +1098,80 @@ svn_fs_fs__unparse_representation(repres
                                   apr_pool_t *result_pool,
                                   apr_pool_t *scratch_pool)
 {
-  char buffer[SVN_INT64_BUFFER_SIZE];
+  svn_stringbuf_t *str;
+  const char *sha1_str;
+  const char *uniquifier_str;
+
   if (svn_fs_fs__id_txn_used(&rep->txn_id) && mutable_rep_truncated)
     return svn_stringbuf_ncreate("-1", 2, result_pool);
 
-  if (format < SVN_FS_FS__MIN_REP_SHARING_FORMAT || !rep->has_sha1)
-    return svn_stringbuf_createf
-            (result_pool, "%ld %" APR_UINT64_T_FMT " %" SVN_FILESIZE_T_FMT
-             " %" SVN_FILESIZE_T_FMT " %s",
-             rep->revision, rep->item_index, rep->size,
-             rep->expanded_size,
-             format_digest(rep->md5_digest, svn_checksum_md5, FALSE,
-                           scratch_pool));
-
-  svn__ui64tobase36(buffer, rep->uniquifier.number);
-  return svn_stringbuf_createf
-          (result_pool, "%ld %" APR_UINT64_T_FMT " %" SVN_FILESIZE_T_FMT
-           " %" SVN_FILESIZE_T_FMT " %s %s %s/_%s",
-           rep->revision, rep->item_index, rep->size,
-           rep->expanded_size,
-           format_digest(rep->md5_digest, svn_checksum_md5,
-                         FALSE, scratch_pool),
-           format_digest(rep->sha1_digest, svn_checksum_sha1,
-                         !rep->has_sha1, scratch_pool),
-           svn_fs_fs__id_txn_unparse(&rep->uniquifier.noderev_txn_id,
-                                     scratch_pool),
-           buffer);
+  /* Format of the string:
+     <rev> <item_index> <size> <expanded-size> <md5> [<sha1>] [<uniquifier>]
+   */
+  str = svn_stringbuf_createf(
+          result_pool,
+          "%ld"
+          " %" APR_UINT64_T_FMT
+          " %" SVN_FILESIZE_T_FMT
+          " %" SVN_FILESIZE_T_FMT
+          " %s",
+          rep->revision,
+          rep->item_index,
+          rep->size,
+          rep->expanded_size,
+          format_digest(rep->md5_digest, svn_checksum_md5, scratch_pool));
+
+  /* Compatibility: these formats don't understand <sha1> and <uniquifier>. */
+  if (format < SVN_FS_FS__MIN_REP_SHARING_FORMAT)
+    return str;
+
+  if (format < SVN_FS_FS__MIN_REP_STRING_OPTIONAL_VALUES_FORMAT)
+    {
+      /* Compatibility: these formats can only have <sha1> and <uniquifier>
+         present simultaneously, or don't have them at all. */
+      if (rep->has_sha1)
+        {
+          sha1_str = format_digest(rep->sha1_digest, svn_checksum_sha1,
+                                   scratch_pool);
+          uniquifier_str = format_uniquifier(&rep->uniquifier.noderev_txn_id,
+                                             rep->uniquifier.number,
+                                             scratch_pool);
+          svn_stringbuf_appendbyte(str, ' ');
+          svn_stringbuf_appendcstr(str, sha1_str);
+          svn_stringbuf_appendbyte(str, ' ');
+          svn_stringbuf_appendcstr(str, uniquifier_str);
+        }
+      return str;
+    }
+
+  /* The most recent formats support optional <sha1> and <uniquifier> values. 
*/
+  if (rep->has_sha1)
+    {
+      sha1_str = format_digest(rep->sha1_digest, svn_checksum_sha1,
+                               scratch_pool);
+    }
+  else
+    sha1_str = "-";
+
+  if (rep->uniquifier.number == 0 &&
+      rep->uniquifier.noderev_txn_id.number == 0 &&
+      rep->uniquifier.noderev_txn_id.revision == 0)
+    {
+      uniquifier_str = "-";
+    }
+  else
+    {
+      uniquifier_str = format_uniquifier(&rep->uniquifier.noderev_txn_id,
+                                         rep->uniquifier.number,
+                                         scratch_pool);
+    }
+
+  svn_stringbuf_appendbyte(str, ' ');
+  svn_stringbuf_appendcstr(str, sha1_str);
+  svn_stringbuf_appendbyte(str, ' ');
+  svn_stringbuf_appendcstr(str, uniquifier_str);
+
+  return str;
 }
 
 

Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/pack.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/pack.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_fs/pack.c (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_fs/pack.c Sat May 23 
14:16:56 2020
@@ -315,12 +315,12 @@ initialize_pack_context(pack_context_t *
   context->file_props = apr_array_make(pool, max_items,
                                        sizeof(svn_fs_fs__p2l_entry_t *));
   SVN_ERR(svn_io_open_unique_file3(&context->file_props_file, NULL, temp_dir,
-                                   svn_io_file_del_on_close, 
+                                   svn_io_file_del_on_close,
                                    context->info_pool, pool));
   context->dir_props = apr_array_make(pool, max_items,
                                       sizeof(svn_fs_fs__p2l_entry_t *));
   SVN_ERR(svn_io_open_unique_file3(&context->dir_props_file, NULL, temp_dir,
-                                   svn_io_file_del_on_close, 
+                                   svn_io_file_del_on_close,
                                    context->info_pool, pool));
 
   /* noderev and representation item bucket */
@@ -1701,7 +1701,7 @@ svn_fs_fs__get_packed_offset(apr_off_t *
   return svn_cache__set(ffd->packed_offset_cache, &shard, manifest, pool);
 }
 
-/* Packing logic for physical addresssing mode:
+/* Packing logic for physical addressing mode:
  * Simply concatenate all revision contents.
  *
  * Pack the revision shard starting at SHARD_REV containing exactly
@@ -2067,9 +2067,9 @@ pack_body(void *baton,
   if (fully_packed)
     {
       if (pb->notify_func)
-        (*pb->notify_func)(pb->notify_baton,
-                           ffd->min_unpacked_rev / ffd->max_files_per_dir,
-                           svn_fs_pack_notify_noop, pool);
+        SVN_ERR(pb->notify_func(pb->notify_baton,
+                                ffd->min_unpacked_rev / ffd->max_files_per_dir,
+                                svn_fs_pack_notify_noop, pool));
 
       return SVN_NO_ERROR;
     }
@@ -2122,7 +2122,7 @@ svn_fs_fs__pack(svn_fs_t *fs,
   if (!ffd->max_files_per_dir)
     {
       if (notify_func)
-        (*notify_func)(notify_baton, -1, svn_fs_pack_notify_noop, pool);
+        SVN_ERR(notify_func(notify_baton, -1, svn_fs_pack_notify_noop, pool));
 
       return SVN_NO_ERROR;
     }
@@ -2132,9 +2132,9 @@ svn_fs_fs__pack(svn_fs_t *fs,
   if (fully_packed)
     {
       if (notify_func)
-        (*notify_func)(notify_baton,
-                       ffd->min_unpacked_rev / ffd->max_files_per_dir,
-                       svn_fs_pack_notify_noop, pool);
+        SVN_ERR(notify_func(notify_baton,
+                            ffd->min_unpacked_rev / ffd->max_files_per_dir,
+                            svn_fs_pack_notify_noop, pool));
 
       return SVN_NO_ERROR;
     }

Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/recovery.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/recovery.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_fs/recovery.c (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_fs/recovery.c Sat May 23 
14:16:56 2020
@@ -471,9 +471,15 @@ recover_body(void *baton, apr_pool_t *po
     }
 
   /* Prune younger-than-(newfound-youngest) revisions from the rep
-     cache if sharing is enabled taking care not to create the cache
-     if it does not exist. */
-  if (ffd->rep_sharing_allowed)
+     cache, taking care not to create the cache if it does not exist.
+
+     We do this whenever rep-cache.db exists, whether it's currently enabled
+     or not, to prevent a data loss that could result from having revisions
+     created after this 'recover' operation referring to rep-cache.db rows
+     that were created before the recover and that point to revisions younger-
+     than-(newfound-youngest).
+   */
+  if (ffd->format >= SVN_FS_FS__MIN_REP_SHARING_FORMAT)
     {
       svn_boolean_t rep_cache_exists;
 

Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/rep-cache-db.sql
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/rep-cache-db.sql?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_fs/rep-cache-db.sql 
(original)
+++ subversion/branches/addremove/subversion/libsvn_fs_fs/rep-cache-db.sql Sat 
May 23 14:16:56 2020
@@ -21,7 +21,7 @@
  * ====================================================================
  */
 
--- STMT_CREATE_SCHEMA
+-- STMT_CREATE_SCHEMA_V1
 /* A table mapping representation hashes to locations in a rev file. */
 CREATE TABLE rep_cache (
   hash TEXT NOT NULL PRIMARY KEY,
@@ -33,36 +33,63 @@ CREATE TABLE rep_cache (
 
 PRAGMA USER_VERSION = 1;
 
+-- STMT_CREATE_SCHEMA_V2
+/* A table mapping representation hashes to locations in a rev file.
+   Same as in V1 schema, except that it uses the `WITHOUT ROWID` optimization:
+   https://sqlite.org/withoutrowid.html
+
+   Note that this optimization is only supported starting from SQLite version
+   3.8.2 (2013-12-06).  To keep compatibility with existing binaries, it is
+   only used for newer filesystem formats that were released together with
+   bumping the minimum required SQLite version.
+ */
+CREATE TABLE rep_cache (
+  hash TEXT NOT NULL PRIMARY KEY,
+  revision INTEGER NOT NULL,
+  offset INTEGER NOT NULL,
+  size INTEGER NOT NULL,
+  expanded_size INTEGER NOT NULL
+  ) WITHOUT ROWID;
+
+PRAGMA USER_VERSION = 2;
 
 -- STMT_GET_REP
+/* Works for both V1 and V2 schemas. */
 SELECT revision, offset, size, expanded_size
 FROM rep_cache
 WHERE hash = ?1
 
 -- STMT_SET_REP
-INSERT OR FAIL INTO rep_cache (hash, revision, offset, size, expanded_size)
+/* Works for both V1 and V2 schemas. */
+INSERT OR IGNORE INTO rep_cache (hash, revision, offset, size, expanded_size)
 VALUES (?1, ?2, ?3, ?4, ?5)
 
 -- STMT_GET_REPS_FOR_RANGE
+/* Works for both V1 and V2 schemas. */
 SELECT hash, revision, offset, size, expanded_size
 FROM rep_cache
 WHERE revision >= ?1 AND revision <= ?2
 
 -- STMT_GET_MAX_REV
+/* Works for both V1 and V2 schemas. */
 SELECT MAX(revision)
 FROM rep_cache
 
 -- STMT_DEL_REPS_YOUNGER_THAN_REV
+/* Works for both V1 and V2 schemas. */
 DELETE FROM rep_cache
 WHERE revision > ?1
 
 /* An INSERT takes an SQLite reserved lock that prevents other writes
    but doesn't block reads.  The incomplete transaction means that no
    permanent change is made to the database and the transaction is
-   removed when the database is closed.  */
+   removed when the database is closed.
+
+   Works for both V1 and V2 schemas.  */
 -- STMT_LOCK_REP
 BEGIN TRANSACTION;
 INSERT INTO rep_cache VALUES ('dummy', 0, 0, 0, 0)
 
 -- STMT_UNLOCK_REP
+/* Works for both V1 and V2 schemas. */
 ROLLBACK TRANSACTION;

Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/rep-cache.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/rep-cache.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_fs/rep-cache.c (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_fs/rep-cache.c Sat May 
23 14:16:56 2020
@@ -36,9 +36,6 @@
 
 #include "rep-cache-db.h"
 
-/* A few magic values */
-#define REP_CACHE_SCHEMA_FORMAT   1
-
 REP_CACHE_DB_SQL_DECLARE_STATEMENTS(statements);
 
 
@@ -102,13 +99,17 @@ open_rep_cache(void *baton,
 
   SVN_SQLITE__ERR_CLOSE(svn_sqlite__read_schema_version(&version, sdb, pool),
                         sdb);
-  if (version < REP_CACHE_SCHEMA_FORMAT)
+  /* If we have an uninitialized database, go ahead and create the schema. */
+  if (version <= 0)
     {
-      /* Must be 0 -- an uninitialized (no schema) database. Create
-         the schema. Results in schema version of 1.  */
-      SVN_SQLITE__ERR_CLOSE(svn_sqlite__exec_statements(sdb,
-                                                        STMT_CREATE_SCHEMA),
-                            sdb);
+      int stmt;
+
+      if (ffd->format >= SVN_FS_FS__MIN_REP_CACHE_SCHEMA_V2_FORMAT)
+        stmt = STMT_CREATE_SCHEMA_V2;
+      else
+        stmt = STMT_CREATE_SCHEMA_V1;
+
+      SVN_SQLITE__ERR_CLOSE(svn_sqlite__exec_statements(sdb, stmt), sdb);
     }
 
   /* This is used as a flag that the database is available so don't
@@ -327,7 +328,6 @@ svn_fs_fs__set_rep_reference(svn_fs_t *f
 {
   fs_fs_data_t *ffd = fs->fsap_data;
   svn_sqlite__stmt_t *stmt;
-  svn_error_t *err;
   svn_checksum_t checksum;
   checksum.kind = svn_checksum_sha1;
   checksum.digest = rep->sha1_digest;
@@ -350,28 +350,7 @@ svn_fs_fs__set_rep_reference(svn_fs_t *f
                             (apr_int64_t) rep->size,
                             (apr_int64_t) rep->expanded_size));
 
-  err = svn_sqlite__insert(NULL, stmt);
-  if (err)
-    {
-      representation_t *old_rep;
-
-      if (err->apr_err != SVN_ERR_SQLITE_CONSTRAINT)
-        return svn_error_trace(err);
-
-      svn_error_clear(err);
-
-      /* Constraint failed so the mapping for SHA1_CHECKSUM->REP
-         should exist.  If so that's cool -- just do nothing.  If not,
-         that's a red flag!  */
-      SVN_ERR(svn_fs_fs__get_rep_reference(&old_rep, fs, &checksum, pool));
-
-      if (!old_rep)
-        {
-          /* Something really odd at this point, we failed to insert the
-             checksum AND failed to read an existing checksum.  Do we need
-             to flag this? */
-        }
-    }
+  SVN_ERR(svn_sqlite__insert(NULL, stmt));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/revprops.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/revprops.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_fs/revprops.c (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_fs/revprops.c Sat May 23 
14:16:56 2020
@@ -261,7 +261,7 @@ cache_revprops(svn_boolean_t *is_cached,
 }
 
 /* Read the non-packed revprops for revision REV in FS, put them into the
- * revprop cache if PROPULATE_CACHE is set and return them in *PROPERTIES. 
+ * revprop cache if PROPULATE_CACHE is set and return them in *PROPERTIES.
  *
  * If the data could not be read due to an otherwise recoverable error,
  * leave *PROPERTIES unchanged. No error will be returned in that case.
@@ -671,6 +671,64 @@ read_pack_revprop(packed_revprops_t **re
 
   return SVN_NO_ERROR;
 }
+
+svn_error_t *
+svn_fs_fs__get_revision_props_size(apr_off_t *props_size_p,
+                                   svn_fs_t *fs,
+                                   svn_revnum_t rev,
+                                   apr_pool_t *scratch_pool)
+{
+  fs_fs_data_t *ffd = fs->fsap_data;
+
+  /* should they be available at all? */
+  SVN_ERR(svn_fs_fs__ensure_revision_exists(rev, fs, scratch_pool));
+
+  /* if REV had not been packed when we began, try reading it from the
+   * non-packed shard.  If that fails, we will fall through to packed
+   * shard reads. */
+  if (!svn_fs_fs__is_packed_revprop(fs, rev))
+    {
+      const char *path = svn_fs_fs__path_revprops(fs, rev, scratch_pool);
+      svn_error_t *err;
+      apr_file_t *file;
+      svn_filesize_t file_size;
+
+      err = svn_io_file_open(&file, path, APR_FOPEN_READ, APR_OS_DEFAULT,
+                             scratch_pool);
+      if (!err)
+        err = svn_io_file_size_get(&file_size, file, scratch_pool);
+      if (!err)
+        {
+          *props_size_p = (apr_off_t)file_size;
+          return SVN_NO_ERROR;
+        }
+      else if (!APR_STATUS_IS_ENOENT(err->apr_err)
+               || ffd->format < SVN_FS_FS__MIN_PACKED_REVPROP_FORMAT)
+        {
+          return svn_error_trace(err);
+        }
+
+      /* fall through: maybe the revision got packed while we were looking */
+      svn_error_clear(err);
+    }
+
+  /* Try reading packed revprops.  If that fails, REV is most
+   * likely invalid (or its revprops highly contested). */
+  {
+    packed_revprops_t *revprops;
+
+    /* ### This is inefficient -- reading all the revprops in a pack. We
+       should just read the index. */
+    SVN_ERR(read_pack_revprop(&revprops, fs, rev,
+                              TRUE /*read_all*/, FALSE /*populate_cache*/,
+                              scratch_pool));
+    *props_size_p = (apr_off_t)APR_ARRAY_IDX(revprops->sizes,
+                                             rev - revprops->start_revision,
+                                             apr_size_t);
+  }
+
+  return SVN_NO_ERROR;
+}
 
 /* Read the revprops for revision REV in FS and return them in *PROPERTIES_P.
  *

Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/revprops.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/revprops.h?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_fs/revprops.h (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_fs/revprops.h Sat May 23 
14:16:56 2020
@@ -62,6 +62,15 @@ svn_fs_fs__upgrade_cleanup_pack_revprops
 void
 svn_fs_fs__reset_revprop_cache(svn_fs_t *fs);
 
+/* Set *PROPS_SIZE_P to the size in bytes on disk of the revprops for
+ * revision REV in FS. The size excludes indexes.
+ */
+svn_error_t *
+svn_fs_fs__get_revision_props_size(apr_off_t *props_size_p,
+                                   svn_fs_t *fs,
+                                   svn_revnum_t rev,
+                                   apr_pool_t *scratch_pool);
+
 /* Read the revprops for revision REV in FS and return them in *PROPERTIES_P.
  * If REFRESH is set, clear the revprop cache before accessing the data.
  *

Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/stats.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/stats.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_fs/stats.c (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_fs/stats.c Sat May 23 
14:16:56 2020
@@ -28,7 +28,6 @@
 #include "private/svn_cache.h"
 #include "private/svn_sorts_private.h"
 #include "private/svn_string_private.h"
-#include "private/svn_fs_fs_private.h"
 
 #include "index.h"
 #include "pack.h"
@@ -37,6 +36,7 @@
 #include "fs_fs.h"
 #include "cached_data.h"
 #include "low_level.h"
+#include "revprops.h"
 
 #include "../libsvn_fs/fs-loader.h"
 
@@ -488,7 +488,7 @@ parse_representation(rep_stats_t **repre
             }
         }
 
-      svn_sort__array_insert(revision_info->representations, &result, idx);
+      SVN_ERR(svn_sort__array_insert2(revision_info->representations, &result, 
idx));
     }
 
   *representation = result;
@@ -1397,3 +1397,96 @@ svn_fs_fs__get_stats(svn_fs_fs__stats_t
 
   return SVN_NO_ERROR;
 }
+
+/* Baton for rev_size_index_entry_cb. */
+struct rev_size_baton_t {
+  svn_revnum_t revision;
+  apr_off_t rev_size;
+};
+
+/* Implements svn_fs_fs__dump_index_func_t, summing object sizes for
+ * revision BATON->revision into BATON->rev_size.
+ */
+static svn_error_t *
+rev_size_index_entry_cb(const svn_fs_fs__p2l_entry_t *entry,
+                        void *baton,
+                        apr_pool_t *scratch_pool)
+{
+  struct rev_size_baton_t *b = baton;
+
+  if (entry->item.revision == b->revision)
+    b->rev_size += entry->size;
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_fs_fs__revision_size(apr_off_t *rev_size,
+                         svn_fs_t *fs,
+                         svn_revnum_t revision,
+                         apr_pool_t *scratch_pool)
+{
+  /* Get the size of the revision (excluding rev-props) */
+  if (svn_fs_fs__use_log_addressing(fs))
+    {
+      /* This works for a packed or a non-packed revision.
+         We could provide an optimized case for a non-packed revision
+         using svn_fs_fs__p2l_get_max_offset(). */
+      struct rev_size_baton_t b = { 0, 0 };
+
+      b.revision = revision;
+      SVN_ERR(svn_fs_fs__dump_index(fs, revision,
+                                    rev_size_index_entry_cb, &b,
+                                    NULL, NULL, scratch_pool));
+      *rev_size = b.rev_size;
+    }
+  else
+    {
+      svn_fs_fs__revision_file_t *rev_file;
+      svn_revnum_t min_unpacked_rev;
+
+      SVN_ERR(svn_fs_fs__open_pack_or_rev_file(&rev_file, fs, revision,
+                                               scratch_pool, scratch_pool));
+      SVN_ERR(svn_fs_fs__min_unpacked_rev(&min_unpacked_rev, fs,
+                                          scratch_pool));
+      if (revision < min_unpacked_rev)
+        {
+          int shard_size = svn_fs_fs__shard_size(fs);
+          apr_off_t start_offset, end_offset;
+
+          SVN_ERR(svn_fs_fs__get_packed_offset(&start_offset, fs, revision,
+                                               scratch_pool));
+          if (((revision + 1) % shard_size) == 0)
+            {
+              svn_filesize_t file_size;
+
+              SVN_ERR(svn_io_file_size_get(&file_size, rev_file->file, 
scratch_pool));
+              end_offset = (apr_off_t)file_size;
+            }
+          else
+            {
+              SVN_ERR(svn_fs_fs__get_packed_offset(&end_offset, fs,
+                                                   revision + 1, 
scratch_pool));
+            }
+          *rev_size = (end_offset - start_offset);
+        }
+      else
+        {
+          svn_filesize_t file_size;
+
+          SVN_ERR(svn_io_file_size_get(&file_size, rev_file->file, 
scratch_pool));
+          *rev_size = (apr_off_t)file_size;
+        }
+
+      SVN_ERR(svn_fs_fs__close_revision_file(rev_file));
+    }
+
+  /* Add the size of the rev-props */
+  {
+    apr_off_t size;
+
+    SVN_ERR(svn_fs_fs__get_revision_props_size(&size, fs, revision, 
scratch_pool));
+    *rev_size += size;
+  }
+
+  return SVN_NO_ERROR;
+}

Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/structure
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/structure?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_fs/structure (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_fs/structure Sat May 23 
14:16:56 2020
@@ -118,7 +118,7 @@ representation checksum and location map
 hash text as the primary key, mapped to the representation revision, offset,
 size and expanded size.  This file is only consulted during writes and never
 during reads.  Consequently, it is not required, and may be removed at an
-abritrary time, with the subsequent loss of rep-sharing capabilities for
+arbitrary time, with the subsequent loss of rep-sharing capabilities for
 revisions written thereafter.
 
 Filesystem formats
@@ -568,6 +568,9 @@ defined:
             ### in formats >=4, also present:
             <sha1-digest> gives hex SHA1 digest of expanded rep
             <uniquifier> see representation_t->uniquifier in fs.h
+            ### Starting from format 8, a special notation "-"
+            can be used for optional values that are not present
+            (<sha1-digest> and <uniquifier>).
   cpath     FS pathname node was created at
   copyfrom  "<rev> <path>" of copyfrom data
   copyroot  "<rev> <created-path>" of the root of this copy

Modified: 
subversion/branches/addremove/subversion/libsvn_fs_fs/temp_serializer.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/temp_serializer.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_fs/temp_serializer.c 
(original)
+++ subversion/branches/addremove/subversion/libsvn_fs_fs/temp_serializer.c Sat 
May 23 14:16:56 2020
@@ -38,7 +38,7 @@
 #include "cached_data.h"
 
 /* Utility to encode a signed NUMBER into a variable-length sequence of
- * 8-bit chars in KEY_BUFFER and return the last writen position.
+ * 8-bit chars in KEY_BUFFER and return the last written position.
  *
  * Numbers will be stored in 7 bits / byte and using byte values above
  * 32 (' ') to make them combinable with other string by simply separating
@@ -1013,13 +1013,13 @@ slowly_replace_dir_entry(void **data,
         APR_ARRAY_IDX(entries, idx, svn_fs_dirent_t *)
           = replace_baton->new_entry;
       else
-        svn_sort__array_insert(entries, &replace_baton->new_entry, idx);
+        SVN_ERR(svn_sort__array_insert2(entries, &replace_baton->new_entry, 
idx));
     }
   else
     {
       /* Remove the old ENTRY. */
       if (entry)
-        svn_sort__array_delete(entries, idx, 1);
+        SVN_ERR(svn_sort__array_delete2(entries, idx, 1));
     }
 
   return svn_fs_fs__serialize_dir_entries(data, data_len, dir, pool);

Modified: 
subversion/branches/addremove/subversion/libsvn_fs_fs/temp_serializer.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/temp_serializer.h?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_fs/temp_serializer.h 
(original)
+++ subversion/branches/addremove/subversion/libsvn_fs_fs/temp_serializer.h Sat 
May 23 14:16:56 2020
@@ -53,13 +53,16 @@ svn_fs_fs__noderev_deserialize(void *buf
 /**
  * Adds position information to the raw window data in WINDOW.
  */
-typedef struct
+typedef struct svn_fs_fs__raw_cached_window_t
 {
   /* the (unprocessed) txdelta window byte sequence cached / to be cached */
   svn_string_t window;
 
   /* the offset within the representation right after reading the window */
   apr_off_t end_offset;
+
+  /* svndiff version */
+  int ver;
 } svn_fs_fs__raw_cached_window_t;
 
 /**
@@ -86,7 +89,7 @@ svn_fs_fs__deserialize_raw_window(void *
  * #svn_txdelta_window_t is not sufficient for caching the data it
  * represents because data read process needs auxiliary information.
  */
-typedef struct
+typedef struct svn_fs_fs__txdelta_cached_window_t
 {
   /* the txdelta window information cached / to be cached */
   svn_txdelta_window_t *window;
@@ -374,7 +377,7 @@ typedef struct svn_fs_fs__changes_list_t
      of elements in the list is a multiple of our block / range size. */
   svn_boolean_t eol;
 
-  /* Array of #svn_fs_x__change_t * representing a consecutive sub-range of
+  /* Array of #svn_fs_fs__change_t * representing a consecutive sub-range of
      elements in a changed paths list. */
 
   /* number of entries in the array */

Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/transaction.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/transaction.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_fs/transaction.c 
(original)
+++ subversion/branches/addremove/subversion/libsvn_fs_fs/transaction.c Sat May 
23 14:16:56 2020
@@ -587,7 +587,7 @@ unparse_dir_entry(svn_fs_dirent_t *diren
                       : sizeof(SVN_FS_FS__KIND_DIR);
   apr_size_t value_len = type_len + id_str->len;
 
-  /* A buffer with sufficient space for 
+  /* A buffer with sufficient space for
    * - both string lines
    * - 4 newlines
    * - 2 lines K/V lines containing a number each
@@ -3336,6 +3336,24 @@ write_final_rev(const svn_fs_id_t **new_
   if (noderev->data_rep && noderev->kind == svn_node_dir)
     noderev->data_rep->has_sha1 = FALSE;
 
+  /* Compatibility: while we don't need to serialize SHA1 for props (it is
+     not used), older formats can only have representation strings that either
+     have both the SHA1 value *and* the uniquifier, or don't have them at all.
+     For such formats, both values get written to the disk only if the SHA1
+     is present.
+
+     We cannot omit the uniquifier, as doing so breaks svn_fs_props_changed()
+     for properties with shared representations, see issues #4623 and #4700.
+     Therefore, we skip writing SHA1, but only for the newer formats where
+     this dependency is untied and we can write the uniquifier to the disk
+     without the SHA1.
+   */
+  if (ffd->format >= SVN_FS_FS__MIN_REP_STRING_OPTIONAL_VALUES_FORMAT &&
+      noderev->prop_rep)
+    {
+      noderev->prop_rep->has_sha1 = FALSE;
+    }
+
   /* Workaround issue #4031: is-fresh-txn-root in revision files. */
   noderev->is_fresh_txn_root = FALSE;
 
@@ -3695,7 +3713,7 @@ promote_cached_directories(svn_fs_t *fs,
 
       /* Currently, the entry for KEY - if it still exists - is marked
        * as "stale" and would not be used.  Mark it as current for in-
-       * revison data. */
+       * revision data. */
       SVN_ERR(svn_cache__set_partial(ffd->dir_cache, key,
                                      svn_fs_fs__reset_txn_filesize, NULL,
                                      iterpool));

Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/tree.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/tree.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_fs/tree.c Sat May 23 
14:16:56 2020
@@ -920,6 +920,25 @@ try_match_last_node(dag_node_t **node_p,
   return SVN_NO_ERROR;
 }
 
+/* Helper for open_path() that constructs and returns an appropriate
+   SVN_ERR_FS_NOT_DIRECTORY error. */
+static svn_error_t *
+err_not_directory(svn_fs_root_t *root,
+                  const char *path,
+                  apr_pool_t *scratch_pool)
+{
+  const char *msg;
+
+  msg = root->is_txn_root
+      ? apr_psprintf(scratch_pool,
+                     _("Failure opening '%s' in transaction '%s'"),
+                     path, root->txn)
+      : apr_psprintf(scratch_pool,
+                     _("Failure opening '%s' in revision %ld"),
+                     path, root->rev);
+
+  return svn_error_quick_wrap(SVN_FS__ERR_NOT_DIRECTORY(root->fs, path), msg);
+}
 
 /* Open the node identified by PATH in ROOT, allocating in POOL.  Set
    *PARENT_PATH_P to a path from the node up to ROOT.  The resulting
@@ -1016,12 +1035,26 @@ open_path(parent_path_t **parent_path_p,
           SVN_ERR(dag_node_cache_get(&here, root, directory, pool));
 
           /* Did the shortcut work? */
-          if (here)
+          if (here && svn_fs_fs__dag_node_kind(here) == svn_node_dir)
             {
               apr_size_t dirname_len = strlen(directory);
               path_so_far->len = dirname_len;
               rest = path + dirname_len + 1;
             }
+          else if (here)
+            {
+              /* The parent node is not a directory.  We are looking for some
+                 sub-path, so that sub-path will not exist.  That will be o.k.
+                 if we are just here to check for the path's existence, but
+                 should result in an error otherwise. */
+              if (flags & open_path_allow_null)
+                {
+                  *parent_path_p = NULL;
+                  return SVN_NO_ERROR;
+                }
+              else
+                return svn_error_trace(err_not_directory(root, directory, 
pool));
+            }
         }
     }
 
@@ -1144,8 +1177,6 @@ open_path(parent_path_t **parent_path_p,
       /* The path isn't finished yet; we'd better be in a directory.  */
       if (svn_fs_fs__dag_node_kind(child) != svn_node_dir)
         {
-          const char *msg;
-
           /* Since this is not a directory and we are looking for some
              sub-path, that sub-path will not exist.  That will be o.k.,
              if we are just here to check for the path's existence. */
@@ -1156,14 +1187,8 @@ open_path(parent_path_t **parent_path_p,
             }
 
           /* It's really a problem ... */
-          msg = root->is_txn_root
-              ? apr_psprintf(iterpool,
-                             _("Failure opening '%s' in transaction '%s'"),
-                             path, root->txn)
-              : apr_psprintf(iterpool,
-                             _("Failure opening '%s' in revision %ld"),
-                             path, root->rev);
-          SVN_ERR_W(SVN_FS__ERR_NOT_DIRECTORY(fs, path_so_far->data), msg);
+          return svn_error_trace(
+                   err_not_directory(root, path_so_far->data, iterpool));
         }
 
       rest = next;
@@ -3123,7 +3148,7 @@ struct text_baton_t
  * svn_fs_apply_text()      ==> ... ==> txn_body_fulltext_finalize_edits()
  */
 
-/* Write function for the publically returned stream. */
+/* Write function for the publicly returned stream. */
 static svn_error_t *
 text_stream_writer(void *baton,
                    const char *data,
@@ -3135,7 +3160,7 @@ text_stream_writer(void *baton,
   return svn_stream_write(tb->file_stream, data, len);
 }
 
-/* Close function for the publically returned stream. */
+/* Close function for the publicly returned stream. */
 static svn_error_t *
 text_stream_closer(void *baton)
 {
@@ -4619,7 +4644,7 @@ make_txn_root(svn_fs_root_t **root_p,
                                       svn_fs_fs__dag_deserialize,
                                       APR_HASH_KEY_STRING,
                                       32, 20, FALSE,
-                                      apr_pstrcat(pool, txn, ":TXN",
+                                      apr_pstrcat(pool, root->txn, ":TXN",
                                                   SVN_VA_NULL),
                                       root->pool));
 

Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/util.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/util.h?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_fs/util.h (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_fs/util.h Sat May 23 
14:16:56 2020
@@ -316,7 +316,7 @@ svn_error_t *
 svn_fs_fs__update_min_unpacked_rev(svn_fs_t *fs,
                                    apr_pool_t *pool);
 
-/* Atomically update the 'min-unpacked-rev' file in FS to hold the specifed
+/* Atomically update the 'min-unpacked-rev' file in FS to hold the specified
  * REVNUM.  Perform temporary allocations in SCRATCH_POOL.
  */
 svn_error_t *
@@ -336,7 +336,7 @@ svn_fs_fs__read_current(svn_revnum_t *re
                         svn_fs_t *fs,
                         apr_pool_t *pool);
 
-/* Atomically update the 'current' file to hold the specifed REV,
+/* Atomically update the 'current' file to hold the specified REV,
    NEXT_NODE_ID, and NEXT_COPY_ID.  (The two next-ID parameters are
    ignored and may be 0 if the FS format does not use them.)
    Perform temporary allocations in POOL. */

Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/verify.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/verify.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_fs/verify.c (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_fs/verify.c Sat May 23 
14:16:56 2020
@@ -681,10 +681,10 @@ compare_p2l_to_rev(svn_fs_t *fs,
                                      NULL,
                                      _("p2l index entry for revision r%ld"
                                        " at offset %s contains invalid item"
-                                       " type %d"),
+                                       " type %u"),
                                      start,
                                      apr_off_t_toa(pool, offset),
-                                     entry->type);
+                                     (unsigned int)entry->type);
 
           /* There can be only one changes entry and that has a fixed type
            * and item number.  Its presence and parse-ability will be checked
@@ -694,11 +694,12 @@ compare_p2l_to_rev(svn_fs_t *fs,
             return svn_error_createf(SVN_ERR_FS_INDEX_CORRUPTION,
                                      NULL,
                                      _("p2l index entry for changes in"
-                                       " revision r%ld is item %ld of type"
-                                       " %d at offset %s"),
+                                       " revision r%ld is item"
+                                       " %"APR_UINT64_T_FMT
+                                       " of type %u at offset %s"),
                                      entry->item.revision,
                                      entry->item.number,
-                                     entry->type,
+                                     (unsigned int)entry->type,
                                      apr_off_t_toa(pool, offset));
 
           /* Check contents. */

Propchange: subversion/branches/addremove/subversion/libsvn_fs_x/
------------------------------------------------------------------------------
  Merged /subversion/branches/swig-py3/subversion/libsvn_fs_x:r1813660-1869353
  Merged /subversion/trunk/subversion/libsvn_fs_x:r1802696-1878056

Modified: subversion/branches/addremove/subversion/libsvn_fs_x/cached_data.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/cached_data.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_x/cached_data.c 
(original)
+++ subversion/branches/addremove/subversion/libsvn_fs_x/cached_data.c Sat May 
23 14:16:56 2020
@@ -394,7 +394,7 @@ svn_fs_x__get_mergeinfo_count(apr_int64_
 {
   svn_fs_x__noderev_t *noderev;
 
-  /* If we want a full acccess log, we need to provide full data and
+  /* If we want a full access log, we need to provide full data and
      cannot take shortcuts here. */
 #if !defined(SVN_FS_X__LOG_ACCESS)
 
@@ -951,7 +951,7 @@ typedef struct rep_read_baton_t
   /* Used for temporary allocations during the read. */
   apr_pool_t *scratch_pool;
 
-  /* Pool used to store file handles and other data that is persistant
+  /* Pool used to store file handles and other data that is persistent
      for the entire stream read. */
   apr_pool_t *filehandle_pool;
 } rep_read_baton_t;
@@ -1518,7 +1518,7 @@ get_combined_window(svn_stringbuf_t **re
   return SVN_NO_ERROR;
 }
 
-/* Returns whether or not the expanded fulltext of the file is cachable
+/* Returns whether or not the expanded fulltext of the file is cacheable
  * based on its size SIZE.  The decision depends on the cache used by FFD.
  */
 static svn_boolean_t
@@ -2229,7 +2229,7 @@ svn_fs_x__get_contents_from_file(svn_str
                              rb->filehandle_pool, rb->scratch_pool));
 
       /* Insert the access to REP as the first element of the delta chain. */
-      svn_sort__array_insert(rb->rs_list, &rs, 0);
+      SVN_ERR(svn_sort__array_insert2(rb->rs_list, &rs, 0));
     }
 
   /* Now, the baton is complete and we can assemble the stream around it. */
@@ -2585,7 +2585,7 @@ parse_dir_entries(apr_array_header_t **e
 }
 
 /* For directory NODEREV in FS, return the *FILESIZE of its in-txn
- * representation.  If the directory representation is comitted data,
+ * representation.  If the directory representation is committed data,
  * set *FILESIZE to SVN_INVALID_FILESIZE. Use SCRATCH_POOL for temporaries.
  */
 static svn_error_t *

Modified: subversion/branches/addremove/subversion/libsvn_fs_x/caching.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/caching.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_x/caching.c (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_x/caching.c Sat May 23 
14:16:56 2020
@@ -415,7 +415,7 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
    *   (e.g. fulltexts etc.)
    * - Index data required to find any of the other data has high prio
    *   (e.g. noderevs, L2P and P2L index pages)
-   * - everthing else should use default prio
+   * - everything else should use default prio
    */
 
 #ifdef SVN_DEBUG_CACHE_DUMP_STATS

Modified: subversion/branches/addremove/subversion/libsvn_fs_x/changes.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/changes.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_x/changes.c (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_x/changes.c Sat May 23 
14:16:56 2020
@@ -184,7 +184,7 @@ svn_fs_x__changes_append_list(apr_size_t
 
   /* simply append the list and all changes */
   for (i = 0; i < list->nelts; ++i)
-    append_change(changes, APR_ARRAY_IDX(list, i, svn_fs_x__change_t *));
+    SVN_ERR(append_change(changes, APR_ARRAY_IDX(list, i, svn_fs_x__change_t 
*)));
 
   /* terminate the list by storing the next changes offset */
   APR_ARRAY_PUSH(changes->offsets, int) = changes->changes->nelts;

Modified: subversion/branches/addremove/subversion/libsvn_fs_x/dag_cache.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/dag_cache.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_x/dag_cache.c (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_x/dag_cache.c Sat May 23 
14:16:56 2020
@@ -807,7 +807,7 @@ get_copy_inheritance(svn_fs_x__copy_id_i
      or if it is a branch point that we are accessing via its original
      copy destination path. */
   svn_fs_x__dag_get_copyroot(&copyroot_rev, &copyroot_path, child->node);
-  SVN_ERR(svn_fs_x__revision_root(&copyroot_root, fs, copyroot_rev, 
+  SVN_ERR(svn_fs_x__revision_root(&copyroot_root, fs, copyroot_rev,
                                   scratch_pool));
   SVN_ERR(svn_fs_x__get_temp_dag_node(&copyroot_node, copyroot_root,
                                       copyroot_path, scratch_pool));
@@ -833,7 +833,7 @@ get_copy_inheritance(svn_fs_x__copy_id_i
 }
 
 /* Allocate a new svn_fs_x__dag_path_t node from RESULT_POOL, containing
-   NODE, ENTRY and PARENT, all copied into RESULT_POOL as well.  */
+   NODE, ENTRY and PARENT; NODE and ENTRY are copied into RESULT_POOL.  */
 static svn_fs_x__dag_path_t *
 make_parent_path(dag_node_t *node,
                  const svn_stringbuf_t *entry,
@@ -909,7 +909,7 @@ svn_fs_x__get_dag_path(svn_fs_x__dag_pat
         {
           /* If this was the last path component, and the caller
              said it was optional, then don't return an error;
-             just put a NULL node pointer in the path. 
+             just put a NULL node pointer in the path.
            */
           if ((flags & svn_fs_x__dag_path_last_optional)
               && (path_len == path.len))

Modified: subversion/branches/addremove/subversion/libsvn_fs_x/dag_cache.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/dag_cache.h?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_x/dag_cache.h (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_x/dag_cache.h Sat May 23 
14:16:56 2020
@@ -103,7 +103,7 @@ typedef struct svn_fs_x__dag_path_t
    IS_TXN_PATH must be set.  If IS_TXN_PATH is FALSE, no copy ID
    inheritance information will be calculated for the *PARENT_PATH_P chain.
 
-   If FLAGS & open_path_last_optional is zero, return the error
+   If FLAGS & svn_fs_x__dag_path_last_optional is zero, return the error
    SVN_ERR_FS_NOT_FOUND if the node PATH refers to does not exist.  If
    non-zero, require all the parent directories to exist as normal,
    but if the final path component doesn't exist, simply return a path

Modified: subversion/branches/addremove/subversion/libsvn_fs_x/fs.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/fs.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_x/fs.c (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_x/fs.c Sat May 23 
14:16:56 2020
@@ -310,7 +310,8 @@ static fs_vtable_t fs_vtable = {
   x_info,
   svn_fs_x__verify_root,
   x_freeze,
-  x_set_errcall
+  x_set_errcall,
+  NULL /* ioctl */
 };
 
 
@@ -641,7 +642,8 @@ static fs_library_vtable_t library_vtabl
   x_logfiles,
   NULL /* parse_id */,
   x_set_svn_fs_open,
-  x_info_dup
+  x_info_dup,
+  NULL /* ioctl */
 };
 
 svn_error_t *

Modified: subversion/branches/addremove/subversion/libsvn_fs_x/fs_x.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/fs_x.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_x/fs_x.c (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_x/fs_x.c Sat May 23 
14:16:56 2020
@@ -951,7 +951,7 @@ write_revision_zero(svn_fs_t *fs,
 
   SVN_ERR(svn_io_file_open(&apr_file,
                            svn_fs_x__path_revprops(fs, 0, scratch_pool),
-                           APR_WRITE | APR_CREATE, APR_OS_DEFAULT, 
+                           APR_WRITE | APR_CREATE, APR_OS_DEFAULT,
                            scratch_pool));
   SVN_ERR(svn_fs_x__write_non_packed_revprops(apr_file, proplist,
                                               scratch_pool));

Modified: subversion/branches/addremove/subversion/libsvn_fs_x/hotcopy.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/hotcopy.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_x/hotcopy.c (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_x/hotcopy.c Sat May 23 
14:16:56 2020
@@ -625,7 +625,7 @@ hotcopy_body(void *baton,
     SVN_ERR(cancel_func(cancel_baton));
 
   /* Split the logic for new and old FS formats. The latter is much simpler
-   * due to the absense of sharding and packing. However, it requires special
+   * due to the absence of sharding and packing. However, it requires special
    * care when updating the 'current' file (which contains not just the
    * revision number, but also the next-ID counters). */
   SVN_ERR(hotcopy_revisions(src_fs, dst_fs, src_youngest, dst_youngest,

Modified: subversion/branches/addremove/subversion/libsvn_fs_x/id.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/id.h?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_x/id.h (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_x/id.h Sat May 23 
14:16:56 2020
@@ -37,7 +37,7 @@ typedef apr_int64_t svn_fs_x__txn_id_t;
 
 /* Change set is the umbrella term for transaction and revision in FSX.
  * Revision numbers (>=0) map 1:1 onto change sets while txns are mapped
- * onto the negatve value range. */
+ * onto the negative value range. */
 typedef apr_int64_t svn_fs_x__change_set_t;
 
 /* Invalid / unused change set number. */

Modified: subversion/branches/addremove/subversion/libsvn_fs_x/index.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/index.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_x/index.c (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_x/index.c Sat May 23 
14:16:56 2020
@@ -2742,8 +2742,8 @@ get_p2l_page(apr_array_header_t **entrie
  * Set *END to TRUE if the caller should stop refeching.
  *
  * *BATON will be updated with the selected page's info and SCRATCH_POOL
- * will be used for temporary allocations.  If the data is alread in the
- * cache, descrease *LEAKING_BUCKET and increase it otherwise.  With that
+ * will be used for temporary allocations.  If the data is already in the
+ * cache, decrease *LEAKING_BUCKET and increase it otherwise.  With that
  * pattern we will still read all pages from the block even if some of
  * them survived in the cached.
  */
@@ -2919,7 +2919,7 @@ append_p2l_entries(apr_array_header_t *e
     }
 }
 
-/* Auxilliary struct passed to p2l_entries_func selecting the relevant
+/* Auxiliary struct passed to p2l_entries_func selecting the relevant
  * data range. */
 typedef struct p2l_entries_baton_t
 {

Modified: subversion/branches/addremove/subversion/libsvn_fs_x/low_level.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/low_level.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_x/low_level.c (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_x/low_level.c Sat May 23 
14:16:56 2020
@@ -161,16 +161,16 @@ svn_fs_x__parse_footer(apr_off_t *l2p_of
                             rev));
   *p2l_offset = (apr_off_t)val;
 
-  /* The P2L indes follows the L2P index */
+  /* The P2L index follows the L2P index */
   if (*p2l_offset <= *l2p_offset)
     return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
                              "P2L offset %s must be larger than L2P offset %s"
                              " in r%ld footer",
                              apr_psprintf(result_pool,
-                                          "%" APR_UINT64_T_HEX_FMT,
+                                          "0x%" APR_UINT64_T_HEX_FMT,
                                           (apr_uint64_t)*p2l_offset),
                              apr_psprintf(result_pool,
-                                          "%" APR_UINT64_T_HEX_FMT,
+                                          "0x%" APR_UINT64_T_HEX_FMT,
                                           (apr_uint64_t)*l2p_offset),
                              rev);
 
@@ -998,7 +998,7 @@ svn_fs_x__read_changes(apr_array_header_
       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);
@@ -1131,7 +1131,7 @@ svn_fs_x__write_changes(svn_stream_t *st
     }
 
   if (terminate_list)
-    svn_stream_puts(stream, "\n");
+    SVN_ERR(svn_stream_puts(stream, "\n"));
 
   svn_pool_destroy(iterpool);
 

Modified: subversion/branches/addremove/subversion/libsvn_fs_x/pack.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/pack.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_x/pack.c (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_x/pack.c Sat May 23 
14:16:56 2020
@@ -1461,7 +1461,7 @@ copy_reps_from_temp(pack_context_t *cont
   SVN_ERR(store_items(context, temp_file, reps, initial_reps_count,
                       scratch_pool));
 
-  /* vaccum ENTRIES array: eliminate NULL entries */
+  /* vacuum ENTRIES array: eliminate NULL entries */
   for (i = 0, k = 0; i < reps->nelts; ++i)
     {
       svn_fs_x__p2l_entry_t *entry
@@ -1686,7 +1686,7 @@ write_l2p_index(pack_context_t *context,
                                                context->reps,
                                                pool, scratch_pool));
 
-  /* Append newly written segment to exisiting proto index file. */
+  /* Append newly written segment to existing proto index file. */
   SVN_ERR(svn_io_file_name_get(&proto_index, context->proto_l2p_index,
                                scratch_pool));
 
@@ -2204,9 +2204,9 @@ pack_body(void *baton,
   if (fully_packed)
     {
       if (pb->notify_func)
-        (*pb->notify_func)(pb->notify_baton,
-                           ffd->min_unpacked_rev / ffd->max_files_per_dir,
-                           svn_fs_pack_notify_noop, scratch_pool);
+        SVN_ERR(pb->notify_func(pb->notify_baton,
+                                ffd->min_unpacked_rev / ffd->max_files_per_dir,
+                                svn_fs_pack_notify_noop, scratch_pool));
 
       return SVN_NO_ERROR;
     }
@@ -2258,9 +2258,9 @@ svn_fs_x__pack(svn_fs_t *fs,
       svn_fs_x__data_t *ffd = fs->fsap_data;
 
       if (notify_func)
-        (*notify_func)(notify_baton,
-                       ffd->min_unpacked_rev / ffd->max_files_per_dir,
-                       svn_fs_pack_notify_noop, scratch_pool);
+        SVN_ERR(notify_func(notify_baton,
+                            ffd->min_unpacked_rev / ffd->max_files_per_dir,
+                            svn_fs_pack_notify_noop, scratch_pool));
 
       return SVN_NO_ERROR;
     }

Modified: subversion/branches/addremove/subversion/libsvn_fs_x/rev_file.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/rev_file.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_x/rev_file.c (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_x/rev_file.c Sat May 23 
14:16:56 2020
@@ -66,7 +66,7 @@ struct svn_fs_x__revision_file_t
   svn_fs_x__index_info_t p2l_info;
 
   /* Pool used for all sub-structure allocations (file, streams etc.).
-     A sub-pool of OWNER. NULL until the lazily initilized. */
+     A sub-pool of OWNER. NULL until the lazily initialized. */
   apr_pool_t *pool;
 
   /* Pool that this structure got allocated in. */

Modified: subversion/branches/addremove/subversion/libsvn_fs_x/revprops.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/revprops.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_x/revprops.c (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_x/revprops.c Sat May 23 
14:16:56 2020
@@ -449,7 +449,7 @@ verify_checksum(svn_stringbuf_t *content
                        content->len, scratch_pool));
 
   if (!svn_checksum_match(actual, expected))
-    SVN_ERR(svn_checksum_mismatch_err(expected, actual, scratch_pool, 
+    SVN_ERR(svn_checksum_mismatch_err(expected, actual, scratch_pool,
                                       "checksum mismatch"));
 
   return SVN_NO_ERROR;
@@ -1203,7 +1203,7 @@ repack_file_open(apr_file_t **file,
   if (revprops->entry.start_rev == start_rev)
     APR_ARRAY_IDX(revprops->manifest, idx, manifest_entry_t) = new_entry;
   else
-    svn_sort__array_insert(revprops->manifest, &new_path, idx + 1);
+    SVN_ERR(svn_sort__array_insert2(revprops->manifest, &new_path, idx + 1));
 
   /* open the file */
   new_path = get_revprop_pack_filepath(revprops, &new_entry, scratch_pool);
@@ -1424,7 +1424,7 @@ svn_fs_x__set_revision_proplist(svn_fs_t
                                  scratch_pool));
   else
     SVN_ERR(write_non_packed_revprop(&final_path, &tmp_path,
-                                     fs, rev, proplist, batch, 
+                                     fs, rev, proplist, batch,
                                      scratch_pool, scratch_pool));
 
   /* We use the rev file of this revision as the perms reference,

Modified: subversion/branches/addremove/subversion/libsvn_fs_x/structure
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/structure?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_x/structure (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_x/structure Sat May 23 
14:16:56 2020
@@ -112,7 +112,7 @@ representation checksum and location map
 hash text as the primary key, mapped to the representation revision, offset,
 size and expanded size.  This file is only consulted during writes and never
 during reads.  Consequently, it is not required, and may be removed at an
-abritrary time, with the subsequent loss of rep-sharing capabilities for
+arbitrary time, with the subsequent loss of rep-sharing capabilities for
 revisions written thereafter.
 
 Filesystem formats

Modified: subversion/branches/addremove/subversion/libsvn_fs_x/temp_serializer.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/temp_serializer.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_x/temp_serializer.c 
(original)
+++ subversion/branches/addremove/subversion/libsvn_fs_x/temp_serializer.c Sat 
May 23 14:16:56 2020
@@ -38,7 +38,7 @@
 #include "cached_data.h"
 
 /* Utility to encode a signed NUMBER into a variable-length sequence of
- * 8-bit chars in KEY_BUFFER and return the last writen position.
+ * 8-bit chars in KEY_BUFFER and return the last written position.
  *
  * Numbers will be stored in 7 bits / byte and using byte values above
  * 32 (' ') to make them combinable with other string by simply separating
@@ -183,7 +183,7 @@ svn_fs_x__deserialize_apr_array(void *bu
   (*array)->pool = result_pool;
 }
 
-/* auxilliary structure representing the content of a directory array */
+/* auxiliary structure representing the content of a directory array */
 typedef struct dir_data_t
 {
   /* number of entries in the directory
@@ -925,13 +925,13 @@ slowly_replace_dir_entry(void **data,
         APR_ARRAY_IDX(entries, idx, svn_fs_x__dirent_t *)
           = replace_baton->new_entry;
       else
-        svn_sort__array_insert(entries, &replace_baton->new_entry, idx);
+        SVN_ERR(svn_sort__array_insert2(entries, &replace_baton->new_entry, 
idx));
     }
   else
     {
       /* Remove the old ENTRY. */
       if (entry)
-        svn_sort__array_delete(entries, idx, 1);
+        SVN_ERR(svn_sort__array_delete2(entries, idx, 1));
     }
 
   return svn_fs_x__serialize_dir_entries(data, data_len, dir, pool);

Modified: subversion/branches/addremove/subversion/libsvn_fs_x/transaction.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/transaction.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_x/transaction.c 
(original)
+++ subversion/branches/addremove/subversion/libsvn_fs_x/transaction.c Sat May 
23 14:16:56 2020
@@ -881,7 +881,7 @@ unparse_dir_entry(svn_fs_x__dirent_t *di
   apr_size_t to_write;
   apr_size_t name_len = strlen(dirent->name);
 
-  /* A buffer with sufficient space for 
+  /* A buffer with sufficient space for
    * - entry name + 1 terminating NUL
    * - 1 byte for the node kind
    * - 2 numbers in 7b/8b encoding for the noderev-id
@@ -1259,7 +1259,7 @@ get_and_increment_txn_key_body(void *bat
       SVN_ERR(svn_io_check_path(txn_dir, &kind, iterpool));
       if (kind == svn_node_none)
         {
-          svn_io_dir_make(txn_dir, APR_OS_DEFAULT, iterpool);
+          SVN_ERR(svn_io_dir_make(txn_dir, APR_OS_DEFAULT, iterpool));
           break;
         }
 
@@ -3066,7 +3066,7 @@ get_final_id(svn_fs_x__id_t *part,
     part->change_set = svn_fs_x__change_set_by_rev(revision);
 }
 
-/* Copy a node-revision specified by id ID in fileystem FS from a
+/* Copy a node-revision specified by id ID in filesystem FS from a
    transaction into the proto-rev-file FILE.  Set *NEW_ID_P to a
    pointer to the new noderev-id.  If this is a directory, copy all
    children as well.
@@ -3738,7 +3738,7 @@ promote_cached_directories(svn_fs_t *fs,
 
       /* Currently, the entry for KEY - if it still exists - is marked
        * as "stale" and would not be used.  Mark it as current for in-
-       * revison data. */
+       * revision data. */
       SVN_ERR(svn_cache__set_partial(ffd->dir_cache, key,
                                      svn_fs_x__reset_txn_filesize, NULL,
                                      iterpool));

Modified: subversion/branches/addremove/subversion/libsvn_fs_x/tree.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/tree.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_x/tree.c (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_x/tree.c Sat May 23 
14:16:56 2020
@@ -2060,7 +2060,7 @@ typedef struct text_baton_t
  * svn_fs_apply_text()      ==> ... ==> txn_body_fulltext_finalize_edits()
  */
 
-/* Write function for the publically returned stream. */
+/* Write function for the publicly returned stream. */
 static svn_error_t *
 text_stream_writer(void *baton,
                    const char *data,
@@ -2072,7 +2072,7 @@ text_stream_writer(void *baton,
   return svn_stream_write(tb->file_stream, data, len);
 }
 
-/* Close function for the publically returned stream. */
+/* Close function for the publicly returned stream. */
 static svn_error_t *
 text_stream_closer(void *baton)
 {

Modified: subversion/branches/addremove/subversion/libsvn_fs_x/util.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/util.h?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_x/util.h (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_x/util.h Sat May 23 
14:16:56 2020
@@ -384,7 +384,7 @@ svn_error_t *
 svn_fs_x__update_min_unpacked_rev(svn_fs_t *fs,
                                   apr_pool_t *scratch_pool);
 
-/* Atomically update the 'min-unpacked-rev' file in FS to hold the specifed
+/* Atomically update the 'min-unpacked-rev' file in FS to hold the specified
  * REVNUM.  Perform temporary allocations in SCRATCH_POOL.
  */
 svn_error_t *
@@ -400,7 +400,7 @@ svn_fs_x__read_current(svn_revnum_t *rev
                        svn_fs_t *fs,
                        apr_pool_t *scratch_pool);
 
-/* Atomically update the 'current' file to hold the specifed REV.
+/* Atomically update the 'current' file to hold the specified REV.
    Perform temporary allocations in SCRATCH_POOL. */
 svn_error_t *
 svn_fs_x__write_current(svn_fs_t *fs,

Modified: subversion/branches/addremove/subversion/libsvn_fs_x/verify.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/verify.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_x/verify.c (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_x/verify.c Sat May 23 
14:16:56 2020
@@ -179,7 +179,7 @@ verify_index_checksum(svn_fs_x__revision
 
       SVN_ERR(svn_fs_x__rev_file_name(&file_name, file, scratch_pool));
       SVN_ERR(svn_checksum_mismatch_err(index_info->checksum, actual,
-                                        scratch_pool, 
+                                        scratch_pool,
                                         _("%s checksum mismatch in file %s"),
                                         name, file_name));
     }

Modified: subversion/branches/addremove/subversion/libsvn_ra/compat.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_ra/compat.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_ra/compat.c (original)
+++ subversion/branches/addremove/subversion/libsvn_ra/compat.c Sat May 23 
14:16:56 2020
@@ -942,7 +942,7 @@ svn_ra__get_inherited_props_walk(svn_ra_
                                                          parent_url,
                                                          result_pool);
           new_iprop->prop_hash = final_hash;
-          svn_sort__array_insert(*inherited_props, &new_iprop, 0);
+          SVN_ERR(svn_sort__array_insert2(*inherited_props, &new_iprop, 0));
         }
     }
 


Reply via email to