785 else: |
785 else: |
786 msg = b'unknown compression mode %d' |
786 msg = b'unknown compression mode %d' |
787 msg %= compression_mode |
787 msg %= compression_mode |
788 raise error.RevlogError(msg) |
788 raise error.RevlogError(msg) |
789 |
789 |
|
790 def _chunks(self, revs, targetsize=None): |
|
791 """Obtain decompressed chunks for the specified revisions. |
|
792 |
|
793 Accepts an iterable of numeric revisions that are assumed to be in |
|
794 ascending order. Also accepts an optional already-open file handle |
|
795 to be used for reading. If used, the seek position of the file will |
|
796 not be preserved. |
|
797 |
|
798 This function is similar to calling ``self._chunk()`` multiple times, |
|
799 but is faster. |
|
800 |
|
801 Returns a list with decompressed data for each requested revision. |
|
802 """ |
|
803 if not revs: |
|
804 return [] |
|
805 start = self.start |
|
806 length = self.length |
|
807 inline = self.inline |
|
808 iosize = self.index.entry_size |
|
809 buffer = util.buffer |
|
810 |
|
811 l = [] |
|
812 ladd = l.append |
|
813 |
|
814 if not self.data_config.with_sparse_read: |
|
815 slicedchunks = (revs,) |
|
816 else: |
|
817 slicedchunks = deltautil.slicechunk( |
|
818 self, |
|
819 revs, |
|
820 targetsize=targetsize, |
|
821 ) |
|
822 |
|
823 for revschunk in slicedchunks: |
|
824 firstrev = revschunk[0] |
|
825 # Skip trailing revisions with empty diff |
|
826 for lastrev in revschunk[::-1]: |
|
827 if length(lastrev) != 0: |
|
828 break |
|
829 |
|
830 try: |
|
831 offset, data = self.get_segment_for_revs(firstrev, lastrev) |
|
832 except OverflowError: |
|
833 # issue4215 - we can't cache a run of chunks greater than |
|
834 # 2G on Windows |
|
835 return [self._chunk(rev) for rev in revschunk] |
|
836 |
|
837 decomp = self.decompress |
|
838 # self._decompressor might be None, but will not be used in that case |
|
839 def_decomp = self._decompressor |
|
840 for rev in revschunk: |
|
841 chunkstart = start(rev) |
|
842 if inline: |
|
843 chunkstart += (rev + 1) * iosize |
|
844 chunklength = length(rev) |
|
845 comp_mode = self.index[rev][10] |
|
846 c = buffer(data, chunkstart - offset, chunklength) |
|
847 if comp_mode == COMP_MODE_PLAIN: |
|
848 ladd(c) |
|
849 elif comp_mode == COMP_MODE_INLINE: |
|
850 ladd(decomp(c)) |
|
851 elif comp_mode == COMP_MODE_DEFAULT: |
|
852 ladd(def_decomp(c)) |
|
853 else: |
|
854 msg = b'unknown compression mode %d' |
|
855 msg %= comp_mode |
|
856 raise error.RevlogError(msg) |
|
857 |
|
858 return l |
|
859 |
790 |
860 |
791 class revlog: |
861 class revlog: |
792 """ |
862 """ |
793 the underlying revision storage object |
863 the underlying revision storage object |
794 |
864 |
2404 returns True if text is different than what is stored. |
2474 returns True if text is different than what is stored. |
2405 """ |
2475 """ |
2406 p1, p2 = self.parents(node) |
2476 p1, p2 = self.parents(node) |
2407 return storageutil.hashrevisionsha1(text, p1, p2) != node |
2477 return storageutil.hashrevisionsha1(text, p1, p2) != node |
2408 |
2478 |
2409 def _chunks(self, revs, targetsize=None): |
|
2410 """Obtain decompressed chunks for the specified revisions. |
|
2411 |
|
2412 Accepts an iterable of numeric revisions that are assumed to be in |
|
2413 ascending order. Also accepts an optional already-open file handle |
|
2414 to be used for reading. If used, the seek position of the file will |
|
2415 not be preserved. |
|
2416 |
|
2417 This function is similar to calling ``self._chunk()`` multiple times, |
|
2418 but is faster. |
|
2419 |
|
2420 Returns a list with decompressed data for each requested revision. |
|
2421 """ |
|
2422 if not revs: |
|
2423 return [] |
|
2424 start = self.start |
|
2425 length = self.length |
|
2426 inline = self._inline |
|
2427 iosize = self.index.entry_size |
|
2428 buffer = util.buffer |
|
2429 |
|
2430 l = [] |
|
2431 ladd = l.append |
|
2432 |
|
2433 if not self.data_config.with_sparse_read: |
|
2434 slicedchunks = (revs,) |
|
2435 else: |
|
2436 slicedchunks = deltautil.slicechunk( |
|
2437 self, revs, targetsize=targetsize |
|
2438 ) |
|
2439 |
|
2440 for revschunk in slicedchunks: |
|
2441 firstrev = revschunk[0] |
|
2442 # Skip trailing revisions with empty diff |
|
2443 for lastrev in revschunk[::-1]: |
|
2444 if length(lastrev) != 0: |
|
2445 break |
|
2446 |
|
2447 try: |
|
2448 offset, data = self._inner.get_segment_for_revs( |
|
2449 firstrev, |
|
2450 lastrev, |
|
2451 ) |
|
2452 except OverflowError: |
|
2453 # issue4215 - we can't cache a run of chunks greater than |
|
2454 # 2G on Windows |
|
2455 return [self._inner._chunk(rev) for rev in revschunk] |
|
2456 |
|
2457 decomp = self._inner.decompress |
|
2458 # self._decompressor might be None, but will not be used in that case |
|
2459 def_decomp = self._inner._decompressor |
|
2460 for rev in revschunk: |
|
2461 chunkstart = start(rev) |
|
2462 if inline: |
|
2463 chunkstart += (rev + 1) * iosize |
|
2464 chunklength = length(rev) |
|
2465 comp_mode = self.index[rev][10] |
|
2466 c = buffer(data, chunkstart - offset, chunklength) |
|
2467 if comp_mode == COMP_MODE_PLAIN: |
|
2468 ladd(c) |
|
2469 elif comp_mode == COMP_MODE_INLINE: |
|
2470 ladd(decomp(c)) |
|
2471 elif comp_mode == COMP_MODE_DEFAULT: |
|
2472 ladd(def_decomp(c)) |
|
2473 else: |
|
2474 msg = b'unknown compression mode %d' |
|
2475 msg %= comp_mode |
|
2476 raise error.RevlogError(msg) |
|
2477 |
|
2478 return l |
|
2479 |
|
2480 def deltaparent(self, rev): |
2479 def deltaparent(self, rev): |
2481 """return deltaparent of the given revision""" |
2480 """return deltaparent of the given revision""" |
2482 base = self.index[rev][3] |
2481 base = self.index[rev][3] |
2483 if base == rev: |
2482 if base == rev: |
2484 return nullrev |
2483 return nullrev |
2606 targetsize = None |
2605 targetsize = None |
2607 rawsize = self.index[rev][2] |
2606 rawsize = self.index[rev][2] |
2608 if 0 <= rawsize: |
2607 if 0 <= rawsize: |
2609 targetsize = 4 * rawsize |
2608 targetsize = 4 * rawsize |
2610 |
2609 |
2611 bins = self._chunks(chain, targetsize=targetsize) |
2610 bins = self._inner._chunks(chain, targetsize=targetsize) |
2612 if basetext is None: |
2611 if basetext is None: |
2613 basetext = bytes(bins[0]) |
2612 basetext = bytes(bins[0]) |
2614 bins = bins[1:] |
2613 bins = bins[1:] |
2615 |
2614 |
2616 rawtext = mdiff.patches(basetext, bins) |
2615 rawtext = mdiff.patches(basetext, bins) |