subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kot...@apache.org
Subject svn commit: r1816347 - in /subversion/trunk/subversion/libsvn_fs_fs: fs.h low_level.c structure
Date Sat, 25 Nov 2017 20:16:46 GMT
Author: kotkov
Date: Sat Nov 25 20:16:46 2017
New Revision: 1816347

URL: http://svn.apache.org/viewvc?rev=1816347&view=rev
Log:
fsfs: Lay the groundwork for an extended fix for issues #4623 and #4700.

As per r1813898, we now store both the SHA1 and the uniquifier in the
on-disk property representation strings.  The SHA1 value is not required,
but has to be stored due to an existing dependency in the serializer
where the resulting strings can either have both the SHA1 value *and*
the uniquifier, or don't have them at all.

Untie this dependency by introducing a new notation ("-") for such
optional values, which would be supported by the new filesystem format 8.
This would allow us to skip writing SHA1, and only store the uniquifier
in the representation strings for the new formats.

See https://lists.apache.org/thread.html/d282f27c1260c620fe5deb7c9976f4c05bfb34d5156dee1fa6dad644@%3Cdev.subversion.apache.org%3E

* subversion/libsvn_fs_fs/fs.h
  (SVN_FS_FS__MIN_REP_STRING_OPTIONAL_VALUES_FORMAT): New.

* subversion/libsvn_fs_fs/structure
  (Revision file format): Describe the format extension.

* subversion/libsvn_fs_fs/low_level.c
  (format_uniquifier): New helper function, factored out from ...
  (svn_fs_fs__unparse_representation): ...here.  Support the "-"
   notation for the absent SHA1 and uniquifier values in the new format.
   Tweak the code to handle the older formats one by one.  Keep the code
   for the newest format in the end to simplify extending it in the future.
  (svn_fs_fs__parse_representation): Handle the new "-" notation when
   parsing SHA1 and uniquifier values.

Modified:
    subversion/trunk/subversion/libsvn_fs_fs/fs.h
    subversion/trunk/subversion/libsvn_fs_fs/low_level.c
    subversion/trunk/subversion/libsvn_fs_fs/structure

Modified: subversion/trunk/subversion/libsvn_fs_fs/fs.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/fs.h?rev=1816347&r1=1816346&r2=1816347&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_fs/fs.h (original)
+++ subversion/trunk/subversion/libsvn_fs_fs/fs.h Sat Nov 25 20:16:46 2017
@@ -188,6 +188,14 @@ 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
+
 /* 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/trunk/subversion/libsvn_fs_fs/low_level.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/low_level.c?rev=1816347&r1=1816346&r2=1816347&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_fs/low_level.c (original)
+++ subversion/trunk/subversion/libsvn_fs_fs/low_level.c Sat Nov 25 20:16:46 2017
@@ -814,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
@@ -832,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,
@@ -1051,6 +1074,23 @@ format_digest(const unsigned char *diges
   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,
@@ -1058,29 +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, 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, scratch_pool),
-           format_digest(rep->sha1_digest, svn_checksum_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/trunk/subversion/libsvn_fs_fs/structure
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/structure?rev=1816347&r1=1816346&r2=1816347&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_fs/structure (original)
+++ subversion/trunk/subversion/libsvn_fs_fs/structure Sat Nov 25 20:16:46 2017
@@ -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



Mime
View raw message