revlog: make the index always return the same tuple
authorPierre-Yves David <pierre-yves.david@octobus.net>
Mon, 03 May 2021 12:21:15 +0200
changeset 47156 4292bed8da7c
parent 47155 ac72eee94035
child 47157 47ffc754989a
revlog: make the index always return the same tuple It is simpler to manage the diferrence in on disk format in the internal index code itself and lets the rest of the code always handle the same object. This will become even more important when the data we store will be entirely different (for example the changelog does not need the "linkrev" field. We start with item reading, we will deal with item writing in the next changesets. Differential Revision: https://phab.mercurial-scm.org/D10568
mercurial/cext/revlog.c
mercurial/pure/parsers.py
mercurial/revlogutils/revlogv0.py
mercurial/unionrepo.py
tests/test-parseindex2.py
--- a/mercurial/cext/revlog.c	Mon May 03 12:21:05 2021 +0200
+++ b/mercurial/cext/revlog.c	Mon May 03 12:21:15 2021 +0200
@@ -335,18 +335,17 @@
 	c_node_id = data + 32;
 
 	if (self->entry_size == v1_entry_size) {
-		return Py_BuildValue(v1_tuple_format, offset_flags, comp_len,
-		                     uncomp_len, base_rev, link_rev, parent_1,
-		                     parent_2, c_node_id, self->nodelen);
+		sidedata_offset = 0;
+		sidedata_comp_len = 0;
 	} else {
 		sidedata_offset = getbe64(data + 64);
 		sidedata_comp_len = getbe32(data + 72);
-
-		return Py_BuildValue(v2_tuple_format, offset_flags, comp_len,
-		                     uncomp_len, base_rev, link_rev, parent_1,
-		                     parent_2, c_node_id, self->nodelen,
-		                     sidedata_offset, sidedata_comp_len);
 	}
+
+	return Py_BuildValue(v2_tuple_format, offset_flags, comp_len,
+	                     uncomp_len, base_rev, link_rev, parent_1, parent_2,
+	                     c_node_id, self->nodelen, sidedata_offset,
+	                     sidedata_comp_len);
 }
 /*
  * Pack header information in binary
@@ -2769,15 +2768,9 @@
 		self->entry_size = v1_entry_size;
 	}
 
-	if (self->format_version == format_v1) {
-		self->nullentry =
-		    Py_BuildValue(PY23("iiiiiiis#", "iiiiiiiy#"), 0, 0, 0, -1,
-		                  -1, -1, -1, nullid, self->nodelen);
-	} else {
-		self->nullentry =
-		    Py_BuildValue(PY23("iiiiiiis#ii", "iiiiiiiy#ii"), 0, 0, 0,
-		                  -1, -1, -1, -1, nullid, self->nodelen, 0, 0);
-	}
+	self->nullentry =
+	    Py_BuildValue(PY23("iiiiiiis#ii", "iiiiiiiy#ii"), 0, 0, 0, -1, -1,
+	                  -1, -1, nullid, self->nodelen, 0, 0);
 
 	if (!self->nullentry)
 		return -1;
--- a/mercurial/pure/parsers.py	Mon May 03 12:21:05 2021 +0200
+++ b/mercurial/pure/parsers.py	Mon May 03 12:21:15 2021 +0200
@@ -53,7 +53,7 @@
     # Size of a C long int, platform independent
     int_size = struct.calcsize(b'>i')
     # An empty index entry, used as a default value to be overridden, or nullrev
-    null_item = (0, 0, 0, -1, -1, -1, -1, sha1nodeconstants.nullid)
+    null_item = (0, 0, 0, -1, -1, -1, -1, sha1nodeconstants.nullid, 0, 0)
 
     @util.propertycache
     def entry_size(self):
@@ -122,11 +122,16 @@
         else:
             index = self._calculate_index(i)
             data = self._data[index : index + self.entry_size]
-        r = self.index_format.unpack(data)
+        r = self._unpack_entry(data)
         if self._lgt and i == 0:
             r = (offset_type(0, gettype(r[0])),) + r[1:]
         return r
 
+    def _unpack_entry(self, data):
+        r = self.index_format.unpack(data)
+        r = r + (0, 0)
+        return r
+
     def pack_header(self, header):
         """pack header information as binary"""
         v_fmt = revlog_constants.INDEX_HEADER
@@ -135,7 +140,7 @@
     def entry_binary(self, rev):
         """return the raw binary string representing a revision"""
         entry = self[rev]
-        p = revlog_constants.INDEX_ENTRY_V1.pack(*entry)
+        p = revlog_constants.INDEX_ENTRY_V1.pack(*entry[:8])
         if rev == 0:
             p = p[revlog_constants.INDEX_HEADER.size :]
         return p
@@ -266,7 +271,6 @@
 
 class Index2Mixin(object):
     index_format = revlog_constants.INDEX_ENTRY_V2
-    null_item = (0, 0, 0, -1, -1, -1, -1, sha1nodeconstants.nullid, 0, 0)
 
     def replace_sidedata_info(
         self, i, sidedata_offset, sidedata_length, offset_flags
@@ -292,6 +296,9 @@
             msg = b"cannot rewrite entries outside of this transaction"
             raise KeyError(msg)
 
+    def _unpack_entry(self, data):
+        return self.index_format.unpack(data)
+
     def entry_binary(self, rev):
         """return the raw binary string representing a revision"""
         entry = self[rev]
--- a/mercurial/revlogutils/revlogv0.py	Mon May 03 12:21:05 2021 +0200
+++ b/mercurial/revlogutils/revlogv0.py	Mon May 03 12:21:15 2021 +0200
@@ -135,6 +135,8 @@
             nodemap.get(e[4], node.nullrev),
             nodemap.get(e[5], node.nullrev),
             e[6],
+            0,  # no side data support
+            0,  # no side data support
         )
         index.append(e2)
         nodemap[e[6]] = n
--- a/mercurial/unionrepo.py	Mon May 03 12:21:05 2021 +0200
+++ b/mercurial/unionrepo.py	Mon May 03 12:21:15 2021 +0200
@@ -54,7 +54,18 @@
         for rev2 in self.revlog2:
             rev = self.revlog2.index[rev2]
             # rev numbers - in revlog2, very different from self.rev
-            _start, _csize, rsize, base, linkrev, p1rev, p2rev, node = rev
+            (
+                _start,
+                _csize,
+                rsize,
+                base,
+                linkrev,
+                p1rev,
+                p2rev,
+                node,
+                _sdo,
+                _sds,
+            ) = rev
             flags = _start & 0xFFFF
 
             if linkmapper is None:  # link is to same revlog
--- a/tests/test-parseindex2.py	Mon May 03 12:21:05 2021 +0200
+++ b/tests/test-parseindex2.py	Mon May 03 12:21:15 2021 +0200
@@ -49,6 +49,7 @@
         cache = (0, data)
         while off <= l:
             e = struct.unpack(indexformatng, data[off : off + s])
+            e = e + (0, 0)
             nodemap[e[7]] = n
             append(e)
             n += 1
@@ -58,6 +59,7 @@
     else:
         while off <= l:
             e = struct.unpack(indexformatng, data[off : off + s])
+            e = e + (0, 0)
             nodemap[e[7]] = n
             append(e)
             n += 1
@@ -240,7 +242,7 @@
                 break
 
     def testminusone(self):
-        want = (0, 0, 0, -1, -1, -1, -1, sha1nodeconstants.nullid)
+        want = (0, 0, 0, -1, -1, -1, -1, sha1nodeconstants.nullid, 0, 0)
         index, junk = parsers.parse_index2(data_inlined, True)
         got = index[-1]
         self.assertEqual(want, got)  # inline data