comparison mercurial/revlog.py @ 20180:969148b49fc6

revlog: allow tuning of the chunk cache size (via format.chunkcachesize) Running perfmoonwalk on the Mercurial repo (with almost 20,000 changesets) on Mac OS X with an SSD, before this change: $ hg --config format.chunkcachesize=1024 perfmoonwalk ! wall 2.022021 comb 2.030000 user 1.970000 sys 0.060000 (best of 5) (16,154 cache hits, 3,840 misses.) $ hg --config format.chunkcachesize=4096 perfmoonwalk ! wall 1.901006 comb 1.900000 user 1.880000 sys 0.020000 (best of 6) (19,003 hits, 991 misses.) $ hg --config format.chunkcachesize=16384 perfmoonwalk ! wall 1.802775 comb 1.800000 user 1.800000 sys 0.000000 (best of 6) (19,746 hits, 248 misses.) $ hg --config format.chunkcachesize=32768 perfmoonwalk ! wall 1.818545 comb 1.810000 user 1.810000 sys 0.000000 (best of 6) (19,870 hits, 124 misses.) $ hg --config format.chunkcachesize=65536 perfmoonwalk ! wall 1.801350 comb 1.810000 user 1.800000 sys 0.010000 (best of 6) (19,932 hits, 62 misses.) $ hg --config format.chunkcachesize=131072 perfmoonwalk ! wall 1.805879 comb 1.820000 user 1.810000 sys 0.010000 (best of 6) (19,963 hits, 31 misses.) We may want to change the default size in the future based on testing and user feedback.
author Brodie Rao <brodie@sf.io>
date Sun, 17 Nov 2013 18:04:29 -0500
parents 5bb3826bdac4
children 33394f2e331e
comparison
equal deleted inserted replaced
20179:5bb3826bdac4 20180:969148b49fc6
200 self.datafile = indexfile[:-2] + ".d" 200 self.datafile = indexfile[:-2] + ".d"
201 self.opener = opener 201 self.opener = opener
202 self._cache = None 202 self._cache = None
203 self._basecache = None 203 self._basecache = None
204 self._chunkcache = (0, '') 204 self._chunkcache = (0, '')
205 self._chunkcachesize = 65536
205 self.index = [] 206 self.index = []
206 self._pcache = {} 207 self._pcache = {}
207 self._nodecache = {nullid: nullrev} 208 self._nodecache = {nullid: nullrev}
208 self._nodepos = None 209 self._nodepos = None
209 210
213 if 'revlogv1' in opts: 214 if 'revlogv1' in opts:
214 if 'generaldelta' in opts: 215 if 'generaldelta' in opts:
215 v |= REVLOGGENERALDELTA 216 v |= REVLOGGENERALDELTA
216 else: 217 else:
217 v = 0 218 v = 0
219 if 'chunkcachesize' in opts:
220 self._chunkcachesize = opts['chunkcachesize']
221
222 if self._chunkcachesize <= 0:
223 raise RevlogError(_('revlog chunk cache size %r is not greater '
224 'than 0') % self._chunkcachesize)
225 elif self._chunkcachesize & (self._chunkcachesize - 1):
226 raise RevlogError(_('revlog chunk cache size %r is not a power '
227 'of 2') % self._chunkcachesize)
218 228
219 i = '' 229 i = ''
220 self._initempty = True 230 self._initempty = True
221 try: 231 try:
222 f = self.opener(self.indexfile) 232 f = self.opener(self.indexfile)
843 df = self.opener(self.datafile) 853 df = self.opener(self.datafile)
844 854
845 # Cache data both forward and backward around the requested 855 # Cache data both forward and backward around the requested
846 # data, in a fixed size window. This helps speed up operations 856 # data, in a fixed size window. This helps speed up operations
847 # involving reading the revlog backwards. 857 # involving reading the revlog backwards.
848 realoffset = offset & ~65535 858 cachesize = self._chunkcachesize
849 reallength = ((offset + length + 65536) & ~65535) - realoffset 859 realoffset = offset & ~(cachesize - 1)
860 reallength = (((offset + length + cachesize) & ~(cachesize - 1))
861 - realoffset)
850 df.seek(realoffset) 862 df.seek(realoffset)
851 d = df.read(reallength) 863 d = df.read(reallength)
852 df.close() 864 df.close()
853 self._addchunk(realoffset, d) 865 self._addchunk(realoffset, d)
854 if offset != realoffset or reallength != length: 866 if offset != realoffset or reallength != length: