comparison mercurial/obsolete.py @ 33504:5d3ba4395288

obsstore: let read marker API take a range of offsets This allows us to read a customized range of markers, instead of loading all of them. The condition of stop is made consistent across C and Python implementation so we will still read marker when offset=a, stop=a+1.
author Jun Wu <quark@fb.com>
date Sun, 04 Jun 2017 10:02:09 -0700
parents 0407a51b9d8c
children e5f8c7baa729
comparison
equal deleted inserted replaced
33503:27d23fe32887 33504:5d3ba4395288
176 _fm0fixed = '>BIB20s' 176 _fm0fixed = '>BIB20s'
177 _fm0node = '20s' 177 _fm0node = '20s'
178 _fm0fsize = _calcsize(_fm0fixed) 178 _fm0fsize = _calcsize(_fm0fixed)
179 _fm0fnodesize = _calcsize(_fm0node) 179 _fm0fnodesize = _calcsize(_fm0node)
180 180
181 def _fm0readmarkers(data, off): 181 def _fm0readmarkers(data, off, stop):
182 # Loop on markers 182 # Loop on markers
183 l = len(data) 183 while off < stop:
184 while off + _fm0fsize <= l:
185 # read fixed part 184 # read fixed part
186 cur = data[off:off + _fm0fsize] 185 cur = data[off:off + _fm0fsize]
187 off += _fm0fsize 186 off += _fm0fsize
188 numsuc, mdsize, flags, pre = _unpack(_fm0fixed, cur) 187 numsuc, mdsize, flags, pre = _unpack(_fm0fixed, cur)
189 # read replacement 188 # read replacement
315 _fm1parentshift = 14 314 _fm1parentshift = 14
316 _fm1parentmask = (_fm1parentnone << _fm1parentshift) 315 _fm1parentmask = (_fm1parentnone << _fm1parentshift)
317 _fm1metapair = 'BB' 316 _fm1metapair = 'BB'
318 _fm1metapairsize = _calcsize('BB') 317 _fm1metapairsize = _calcsize('BB')
319 318
320 def _fm1purereadmarkers(data, off): 319 def _fm1purereadmarkers(data, off, stop):
321 # make some global constants local for performance 320 # make some global constants local for performance
322 noneflag = _fm1parentnone 321 noneflag = _fm1parentnone
323 sha2flag = usingsha256 322 sha2flag = usingsha256
324 sha1size = _fm1nodesha1size 323 sha1size = _fm1nodesha1size
325 sha2size = _fm1nodesha256size 324 sha2size = _fm1nodesha256size
329 metafmt = _fm1metapair 328 metafmt = _fm1metapair
330 fsize = _fm1fsize 329 fsize = _fm1fsize
331 unpack = _unpack 330 unpack = _unpack
332 331
333 # Loop on markers 332 # Loop on markers
334 stop = len(data) - _fm1fsize
335 ufixed = struct.Struct(_fm1fixed).unpack 333 ufixed = struct.Struct(_fm1fixed).unpack
336 334
337 while off <= stop: 335 while off < stop:
338 # read fixed part 336 # read fixed part
339 o1 = off + fsize 337 o1 = off + fsize
340 t, secs, tz, flags, numsuc, numpar, nummeta, prec = ufixed(data[off:o1]) 338 t, secs, tz, flags, numsuc, numpar, nummeta, prec = ufixed(data[off:o1])
341 339
342 if flags & sha2flag: 340 if flags & sha2flag:
426 for key, value in metadata: 424 for key, value in metadata:
427 data.append(key) 425 data.append(key)
428 data.append(value) 426 data.append(value)
429 return ''.join(data) 427 return ''.join(data)
430 428
431 def _fm1readmarkers(data, off): 429 def _fm1readmarkers(data, off, stop):
432 native = getattr(parsers, 'fm1readmarkers', None) 430 native = getattr(parsers, 'fm1readmarkers', None)
433 if not native: 431 if not native:
434 return _fm1purereadmarkers(data, off) 432 return _fm1purereadmarkers(data, off, stop)
435 stop = len(data) - _fm1fsize
436 return native(data, off, stop) 433 return native(data, off, stop)
437 434
438 # mapping to read/write various marker formats 435 # mapping to read/write various marker formats
439 # <version> -> (decoder, encoder) 436 # <version> -> (decoder, encoder)
440 formats = {_fm0version: (_fm0readmarkers, _fm0encodeonemarker), 437 formats = {_fm0version: (_fm0readmarkers, _fm0encodeonemarker),
442 439
443 def _readmarkerversion(data): 440 def _readmarkerversion(data):
444 return _unpack('>B', data[0:1])[0] 441 return _unpack('>B', data[0:1])[0]
445 442
446 @util.nogc 443 @util.nogc
447 def _readmarkers(data): 444 def _readmarkers(data, off=None, stop=None):
448 """Read and enumerate markers from raw data""" 445 """Read and enumerate markers from raw data"""
449 diskversion = _readmarkerversion(data) 446 diskversion = _readmarkerversion(data)
450 off = 1 447 if not off:
448 off = 1 # skip 1 byte version number
449 if stop is None:
450 stop = len(data)
451 if diskversion not in formats: 451 if diskversion not in formats:
452 msg = _('parsing obsolete marker: unknown version %r') % diskversion 452 msg = _('parsing obsolete marker: unknown version %r') % diskversion
453 raise error.UnknownVersion(msg, version=diskversion) 453 raise error.UnknownVersion(msg, version=diskversion)
454 return diskversion, formats[diskversion][0](data, off) 454 return diskversion, formats[diskversion][0](data, off, stop)
455 455
456 def encodeheader(version=_fm0version): 456 def encodeheader(version=_fm0version):
457 return _pack('>B', version) 457 return _pack('>B', version)
458 458
459 def encodemarkers(markers, addheader=False, version=_fm0version): 459 def encodemarkers(markers, addheader=False, version=_fm0version):