Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/revlog.py @ 46723: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
46722:3d740058b467 | 46723: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 |