comparison mercurial/revlog.py @ 46710:4cd214c9948d

revlogv2: don't assume that the sidedata of the last rev is right after data We are going to be rewriting sidedata soon, it's going to be appended to the revlog data file, meaning that the data and the sidedata might not be contiguous. Differential Revision: https://phab.mercurial-scm.org/D10025
author Raphaël Gomès <rgomes@octobus.net>
date Fri, 19 Feb 2021 11:07:10 +0100
parents 3d740058b467
children a41565bef69f
comparison
equal deleted inserted replaced
46709:3d740058b467 46710:4cd214c9948d
918 raise 918 raise
919 919
920 # Derived from index values. 920 # Derived from index values.
921 921
922 def end(self, rev): 922 def end(self, rev):
923 return self.start(rev) + self.length(rev) + self.sidedata_length(rev) 923 return self.start(rev) + self.length(rev)
924 924
925 def parents(self, node): 925 def parents(self, node):
926 i = self.index 926 i = self.index
927 d = i[self.rev(node)] 927 d = i[self.rev(node)]
928 return i[d[5]][7], i[d[6]][7] # map revisions to nodes inline 928 return i[d[5]][7], i[d[6]][7] # map revisions to nodes inline
2329 2329
2330 btext = [rawtext] 2330 btext = [rawtext]
2331 2331
2332 curr = len(self) 2332 curr = len(self)
2333 prev = curr - 1 2333 prev = curr - 1
2334 offset = self.end(prev) 2334
2335 offset = self._get_data_offset(prev)
2335 2336
2336 if self._concurrencychecker: 2337 if self._concurrencychecker:
2337 if self._inline: 2338 if self._inline:
2338 # offset is "as if" it were in the .d file, so we need to add on 2339 # offset is "as if" it were in the .d file, so we need to add on
2339 # the size of the entry metadata. 2340 # the size of the entry metadata.
2414 2415
2415 if type(rawtext) == bytes: # only accept immutable objects 2416 if type(rawtext) == bytes: # only accept immutable objects
2416 self._revisioncache = (node, curr, rawtext) 2417 self._revisioncache = (node, curr, rawtext)
2417 self._chainbasecache[curr] = deltainfo.chainbase 2418 self._chainbasecache[curr] = deltainfo.chainbase
2418 return curr 2419 return curr
2420
2421 def _get_data_offset(self, prev):
2422 """Returns the current offset in the (in-transaction) data file.
2423 Versions < 2 of the revlog can get this 0(1), revlog v2 needs a docket
2424 file to store that information: since sidedata can be rewritten to the
2425 end of the data file within a transaction, you can have cases where, for
2426 example, rev `n` does not have sidedata while rev `n - 1` does, leading
2427 to `n - 1`'s sidedata being written after `n`'s data.
2428
2429 TODO cache this in a docket file before getting out of experimental."""
2430 if self.version & 0xFFFF != REVLOGV2:
2431 return self.end(prev)
2432
2433 offset = 0
2434 for rev, entry in enumerate(self.index):
2435 sidedata_end = entry[8] + entry[9]
2436 # Sidedata for a previous rev has potentially been written after
2437 # this rev's end, so take the max.
2438 offset = max(self.end(rev), offset, sidedata_end)
2439 return offset
2419 2440
2420 def _writeentry( 2441 def _writeentry(
2421 self, transaction, ifh, dfh, entry, data, link, offset, sidedata 2442 self, transaction, ifh, dfh, entry, data, link, offset, sidedata
2422 ): 2443 ):
2423 # Files opened in a+ mode have inconsistent behavior on various 2444 # Files opened in a+ mode have inconsistent behavior on various