mercurial/revlog.py
changeset 47242 4abd474a10af
parent 47241 2219853a1503
child 47245 de63be070e02
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