comparison mercurial/revlog.py @ 16423:a150923b49ba

revlog: avoid an expensive string copy This showed up in a statprof profile of "hg svn rebuildmeta", which is read-intensive on the changelog. This two-line patch improved the performance of that command by 10%.
author Bryan O'Sullivan <bryano@fb.com>
date Thu, 12 Apr 2012 20:26:33 -0700
parents e5750c6716eb
children ff63d71ac8ab
comparison
equal deleted inserted replaced
16422:c0b5bab3fb11 16423:a150923b49ba
816 df.seek(offset) 816 df.seek(offset)
817 d = df.read(readahead) 817 d = df.read(readahead)
818 df.close() 818 df.close()
819 self._addchunk(offset, d) 819 self._addchunk(offset, d)
820 if readahead > length: 820 if readahead > length:
821 return d[:length] 821 return util.buffer(d, 0, length)
822 return d 822 return d
823 823
824 def _getchunk(self, offset, length): 824 def _getchunk(self, offset, length):
825 o, d = self._chunkcache 825 o, d = self._chunkcache
826 l = len(d) 826 l = len(d)
829 cachestart = offset - o 829 cachestart = offset - o
830 cacheend = cachestart + length 830 cacheend = cachestart + length
831 if cachestart >= 0 and cacheend <= l: 831 if cachestart >= 0 and cacheend <= l:
832 if cachestart == 0 and cacheend == l: 832 if cachestart == 0 and cacheend == l:
833 return d # avoid a copy 833 return d # avoid a copy
834 return d[cachestart:cacheend] 834 return util.buffer(d, cachestart, cacheend - cachestart)
835 835
836 return self._loadchunk(offset, length) 836 return self._loadchunk(offset, length)
837 837
838 def _chunkraw(self, startrev, endrev): 838 def _chunkraw(self, startrev, endrev):
839 start = self.start(startrev) 839 start = self.start(startrev)
862 return rev - 1 862 return rev - 1
863 863
864 def revdiff(self, rev1, rev2): 864 def revdiff(self, rev1, rev2):
865 """return or calculate a delta between two revisions""" 865 """return or calculate a delta between two revisions"""
866 if rev1 != nullrev and self.deltaparent(rev2) == rev1: 866 if rev1 != nullrev and self.deltaparent(rev2) == rev1:
867 return self._chunk(rev2) 867 return str(self._chunk(rev2))
868 868
869 return mdiff.textdiff(self.revision(self.node(rev1)), 869 return mdiff.textdiff(self.revision(self.node(rev1)),
870 self.revision(self.node(rev2))) 870 self.revision(self.node(rev2)))
871 871
872 def revision(self, nodeorrev): 872 def revision(self, nodeorrev):
919 # drop cache to save memory 919 # drop cache to save memory
920 self._cache = None 920 self._cache = None
921 921
922 self._chunkraw(base, rev) 922 self._chunkraw(base, rev)
923 if text is None: 923 if text is None:
924 text = self._chunkbase(base) 924 text = str(self._chunkbase(base))
925 925
926 bins = [self._chunk(r) for r in chain] 926 bins = [self._chunk(r) for r in chain]
927 text = mdiff.patches(text, bins) 927 text = mdiff.patches(text, bins)
928 928
929 text = self._checkhash(text, node, rev) 929 text = self._checkhash(text, node, rev)