comparison mercurial/branchmap.py @ 48363:8e5effbf52d0 stable

branchmap: stop writing cache for uncommitted data If we are about to write the branch while a transaction is active. we delay that write. After the transaction is closed, we flush all the write we delayed (unless they have been written in between). Differential Revision: https://phab.mercurial-scm.org/D12128
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Tue, 01 Feb 2022 15:19:50 +0100
parents bea4717415c0
children f8f2ecdde4b5
comparison
equal deleted inserted replaced
48362:3f618484eeb6 48363:8e5effbf52d0
147 return 147 return
148 148
149 def clear(self): 149 def clear(self):
150 self._per_filter.clear() 150 self._per_filter.clear()
151 151
152 def write_delayed(self, repo):
153 unfi = repo.unfiltered()
154 for filtername, cache in self._per_filter.items():
155 if cache._delayed:
156 repo = unfi.filtered(filtername)
157 cache.write(repo)
158
152 159
153 def _unknownnode(node): 160 def _unknownnode(node):
154 """raises ValueError when branchcache found a node which does not exists""" 161 """raises ValueError when branchcache found a node which does not exists"""
155 raise ValueError('node %s does not exist' % pycompat.sysstr(hex(node))) 162 raise ValueError('node %s does not exist' % pycompat.sysstr(hex(node)))
156 163
197 # type: (localrepo.localrepository, Union[Dict[bytes, List[bytes]], Iterable[Tuple[bytes, List[bytes]]]], bytes, int, Optional[bytes], Optional[Set[bytes]], Optional[Callable[[bytes], bool]]) -> None 204 # type: (localrepo.localrepository, Union[Dict[bytes, List[bytes]], Iterable[Tuple[bytes, List[bytes]]]], bytes, int, Optional[bytes], Optional[Set[bytes]], Optional[Callable[[bytes], bool]]) -> None
198 """hasnode is a function which can be used to verify whether changelog 205 """hasnode is a function which can be used to verify whether changelog
199 has a given node or not. If it's not provided, we assume that every node 206 has a given node or not. If it's not provided, we assume that every node
200 we have exists in changelog""" 207 we have exists in changelog"""
201 self._repo = repo 208 self._repo = repo
209 self._delayed = False
202 if tipnode is None: 210 if tipnode is None:
203 self.tipnode = repo.nullid 211 self.tipnode = repo.nullid
204 else: 212 else:
205 self.tipnode = tipnode 213 self.tipnode = tipnode
206 self.tiprev = tiprev 214 self.tiprev = tiprev
401 self.filteredhash, 409 self.filteredhash,
402 self._closednodes, 410 self._closednodes,
403 ) 411 )
404 412
405 def write(self, repo): 413 def write(self, repo):
414 tr = repo.currenttransaction()
415 if not getattr(tr, 'finalized', True):
416 # Avoid premature writing.
417 #
418 # (The cache warming setup by localrepo will update the file later.)
419 self._delayed = True
420 return
406 try: 421 try:
407 f = repo.cachevfs(self._filename(repo), b"w", atomictemp=True) 422 f = repo.cachevfs(self._filename(repo), b"w", atomictemp=True)
408 cachekey = [hex(self.tipnode), b'%d' % self.tiprev] 423 cachekey = [hex(self.tipnode), b'%d' % self.tiprev]
409 if self.filteredhash is not None: 424 if self.filteredhash is not None:
410 cachekey.append(hex(self.filteredhash)) 425 cachekey.append(hex(self.filteredhash))
425 b'wrote %s with %d labels and %d nodes\n', 440 b'wrote %s with %d labels and %d nodes\n',
426 _branchcachedesc(repo), 441 _branchcachedesc(repo),
427 len(self._entries), 442 len(self._entries),
428 nodecount, 443 nodecount,
429 ) 444 )
445 self._delayed = False
430 except (IOError, OSError, error.Abort) as inst: 446 except (IOError, OSError, error.Abort) as inst:
431 # Abort may be raised by read only opener, so log and continue 447 # Abort may be raised by read only opener, so log and continue
432 repo.ui.debug( 448 repo.ui.debug(
433 b"couldn't write branch cache: %s\n" 449 b"couldn't write branch cache: %s\n"
434 % stringutil.forcebytestr(inst) 450 % stringutil.forcebytestr(inst)