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