Mercurial > hg
comparison mercurial/revlogutils/nodemap.py @ 44322:72c15641c8b4
nodemap: introduce an explicit class/object for the docket
We are about to add more information to this docket, having a clear location to
stock them in memory will help.
Differential Revision: https://phab.mercurial-scm.org/D7884
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Wed, 15 Jan 2020 15:49:35 +0100 |
parents | f0862ee1a31e |
children | 76a96e3a2bbb |
comparison
equal
deleted
inserted
replaced
44321:f0862ee1a31e | 44322:72c15641c8b4 |
---|---|
34 offset = 0 | 34 offset = 0 |
35 (version,) = S_VERSION.unpack(pdata[offset : offset + S_VERSION.size]) | 35 (version,) = S_VERSION.unpack(pdata[offset : offset + S_VERSION.size]) |
36 if version != ONDISK_VERSION: | 36 if version != ONDISK_VERSION: |
37 return None | 37 return None |
38 offset += S_VERSION.size | 38 offset += S_VERSION.size |
39 (uuid_size,) = S_HEADER.unpack(pdata[offset : offset + S_HEADER.size]) | 39 (uid_size,) = S_HEADER.unpack(pdata[offset : offset + S_HEADER.size]) |
40 offset += S_HEADER.size | 40 offset += S_HEADER.size |
41 uid = pdata[offset : offset + uuid_size] | 41 docket = NodeMapDocket(pdata[offset : offset + uid_size]) |
42 | 42 |
43 filename = _rawdata_filepath(revlog, uid) | 43 filename = _rawdata_filepath(revlog, docket) |
44 return revlog.opener.tryread(filename) | 44 return revlog.opener.tryread(filename) |
45 | 45 |
46 | 46 |
47 def setup_persistent_nodemap(tr, revlog): | 47 def setup_persistent_nodemap(tr, revlog): |
48 """Install whatever is needed transaction side to persist a nodemap on disk | 48 """Install whatever is needed transaction side to persist a nodemap on disk |
71 raise error.ProgrammingError(msg) | 71 raise error.ProgrammingError(msg) |
72 if util.safehasattr(revlog.index, "nodemap_data_all"): | 72 if util.safehasattr(revlog.index, "nodemap_data_all"): |
73 data = revlog.index.nodemap_data_all() | 73 data = revlog.index.nodemap_data_all() |
74 else: | 74 else: |
75 data = persistent_data(revlog.index) | 75 data = persistent_data(revlog.index) |
76 uid = _make_uid() | 76 target_docket = NodeMapDocket() |
77 datafile = _rawdata_filepath(revlog, uid) | 77 datafile = _rawdata_filepath(revlog, target_docket) |
78 olds = _other_rawdata_filepath(revlog, uid) | 78 olds = _other_rawdata_filepath(revlog, target_docket) |
79 if olds: | 79 if olds: |
80 realvfs = getattr(revlog, '_realopener', revlog.opener) | 80 realvfs = getattr(revlog, '_realopener', revlog.opener) |
81 | 81 |
82 def cleanup(tr): | 82 def cleanup(tr): |
83 for oldfile in olds: | 83 for oldfile in olds: |
90 with revlog.opener(datafile, b'w') as fd: | 90 with revlog.opener(datafile, b'w') as fd: |
91 fd.write(data) | 91 fd.write(data) |
92 # EXP-TODO: if this is a cache, this should use a cache vfs, not a | 92 # EXP-TODO: if this is a cache, this should use a cache vfs, not a |
93 # store vfs | 93 # store vfs |
94 with revlog.opener(revlog.nodemap_file, b'w', atomictemp=True) as fp: | 94 with revlog.opener(revlog.nodemap_file, b'w', atomictemp=True) as fp: |
95 fp.write(_serialize_docket(uid)) | 95 fp.write(target_docket.serialize()) |
96 # EXP-TODO: if the transaction abort, we should remove the new data and | 96 # EXP-TODO: if the transaction abort, we should remove the new data and |
97 # reinstall the old one. | 97 # reinstall the old one. |
98 | 98 |
99 | 99 |
100 ### Nodemap docket file | 100 ### Nodemap docket file |
133 | 133 |
134 The identifier is random and composed of ascii characters.""" | 134 The identifier is random and composed of ascii characters.""" |
135 return nodemod.hex(os.urandom(ID_SIZE)) | 135 return nodemod.hex(os.urandom(ID_SIZE)) |
136 | 136 |
137 | 137 |
138 def _serialize_docket(uid): | 138 class NodeMapDocket(object): |
139 """return serialized bytes for a docket using the passed uid""" | 139 """metadata associated with persistent nodemap data |
140 data = [] | 140 |
141 data.append(S_VERSION.pack(ONDISK_VERSION)) | 141 The persistent data may come from disk or be on their way to disk. |
142 data.append(S_HEADER.pack(len(uid))) | 142 """ |
143 data.append(uid) | 143 |
144 return b''.join(data) | 144 def __init__(self, uid=None): |
145 | 145 if uid is None: |
146 | 146 uid = _make_uid() |
147 def _rawdata_filepath(revlog, uid): | 147 self.uid = uid |
148 | |
149 def copy(self): | |
150 return NodeMapDocket(uid=self.uid) | |
151 | |
152 def serialize(self): | |
153 """return serialized bytes for a docket using the passed uid""" | |
154 data = [] | |
155 data.append(S_VERSION.pack(ONDISK_VERSION)) | |
156 data.append(S_HEADER.pack(len(self.uid))) | |
157 data.append(self.uid) | |
158 return b''.join(data) | |
159 | |
160 | |
161 def _rawdata_filepath(revlog, docket): | |
148 """The (vfs relative) nodemap's rawdata file for a given uid""" | 162 """The (vfs relative) nodemap's rawdata file for a given uid""" |
149 prefix = revlog.nodemap_file[:-2] | 163 prefix = revlog.nodemap_file[:-2] |
150 return b"%s-%s.nd" % (prefix, uid) | 164 return b"%s-%s.nd" % (prefix, docket.uid) |
151 | 165 |
152 | 166 |
153 def _other_rawdata_filepath(revlog, uid): | 167 def _other_rawdata_filepath(revlog, docket): |
154 prefix = revlog.nodemap_file[:-2] | 168 prefix = revlog.nodemap_file[:-2] |
155 pattern = re.compile(b"(^|/)%s-[0-9a-f]+\.nd$" % prefix) | 169 pattern = re.compile(b"(^|/)%s-[0-9a-f]+\.nd$" % prefix) |
156 new_file_path = _rawdata_filepath(revlog, uid) | 170 new_file_path = _rawdata_filepath(revlog, docket) |
157 new_file_name = revlog.opener.basename(new_file_path) | 171 new_file_name = revlog.opener.basename(new_file_path) |
158 dirpath = revlog.opener.dirname(new_file_path) | 172 dirpath = revlog.opener.dirname(new_file_path) |
159 others = [] | 173 others = [] |
160 for f in revlog.opener.listdir(dirpath): | 174 for f in revlog.opener.listdir(dirpath): |
161 if pattern.match(f) and f != new_file_name: | 175 if pattern.match(f) and f != new_file_name: |