Mercurial > public > mercurial-scm > hg
comparison mercurial/revlog.py @ 47242:4abd474a10af
revlogv2: also keep track for the size of the "data" file
This is useful to make sure we always start writing at the right location,
without effort.
Differential Revision: https://phab.mercurial-scm.org/D10632
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Mon, 03 May 2021 12:35:35 +0200 |
parents | 2219853a1503 |
children | de63be070e02 |
comparison
equal
deleted
inserted
replaced
47241:2219853a1503 | 47242:4abd474a10af |
---|---|
2086 dsize = self.end(r - 1) | 2086 dsize = self.end(r - 1) |
2087 dfh = None | 2087 dfh = None |
2088 if not self._inline: | 2088 if not self._inline: |
2089 try: | 2089 try: |
2090 dfh = self._datafp(b"r+") | 2090 dfh = self._datafp(b"r+") |
2091 dfh.seek(0, os.SEEK_END) | 2091 if self._docket is None: |
2092 dfh.seek(0, os.SEEK_END) | |
2093 else: | |
2094 dfh.seek(self._docket.data_end, os.SEEK_SET) | |
2092 except IOError as inst: | 2095 except IOError as inst: |
2093 if inst.errno != errno.ENOENT: | 2096 if inst.errno != errno.ENOENT: |
2094 raise | 2097 raise |
2095 dfh = self._datafp(b"w+") | 2098 dfh = self._datafp(b"w+") |
2096 transaction.add(self._datafile, dsize) | 2099 transaction.add(self._datafile, dsize) |
2453 end of the data file within a transaction, you can have cases where, for | 2456 end of the data file within a transaction, you can have cases where, for |
2454 example, rev `n` does not have sidedata while rev `n - 1` does, leading | 2457 example, rev `n` does not have sidedata while rev `n - 1` does, leading |
2455 to `n - 1`'s sidedata being written after `n`'s data. | 2458 to `n - 1`'s sidedata being written after `n`'s data. |
2456 | 2459 |
2457 TODO cache this in a docket file before getting out of experimental.""" | 2460 TODO cache this in a docket file before getting out of experimental.""" |
2458 if self._format_version != REVLOGV2: | 2461 if self._docket is None: |
2459 return self.end(prev) | 2462 return self.end(prev) |
2460 | 2463 else: |
2461 offset = 0 | 2464 return self._docket.data_end |
2462 for rev, entry in enumerate(self.index): | |
2463 sidedata_end = entry[8] + entry[9] | |
2464 # Sidedata for a previous rev has potentially been written after | |
2465 # this rev's end, so take the max. | |
2466 offset = max(self.end(rev), offset, sidedata_end) | |
2467 return offset | |
2468 | 2465 |
2469 def _writeentry(self, transaction, entry, data, link, offset, sidedata): | 2466 def _writeentry(self, transaction, entry, data, link, offset, sidedata): |
2470 # Files opened in a+ mode have inconsistent behavior on various | 2467 # Files opened in a+ mode have inconsistent behavior on various |
2471 # platforms. Windows requires that a file positioning call be made | 2468 # platforms. Windows requires that a file positioning call be made |
2472 # when the file handle transitions between reads and writes. See | 2469 # when the file handle transitions between reads and writes. See |
2486 if self._docket is None: | 2483 if self._docket is None: |
2487 ifh.seek(0, os.SEEK_END) | 2484 ifh.seek(0, os.SEEK_END) |
2488 else: | 2485 else: |
2489 ifh.seek(self._docket.index_end, os.SEEK_SET) | 2486 ifh.seek(self._docket.index_end, os.SEEK_SET) |
2490 if dfh: | 2487 if dfh: |
2491 dfh.seek(0, os.SEEK_END) | 2488 if self._docket is None: |
2489 dfh.seek(0, os.SEEK_END) | |
2490 else: | |
2491 dfh.seek(self._docket.data_end, os.SEEK_SET) | |
2492 | 2492 |
2493 curr = len(self) - 1 | 2493 curr = len(self) - 1 |
2494 if not self._inline: | 2494 if not self._inline: |
2495 transaction.add(self._datafile, offset) | 2495 transaction.add(self._datafile, offset) |
2496 transaction.add(self._indexfile, curr * len(entry)) | 2496 transaction.add(self._indexfile, curr * len(entry)) |
2509 if sidedata: | 2509 if sidedata: |
2510 ifh.write(sidedata) | 2510 ifh.write(sidedata) |
2511 self._enforceinlinesize(transaction) | 2511 self._enforceinlinesize(transaction) |
2512 if self._docket is not None: | 2512 if self._docket is not None: |
2513 self._docket.index_end = self._writinghandles[0].tell() | 2513 self._docket.index_end = self._writinghandles[0].tell() |
2514 self._docket.data_end = self._writinghandles[1].tell() | |
2514 | 2515 |
2515 nodemaputil.setup_persistent_nodemap(transaction, self) | 2516 nodemaputil.setup_persistent_nodemap(transaction, self) |
2516 | 2517 |
2517 def addgroup( | 2518 def addgroup( |
2518 self, | 2519 self, |
2671 rev, _ = self.getstrippoint(minlink) | 2672 rev, _ = self.getstrippoint(minlink) |
2672 if rev == len(self): | 2673 if rev == len(self): |
2673 return | 2674 return |
2674 | 2675 |
2675 # first truncate the files on disk | 2676 # first truncate the files on disk |
2676 end = self.start(rev) | 2677 data_end = self.start(rev) |
2677 if not self._inline: | 2678 if not self._inline: |
2678 transaction.add(self._datafile, end) | 2679 transaction.add(self._datafile, data_end) |
2679 end = rev * self.index.entry_size | 2680 end = rev * self.index.entry_size |
2680 else: | 2681 else: |
2681 end += rev * self.index.entry_size | 2682 end = data_end + (rev * self.index.entry_size) |
2682 | 2683 |
2683 transaction.add(self._indexfile, end) | 2684 transaction.add(self._indexfile, end) |
2684 if self._docket is not None: | 2685 if self._docket is not None: |
2685 # XXX we could, leverage the docket while stripping. However it is | 2686 # XXX we could, leverage the docket while stripping. However it is |
2686 # not powerfull enough at the time of this comment | 2687 # not powerfull enough at the time of this comment |
2687 self._docket.index_end = end | 2688 self._docket.index_end = end |
2689 self._docket.data_end = data_end | |
2688 self._docket.write(transaction, stripping=True) | 2690 self._docket.write(transaction, stripping=True) |
2689 | 2691 |
2690 # then reset internal state in memory to forget those revisions | 2692 # then reset internal state in memory to forget those revisions |
2691 self._revisioncache = None | 2693 self._revisioncache = None |
2692 self._chaininfocache = util.lrucachedict(500) | 2694 self._chaininfocache = util.lrucachedict(500) |
3208 | 3210 |
3209 new_entries = [] | 3211 new_entries = [] |
3210 # append the new sidedata | 3212 # append the new sidedata |
3211 with self._writing(transaction): | 3213 with self._writing(transaction): |
3212 ifh, dfh = self._writinghandles | 3214 ifh, dfh = self._writinghandles |
3213 dfh.seek(0, os.SEEK_END) | 3215 if self._docket is not None: |
3216 dfh.seek(self._docket.data_end, os.SEEK_SET) | |
3217 else: | |
3218 dfh.seek(0, os.SEEK_END) | |
3219 | |
3214 current_offset = dfh.tell() | 3220 current_offset = dfh.tell() |
3215 for rev in range(startrev, endrev + 1): | 3221 for rev in range(startrev, endrev + 1): |
3216 entry = self.index[rev] | 3222 entry = self.index[rev] |
3217 new_sidedata, flags = sidedatautil.run_sidedata_helpers( | 3223 new_sidedata, flags = sidedatautil.run_sidedata_helpers( |
3218 store=self, | 3224 store=self, |
3240 # the sidedata computation might have move the file cursors around | 3246 # the sidedata computation might have move the file cursors around |
3241 dfh.seek(current_offset, os.SEEK_SET) | 3247 dfh.seek(current_offset, os.SEEK_SET) |
3242 dfh.write(serialized_sidedata) | 3248 dfh.write(serialized_sidedata) |
3243 new_entries.append(entry) | 3249 new_entries.append(entry) |
3244 current_offset += len(serialized_sidedata) | 3250 current_offset += len(serialized_sidedata) |
3251 if self._docket is not None: | |
3252 self._docket.data_end = dfh.tell() | |
3245 | 3253 |
3246 # rewrite the new index entries | 3254 # rewrite the new index entries |
3247 ifh.seek(startrev * self.index.entry_size) | 3255 ifh.seek(startrev * self.index.entry_size) |
3248 for i, e in enumerate(new_entries): | 3256 for i, e in enumerate(new_entries): |
3249 rev = startrev + i | 3257 rev = startrev + i |