nodemap: track the maximum revision tracked in the nodemap
We need a simple way to detect when the on disk data contains less revision
than the index we read from disk. The docket file is meant for this, we just had
to start tracking that data.
We should also try to detect strip operation, but we will deal with this in
later changesets. Right now we are focusing on defining the API for index
supporting persistent nodemap.
Differential Revision: https://phab.mercurial-scm.org/D7888
--- a/mercurial/debugcommands.py Wed Jan 15 15:50:04 2020 +0100
+++ b/mercurial/debugcommands.py Wed Jan 15 15:50:14 2020 +0100
@@ -2137,6 +2137,7 @@
if nm_data is not None:
docket, data = nm_data
ui.write((b"uid: %s\n") % docket.uid)
+ ui.write((b"tip-rev: %d\n") % docket.tip_rev)
@command(
--- a/mercurial/pure/parsers.py Wed Jan 15 15:50:04 2020 +0100
+++ b/mercurial/pure/parsers.py Wed Jan 15 15:50:14 2020 +0100
@@ -170,15 +170,15 @@
self._nm_root = self._nm_max_idx = self._nm_rev = None
return data
- def update_nodemap_data(self, nm_data):
- """provide full blokc of persisted binary data for a nodemap
+ def update_nodemap_data(self, docket, nm_data):
+ """provide full block of persisted binary data for a nodemap
The data are expected to come from disk. See `nodemap_data_all` for a
produceur of such data."""
if nm_data is not None:
self._nm_root, self._nm_max_idx = nodemaputil.parse_data(nm_data)
if self._nm_root:
- self._nm_rev = len(self) - 1
+ self._nm_rev = docket.tip_rev
else:
self._nm_root = self._nm_max_idx = self._nm_rev = None
--- a/mercurial/revlog.py Wed Jan 15 15:50:04 2020 +0100
+++ b/mercurial/revlog.py Wed Jan 15 15:50:14 2020 +0100
@@ -639,7 +639,7 @@
if use_nodemap:
nodemap_data = nodemaputil.persisted_data(self)
if nodemap_data is not None:
- index.update_nodemap_data(nodemap_data[1])
+ index.update_nodemap_data(*nodemap_data)
except (ValueError, IndexError):
raise error.RevlogError(
_(b"index %s is corrupted") % self.indexfile
--- a/mercurial/revlogutils/nodemap.py Wed Jan 15 15:50:04 2020 +0100
+++ b/mercurial/revlogutils/nodemap.py Wed Jan 15 15:50:14 2020 +0100
@@ -36,9 +36,11 @@
if version != ONDISK_VERSION:
return None
offset += S_VERSION.size
- (uid_size,) = S_HEADER.unpack(pdata[offset : offset + S_HEADER.size])
+ headers = S_HEADER.unpack(pdata[offset : offset + S_HEADER.size])
+ uid_size, tip_rev = headers
offset += S_HEADER.size
docket = NodeMapDocket(pdata[offset : offset + uid_size])
+ docket.tip_rev = tip_rev
filename = _rawdata_filepath(revlog, docket)
return docket, revlog.opener.tryread(filename)
@@ -94,6 +96,7 @@
# store vfs
with revlog.opener(datafile, b'w') as fd:
fd.write(data)
+ target_docket.tip_rev = revlog.tiprev()
# EXP-TODO: if this is a cache, this should use a cache vfs, not a
# store vfs
with revlog.opener(revlog.nodemap_file, b'w', atomictemp=True) as fp:
@@ -142,7 +145,7 @@
ONDISK_VERSION = 0
S_VERSION = struct.Struct(">B")
-S_HEADER = struct.Struct(">B")
+S_HEADER = struct.Struct(">BQ")
ID_SIZE = 8
@@ -164,15 +167,19 @@
if uid is None:
uid = _make_uid()
self.uid = uid
+ self.tip_rev = None
def copy(self):
- return NodeMapDocket(uid=self.uid)
+ new = NodeMapDocket(uid=self.uid)
+ new.tip_rev = self.tip_rev
+ return new
def serialize(self):
"""return serialized bytes for a docket using the passed uid"""
data = []
data.append(S_VERSION.pack(ONDISK_VERSION))
- data.append(S_HEADER.pack(len(self.uid)))
+ headers = (len(self.uid), self.tip_rev)
+ data.append(S_HEADER.pack(*headers))
data.append(self.uid)
return b''.join(data)
--- a/tests/test-persistent-nodemap.t Wed Jan 15 15:50:04 2020 +0100
+++ b/tests/test-persistent-nodemap.t Wed Jan 15 15:50:14 2020 +0100
@@ -14,8 +14,9 @@
$ hg debugbuilddag .+5000
$ hg debugnodemap --metadata
uid: ???????????????? (glob)
+ tip-rev: 5000
$ f --size .hg/store/00changelog.n
- .hg/store/00changelog.n: size=18
+ .hg/store/00changelog.n: size=26
$ f --sha256 .hg/store/00changelog-*.nd
.hg/store/00changelog-????????????????.nd: sha256=b961925120e1c9bc345c199b2cc442abc477029fdece37ef9d99cbe59c0558b7 (glob)
$ hg debugnodemap --dump-new | f --sha256 --size
@@ -51,8 +52,9 @@
$ hg ci -m 'foo'
$ hg debugnodemap --metadata
uid: ???????????????? (glob)
+ tip-rev: 5001
$ f --size .hg/store/00changelog.n
- .hg/store/00changelog.n: size=18
+ .hg/store/00changelog.n: size=26
(The pure code use the debug code that perform incremental update, the C code reencode from scratch)