comparison mercurial/revlogutils/nodemap.py @ 44516:64e2f603de9d

nodemap: make sure hooks have access to an up-to-date version We make sure hooks can read persistent nodemap data and that they access something up-to-date with the pending transaction. Differential Revision: https://phab.mercurial-scm.org/D8187
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Fri, 28 Feb 2020 00:29:18 +0100
parents 6c906eaedd0d
children 448d700e0d27
comparison
equal deleted inserted replaced
44515:6c906eaedd0d 44516:64e2f603de9d
73 if revlog.nodemap_file is None: 73 if revlog.nodemap_file is None:
74 return # we do not use persistent_nodemap on this revlog 74 return # we do not use persistent_nodemap on this revlog
75 callback_id = b"revlog-persistent-nodemap-%s" % revlog.nodemap_file 75 callback_id = b"revlog-persistent-nodemap-%s" % revlog.nodemap_file
76 if tr.hasfinalize(callback_id): 76 if tr.hasfinalize(callback_id):
77 return # no need to register again 77 return # no need to register again
78 tr.addpending(
79 callback_id, lambda tr: _persist_nodemap(tr, revlog, pending=True)
80 )
78 tr.addfinalize(callback_id, lambda tr: _persist_nodemap(tr, revlog)) 81 tr.addfinalize(callback_id, lambda tr: _persist_nodemap(tr, revlog))
79 82
80 83
81 class _NoTransaction(object): 84 class _NoTransaction(object):
82 """transaction like object to update the nodemap outside a transaction 85 """transaction like object to update the nodemap outside a transaction
99 _persist_nodemap(notr, revlog) 102 _persist_nodemap(notr, revlog)
100 for k in sorted(notr._postclose): 103 for k in sorted(notr._postclose):
101 notr._postclose[k](None) 104 notr._postclose[k](None)
102 105
103 106
104 def _persist_nodemap(tr, revlog): 107 def _persist_nodemap(tr, revlog, pending=False):
105 """Write nodemap data on disk for a given revlog 108 """Write nodemap data on disk for a given revlog
106 """ 109 """
107 if getattr(revlog, 'filteredrevs', ()): 110 if getattr(revlog, 'filteredrevs', ()):
108 raise error.ProgrammingError( 111 raise error.ProgrammingError(
109 "cannot persist nodemap of a filtered changelog" 112 "cannot persist nodemap of a filtered changelog"
167 target_docket.data_length = len(data) 170 target_docket.data_length = len(data)
168 target_docket.tip_rev = revlog.tiprev() 171 target_docket.tip_rev = revlog.tiprev()
169 target_docket.tip_node = revlog.node(target_docket.tip_rev) 172 target_docket.tip_node = revlog.node(target_docket.tip_rev)
170 # EXP-TODO: if this is a cache, this should use a cache vfs, not a 173 # EXP-TODO: if this is a cache, this should use a cache vfs, not a
171 # store vfs 174 # store vfs
172 with revlog.opener(revlog.nodemap_file, b'w', atomictemp=True) as fp: 175 file_path = revlog.nodemap_file
176 if pending:
177 file_path += b'.a'
178 with revlog.opener(file_path, b'w', atomictemp=True) as fp:
173 fp.write(target_docket.serialize()) 179 fp.write(target_docket.serialize())
174 revlog._nodemap_docket = target_docket 180 revlog._nodemap_docket = target_docket
175 if feed_data: 181 if feed_data:
176 revlog.index.update_nodemap_data(target_docket, new_data) 182 revlog.index.update_nodemap_data(target_docket, new_data)
177 183
302 return b''.join(data) 308 return b''.join(data)
303 309
304 310
305 def _rawdata_filepath(revlog, docket): 311 def _rawdata_filepath(revlog, docket):
306 """The (vfs relative) nodemap's rawdata file for a given uid""" 312 """The (vfs relative) nodemap's rawdata file for a given uid"""
307 prefix = revlog.nodemap_file[:-2] 313 if revlog.nodemap_file.endswith(b'.n.a'):
314 prefix = revlog.nodemap_file[:-4]
315 else:
316 prefix = revlog.nodemap_file[:-2]
308 return b"%s-%s.nd" % (prefix, docket.uid) 317 return b"%s-%s.nd" % (prefix, docket.uid)
309 318
310 319
311 def _other_rawdata_filepath(revlog, docket): 320 def _other_rawdata_filepath(revlog, docket):
312 prefix = revlog.nodemap_file[:-2] 321 prefix = revlog.nodemap_file[:-2]