Commit e41a164db7a by Pierre-Yves David

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
parent 6614b301ea5
......@@ -2137,6 +2137,7 @@ def debugnodemap(ui, repo, **opts):
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(
......
......@@ -170,15 +170,15 @@ class PersistentNodeMapIndexObject(IndexObject):
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
......
......@@ -639,7 +639,7 @@ class revlog(object):
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
......
......@@ -36,9 +36,11 @@ def persisted_data(revlog):
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 @@ def _persist_nodemap(tr, revlog):
# 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 @@ def _persist_nodemap(tr, revlog):
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 @@ class NodeMapDocket(object):
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)
......
......@@ -14,8 +14,9 @@ Test the persistent on-disk nodemap
$ 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 @@ add a new commit
$ 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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment