diff --git a/mercurial/revlogutils/nodemap.py b/mercurial/revlogutils/nodemap.py --- a/mercurial/revlogutils/nodemap.py +++ b/mercurial/revlogutils/nodemap.py @@ -36,11 +36,11 @@ def persisted_data(revlog): if version != ONDISK_VERSION: return None offset += S_VERSION.size - (uuid_size,) = S_HEADER.unpack(pdata[offset : offset + S_HEADER.size]) + (uid_size,) = S_HEADER.unpack(pdata[offset : offset + S_HEADER.size]) offset += S_HEADER.size - uid = pdata[offset : offset + uuid_size] + docket = NodeMapDocket(pdata[offset : offset + uid_size]) - filename = _rawdata_filepath(revlog, uid) + filename = _rawdata_filepath(revlog, docket) return revlog.opener.tryread(filename) @@ -73,9 +73,9 @@ def _persist_nodemap(tr, revlog): data = revlog.index.nodemap_data_all() else: data = persistent_data(revlog.index) - uid = _make_uid() - datafile = _rawdata_filepath(revlog, uid) - olds = _other_rawdata_filepath(revlog, uid) + target_docket = NodeMapDocket() + datafile = _rawdata_filepath(revlog, target_docket) + olds = _other_rawdata_filepath(revlog, target_docket) if olds: realvfs = getattr(revlog, '_realopener', revlog.opener) @@ -92,7 +92,7 @@ def _persist_nodemap(tr, revlog): # 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: - fp.write(_serialize_docket(uid)) + fp.write(target_docket.serialize()) # EXP-TODO: if the transaction abort, we should remove the new data and # reinstall the old one. @@ -135,25 +135,39 @@ def _make_uid(): return nodemod.hex(os.urandom(ID_SIZE)) -def _serialize_docket(uid): - """return serialized bytes for a docket using the passed uid""" - data = [] - data.append(S_VERSION.pack(ONDISK_VERSION)) - data.append(S_HEADER.pack(len(uid))) - data.append(uid) - return b''.join(data) +class NodeMapDocket(object): + """metadata associated with persistent nodemap data + + The persistent data may come from disk or be on their way to disk. + """ + + def __init__(self, uid=None): + if uid is None: + uid = _make_uid() + self.uid = uid + + def copy(self): + return NodeMapDocket(uid=self.uid) + + 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))) + data.append(self.uid) + return b''.join(data) -def _rawdata_filepath(revlog, uid): +def _rawdata_filepath(revlog, docket): """The (vfs relative) nodemap's rawdata file for a given uid""" prefix = revlog.nodemap_file[:-2] - return b"%s-%s.nd" % (prefix, uid) + return b"%s-%s.nd" % (prefix, docket.uid) -def _other_rawdata_filepath(revlog, uid): +def _other_rawdata_filepath(revlog, docket): prefix = revlog.nodemap_file[:-2] pattern = re.compile(b"(^|/)%s-[0-9a-f]+\.nd$" % prefix) - new_file_path = _rawdata_filepath(revlog, uid) + new_file_path = _rawdata_filepath(revlog, docket) new_file_name = revlog.opener.basename(new_file_path) dirpath = revlog.opener.dirname(new_file_path) others = []