Mercurial > hg
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): |