mercurial/revlog.py
changeset 51084 df50a1592e0c
parent 51083 c3748f38dcd0
child 51085 31f143448704
equal deleted inserted replaced
51083:c3748f38dcd0 51084:df50a1592e0c
   506             mode=b"w",
   506             mode=b"w",
   507             checkambig=self.data_config.check_ambig,
   507             checkambig=self.data_config.check_ambig,
   508             atomictemp=True,
   508             atomictemp=True,
   509         )
   509         )
   510 
   510 
       
   511     def get_segment_for_revs(self, startrev, endrev):
       
   512         """Obtain a segment of raw data corresponding to a range of revisions.
       
   513 
       
   514         Accepts the start and end revisions and an optional already-open
       
   515         file handle to be used for reading. If the file handle is read, its
       
   516         seek position will not be preserved.
       
   517 
       
   518         Requests for data may be satisfied by a cache.
       
   519 
       
   520         Returns a 2-tuple of (offset, data) for the requested range of
       
   521         revisions. Offset is the integer offset from the beginning of the
       
   522         revlog and data is a str or buffer of the raw byte data.
       
   523 
       
   524         Callers will need to call ``self.start(rev)`` and ``self.length(rev)``
       
   525         to determine where each revision's data begins and ends.
       
   526 
       
   527         API: we should consider making this a private part of the InnerRevlog
       
   528         at some point.
       
   529         """
       
   530         # Inlined self.start(startrev) & self.end(endrev) for perf reasons
       
   531         # (functions are expensive).
       
   532         index = self.index
       
   533         istart = index[startrev]
       
   534         start = int(istart[0] >> 16)
       
   535         if startrev == endrev:
       
   536             end = start + istart[1]
       
   537         else:
       
   538             iend = index[endrev]
       
   539             end = int(iend[0] >> 16) + iend[1]
       
   540 
       
   541         if self.inline:
       
   542             start += (startrev + 1) * self.index.entry_size
       
   543             end += (endrev + 1) * self.index.entry_size
       
   544         length = end - start
       
   545 
       
   546         return start, self._segmentfile.read_chunk(start, length)
       
   547 
   511 
   548 
   512 class revlog:
   549 class revlog:
   513     """
   550     """
   514     the underlying revision storage object
   551     the underlying revision storage object
   515 
   552 
   998                             header |= self._format_version
  1035                             header |= self._format_version
   999                             header |= FLAG_INLINE_DATA
  1036                             header |= FLAG_INLINE_DATA
  1000                             header = self.index.pack_header(header)
  1037                             header = self.index.pack_header(header)
  1001                             idx = header + idx
  1038                             idx = header + idx
  1002                         yield idx
  1039                         yield idx
  1003                         yield self._getsegmentforrevs(rev, rev)[1]
  1040                         yield self._inner.get_segment_for_revs(rev, rev)[1]
  1004 
  1041 
  1005             inline_stream = get_stream()
  1042             inline_stream = get_stream()
  1006             next(inline_stream)
  1043             next(inline_stream)
  1007             return [
  1044             return [
  1008                 (self._indexfile, inline_stream, index_size + data_size),
  1045                 (self._indexfile, inline_stream, index_size + data_size),
  2151         returns True if text is different than what is stored.
  2188         returns True if text is different than what is stored.
  2152         """
  2189         """
  2153         p1, p2 = self.parents(node)
  2190         p1, p2 = self.parents(node)
  2154         return storageutil.hashrevisionsha1(text, p1, p2) != node
  2191         return storageutil.hashrevisionsha1(text, p1, p2) != node
  2155 
  2192 
  2156     def _getsegmentforrevs(self, startrev, endrev):
       
  2157         """Obtain a segment of raw data corresponding to a range of revisions.
       
  2158 
       
  2159         Accepts the start and end revisions and an optional already-open
       
  2160         file handle to be used for reading. If the file handle is read, its
       
  2161         seek position will not be preserved.
       
  2162 
       
  2163         Requests for data may be satisfied by a cache.
       
  2164 
       
  2165         Returns a 2-tuple of (offset, data) for the requested range of
       
  2166         revisions. Offset is the integer offset from the beginning of the
       
  2167         revlog and data is a str or buffer of the raw byte data.
       
  2168 
       
  2169         Callers will need to call ``self.start(rev)`` and ``self.length(rev)``
       
  2170         to determine where each revision's data begins and ends.
       
  2171         """
       
  2172         # Inlined self.start(startrev) & self.end(endrev) for perf reasons
       
  2173         # (functions are expensive).
       
  2174         index = self.index
       
  2175         istart = index[startrev]
       
  2176         start = int(istart[0] >> 16)
       
  2177         if startrev == endrev:
       
  2178             end = start + istart[1]
       
  2179         else:
       
  2180             iend = index[endrev]
       
  2181             end = int(iend[0] >> 16) + iend[1]
       
  2182 
       
  2183         if self._inline:
       
  2184             start += (startrev + 1) * self.index.entry_size
       
  2185             end += (endrev + 1) * self.index.entry_size
       
  2186         length = end - start
       
  2187 
       
  2188         return start, self._inner._segmentfile.read_chunk(start, length)
       
  2189 
       
  2190     def _chunk(self, rev):
  2193     def _chunk(self, rev):
  2191         """Obtain a single decompressed chunk for a revision.
  2194         """Obtain a single decompressed chunk for a revision.
  2192 
  2195 
  2193         Accepts an integer revision and an optional already-open file handle
  2196         Accepts an integer revision and an optional already-open file handle
  2194         to be used for reading. If used, the seek position of the file will not
  2197         to be used for reading. If used, the seek position of the file will not
  2195         be preserved.
  2198         be preserved.
  2196 
  2199 
  2197         Returns a str holding uncompressed data for the requested revision.
  2200         Returns a str holding uncompressed data for the requested revision.
  2198         """
  2201         """
  2199         compression_mode = self.index[rev][10]
  2202         compression_mode = self.index[rev][10]
  2200         data = self._getsegmentforrevs(rev, rev)[1]
  2203         data = self._inner.get_segment_for_revs(rev, rev)[1]
  2201         if compression_mode == COMP_MODE_PLAIN:
  2204         if compression_mode == COMP_MODE_PLAIN:
  2202             return data
  2205             return data
  2203         elif compression_mode == COMP_MODE_DEFAULT:
  2206         elif compression_mode == COMP_MODE_DEFAULT:
  2204             return self._decompressor(data)
  2207             return self._decompressor(data)
  2205         elif compression_mode == COMP_MODE_INLINE:
  2208         elif compression_mode == COMP_MODE_INLINE:
  2246             for lastrev in revschunk[::-1]:
  2249             for lastrev in revschunk[::-1]:
  2247                 if length(lastrev) != 0:
  2250                 if length(lastrev) != 0:
  2248                     break
  2251                     break
  2249 
  2252 
  2250             try:
  2253             try:
  2251                 offset, data = self._getsegmentforrevs(firstrev, lastrev)
  2254                 offset, data = self._inner.get_segment_for_revs(
       
  2255                     firstrev,
       
  2256                     lastrev,
       
  2257                 )
  2252             except OverflowError:
  2258             except OverflowError:
  2253                 # issue4215 - we can't cache a run of chunks greater than
  2259                 # issue4215 - we can't cache a run of chunks greater than
  2254                 # 2G on Windows
  2260                 # 2G on Windows
  2255                 return [self._chunk(rev) for rev in revschunk]
  2261                 return [self._chunk(rev) for rev in revschunk]
  2256 
  2262 
  2614         new_dfh = self._datafp(b'w+')
  2620         new_dfh = self._datafp(b'w+')
  2615         new_dfh.truncate(0)  # drop any potentially existing data
  2621         new_dfh.truncate(0)  # drop any potentially existing data
  2616         try:
  2622         try:
  2617             with self.reading():
  2623             with self.reading():
  2618                 for r in self:
  2624                 for r in self:
  2619                     new_dfh.write(self._getsegmentforrevs(r, r)[1])
  2625                     new_dfh.write(self._inner.get_segment_for_revs(r, r)[1])
  2620                 new_dfh.flush()
  2626                 new_dfh.flush()
  2621 
  2627 
  2622             if side_write:
  2628             if side_write:
  2623                 self._indexfile = new_index_file_path
  2629                 self._indexfile = new_index_file_path
  2624                 self._inner.index_file = self._indexfile
  2630                 self._inner.index_file = self._indexfile