##// END OF EJS Templates
revlog: drop emitrevisiondeltas() and associated functionality (API)...
Gregory Szorc -
r39902:e23c03dc default
parent child Browse files
Show More
@@ -19,10 +19,6 b' from .node import ('
19 short,
19 short,
20 )
20 )
21
21
22 from .thirdparty import (
23 attr,
24 )
25
26 from . import (
22 from . import (
27 error,
23 error,
28 match as matchmod,
24 match as matchmod,
@@ -34,10 +30,6 b' from . import ('
34 util,
30 util,
35 )
31 )
36
32
37 from .utils import (
38 interfaceutil,
39 )
40
41 _CHANGEGROUPV1_DELTA_HEADER = struct.Struct("20s20s20s20s")
33 _CHANGEGROUPV1_DELTA_HEADER = struct.Struct("20s20s20s20s")
42 _CHANGEGROUPV2_DELTA_HEADER = struct.Struct("20s20s20s20s20s")
34 _CHANGEGROUPV2_DELTA_HEADER = struct.Struct("20s20s20s20s20s")
43 _CHANGEGROUPV3_DELTA_HEADER = struct.Struct(">20s20s20s20s20sH")
35 _CHANGEGROUPV3_DELTA_HEADER = struct.Struct(">20s20s20s20s20sH")
@@ -499,16 +491,6 b' class headerlessfixup(object):'
499 return d
491 return d
500 return readexactly(self._fh, n)
492 return readexactly(self._fh, n)
501
493
502 @interfaceutil.implementer(repository.irevisiondeltarequest)
503 @attr.s(slots=True, frozen=True)
504 class revisiondeltarequest(object):
505 node = attr.ib()
506 linknode = attr.ib()
507 p1node = attr.ib()
508 p2node = attr.ib()
509 basenode = attr.ib()
510 ellipsis = attr.ib(default=False)
511
512 def _revisiondeltatochunks(delta, headerfn):
494 def _revisiondeltatochunks(delta, headerfn):
513 """Serialize a revisiondelta to changegroup chunks."""
495 """Serialize a revisiondelta to changegroup chunks."""
514
496
@@ -93,9 +93,6 b' class filelog(object):'
93 def revdiff(self, rev1, rev2):
93 def revdiff(self, rev1, rev2):
94 return self._revlog.revdiff(rev1, rev2)
94 return self._revlog.revdiff(rev1, rev2)
95
95
96 def emitrevisiondeltas(self, requests):
97 return self._revlog.emitrevisiondeltas(requests)
98
99 def emitrevisions(self, nodes, nodesorder=None,
96 def emitrevisions(self, nodes, nodesorder=None,
100 revisiondata=False, assumehaveparentrevisions=False,
97 revisiondata=False, assumehaveparentrevisions=False,
101 deltaprevious=False):
98 deltaprevious=False):
@@ -1562,9 +1562,6 b' class manifestrevlog(object):'
1562 def deltaparent(self, rev):
1562 def deltaparent(self, rev):
1563 return self._revlog.deltaparent(rev)
1563 return self._revlog.deltaparent(rev)
1564
1564
1565 def emitrevisiondeltas(self, requests):
1566 return self._revlog.emitrevisiondeltas(requests)
1567
1568 def emitrevisions(self, nodes, nodesorder=None,
1565 def emitrevisions(self, nodes, nodesorder=None,
1569 revisiondata=False, assumehaveparentrevisions=False,
1566 revisiondata=False, assumehaveparentrevisions=False,
1570 deltaprevious=False):
1567 deltaprevious=False):
@@ -391,37 +391,6 b' class irevisiondelta(interfaceutil.Inter'
391 Stored in the bdiff delta format.
391 Stored in the bdiff delta format.
392 """)
392 """)
393
393
394 class irevisiondeltarequest(interfaceutil.Interface):
395 """Represents a request to generate an ``irevisiondelta``."""
396
397 node = interfaceutil.Attribute(
398 """20 byte node of revision being requested.""")
399
400 p1node = interfaceutil.Attribute(
401 """20 byte node of 1st parent of revision.""")
402
403 p2node = interfaceutil.Attribute(
404 """20 byte node of 2nd parent of revision.""")
405
406 linknode = interfaceutil.Attribute(
407 """20 byte node to store in ``linknode`` attribute.""")
408
409 basenode = interfaceutil.Attribute(
410 """Base revision that delta should be generated against.
411
412 If ``nullid``, the derived ``irevisiondelta`` should have its
413 ``revision`` field populated and no delta should be generated.
414
415 If ``None``, the delta may be generated against any revision that
416 is an ancestor of this revision. Or a full revision may be used.
417
418 If any other value, the delta should be produced against that
419 revision.
420 """)
421
422 ellipsis = interfaceutil.Attribute(
423 """Boolean on whether the ellipsis flag should be set.""")
424
425 class ifilerevisionssequence(interfaceutil.Interface):
394 class ifilerevisionssequence(interfaceutil.Interface):
426 """Contains index data for all revisions of a file.
395 """Contains index data for all revisions of a file.
427
396
@@ -630,30 +599,6 b' class ifiledata(interfaceutil.Interface)'
630 revision data.
599 revision data.
631 """
600 """
632
601
633 def emitrevisiondeltas(requests):
634 """Produce ``irevisiondelta`` from ``irevisiondeltarequest``s.
635
636 Given an iterable of objects conforming to the ``irevisiondeltarequest``
637 interface, emits objects conforming to the ``irevisiondelta``
638 interface.
639
640 This method is a generator.
641
642 ``irevisiondelta`` should be emitted in the same order of
643 ``irevisiondeltarequest`` that was passed in.
644
645 The emitted objects MUST conform by the results of
646 ``irevisiondeltarequest``. Namely, they must respect any requests
647 for building a delta from a specific ``basenode`` if defined.
648
649 When sending deltas, implementations must take into account whether
650 the client has the base delta before encoding a delta against that
651 revision. A revision encountered previously in ``requests`` is
652 always a suitable base revision. An example of a bad delta is a delta
653 against a non-ancestor revision. Another example of a bad delta is a
654 delta against a censored revision.
655 """
656
657 def emitrevisions(nodes,
602 def emitrevisions(nodes,
658 nodesorder=None,
603 nodesorder=None,
659 revisiondata=False,
604 revisiondata=False,
@@ -1174,12 +1119,6 b' class imanifeststorage(interfaceutil.Int'
1174 Returns True if the fulltext is different from what is stored.
1119 Returns True if the fulltext is different from what is stored.
1175 """
1120 """
1176
1121
1177 def emitrevisiondeltas(requests):
1178 """Produce ``irevisiondelta`` from ``irevisiondeltarequest``s.
1179
1180 See the documentation for ``ifiledata`` for more.
1181 """
1182
1183 def emitrevisions(nodes,
1122 def emitrevisions(nodes,
1184 nodesorder=None,
1123 nodesorder=None,
1185 revisiondata=False,
1124 revisiondata=False,
@@ -2294,87 +2294,6 b' class revlog(object):'
2294 res.append(self.datafile)
2294 res.append(self.datafile)
2295 return res
2295 return res
2296
2296
2297 def emitrevisiondeltas(self, requests):
2298 frev = self.rev
2299
2300 prevrev = None
2301 for request in requests:
2302 node = request.node
2303 rev = frev(node)
2304
2305 if prevrev is None:
2306 prevrev = self.index[rev][5]
2307
2308 # Requesting a full revision.
2309 if request.basenode == nullid:
2310 baserev = nullrev
2311 # Requesting an explicit revision.
2312 elif request.basenode is not None:
2313 baserev = frev(request.basenode)
2314 # Allowing us to choose.
2315 else:
2316 p1rev, p2rev = self.parentrevs(rev)
2317 deltaparentrev = self.deltaparent(rev)
2318
2319 # Avoid sending full revisions when delta parent is null. Pick
2320 # prev in that case. It's tempting to pick p1 in this case, as
2321 # p1 will be smaller in the common case. However, computing a
2322 # delta against p1 may require resolving the raw text of p1,
2323 # which could be expensive. The revlog caches should have prev
2324 # cached, meaning less CPU for delta generation. There is
2325 # likely room to add a flag and/or config option to control this
2326 # behavior.
2327 if deltaparentrev == nullrev and self._storedeltachains:
2328 baserev = prevrev
2329
2330 # Revlog is configured to use full snapshot for a reason.
2331 # Stick to full snapshot.
2332 elif deltaparentrev == nullrev:
2333 baserev = nullrev
2334
2335 # Pick previous when we can't be sure the base is available
2336 # on consumer.
2337 elif deltaparentrev not in (p1rev, p2rev, prevrev):
2338 baserev = prevrev
2339 else:
2340 baserev = deltaparentrev
2341
2342 if baserev != nullrev and not self.candelta(baserev, rev):
2343 baserev = nullrev
2344
2345 revision = None
2346 delta = None
2347 baserevisionsize = None
2348
2349 if self.iscensored(baserev) or self.iscensored(rev):
2350 try:
2351 revision = self.revision(node, raw=True)
2352 except error.CensoredNodeError as e:
2353 revision = e.tombstone
2354
2355 if baserev != nullrev:
2356 baserevisionsize = self.rawsize(baserev)
2357
2358 elif baserev == nullrev:
2359 revision = self.revision(node, raw=True)
2360 else:
2361 delta = self.revdiff(baserev, rev)
2362
2363 extraflags = REVIDX_ELLIPSIS if request.ellipsis else 0
2364
2365 yield revlogrevisiondelta(
2366 node=node,
2367 p1node=request.p1node,
2368 p2node=request.p2node,
2369 linknode=request.linknode,
2370 basenode=self.node(baserev),
2371 flags=self.flags(rev) | extraflags,
2372 baserevisionsize=baserevisionsize,
2373 revision=revision,
2374 delta=delta)
2375
2376 prevrev = rev
2377
2378 def emitrevisions(self, nodes, nodesorder=None, revisiondata=False,
2297 def emitrevisions(self, nodes, nodesorder=None, revisiondata=False,
2379 assumehaveparentrevisions=False, deltaprevious=False):
2298 assumehaveparentrevisions=False, deltaprevious=False):
2380 if nodesorder not in ('nodes', 'storage', None):
2299 if nodesorder not in ('nodes', 'storage', None):
@@ -25,15 +25,6 b' class basetestcase(unittest.TestCase):'
25 assertRaisesRegex = (# camelcase-required
25 assertRaisesRegex = (# camelcase-required
26 unittest.TestCase.assertRaisesRegexp)
26 unittest.TestCase.assertRaisesRegexp)
27
27
28 class revisiondeltarequest(object):
29 def __init__(self, node, p1, p2, linknode, basenode, ellipsis):
30 self.node = node
31 self.p1node = p1
32 self.p2node = p2
33 self.linknode = linknode
34 self.basenode = basenode
35 self.ellipsis = ellipsis
36
37 class ifileindextests(basetestcase):
28 class ifileindextests(basetestcase):
38 """Generic tests for the ifileindex interface.
29 """Generic tests for the ifileindex interface.
39
30
@@ -454,52 +445,6 b' class ifiledatatests(basetestcase):'
454 with self.assertRaises(IndexError):
445 with self.assertRaises(IndexError):
455 f.revdiff(0, 0)
446 f.revdiff(0, 0)
456
447
457 gen = f.emitrevisiondeltas([])
458 with self.assertRaises(StopIteration):
459 next(gen)
460
461 requests = [
462 revisiondeltarequest(nullid, nullid, nullid, nullid, nullid, False),
463 ]
464 gen = f.emitrevisiondeltas(requests)
465
466 delta = next(gen)
467
468 self.assertEqual(delta.node, nullid)
469 self.assertEqual(delta.p1node, nullid)
470 self.assertEqual(delta.p2node, nullid)
471 self.assertEqual(delta.linknode, nullid)
472 self.assertEqual(delta.basenode, nullid)
473 self.assertIsNone(delta.baserevisionsize)
474 self.assertEqual(delta.revision, b'')
475 self.assertIsNone(delta.delta)
476
477 with self.assertRaises(StopIteration):
478 next(gen)
479
480 requests = [
481 revisiondeltarequest(nullid, nullid, nullid, nullid, nullid, False),
482 revisiondeltarequest(nullid, b'\x01' * 20, b'\x02' * 20,
483 b'\x03' * 20, nullid, False)
484 ]
485
486 gen = f.emitrevisiondeltas(requests)
487
488 next(gen)
489 delta = next(gen)
490
491 self.assertEqual(delta.node, nullid)
492 self.assertEqual(delta.p1node, b'\x01' * 20)
493 self.assertEqual(delta.p2node, b'\x02' * 20)
494 self.assertEqual(delta.linknode, b'\x03' * 20)
495 self.assertEqual(delta.basenode, nullid)
496 self.assertIsNone(delta.baserevisionsize)
497 self.assertEqual(delta.revision, b'')
498 self.assertIsNone(delta.delta)
499
500 with self.assertRaises(StopIteration):
501 next(gen)
502
503 # Emitting empty list is an empty generator.
448 # Emitting empty list is an empty generator.
504 gen = f.emitrevisions([])
449 gen = f.emitrevisions([])
505 with self.assertRaises(StopIteration):
450 with self.assertRaises(StopIteration):
@@ -561,25 +506,6 b' class ifiledatatests(basetestcase):'
561 self.assertEqual(f.revdiff(0, nullrev),
506 self.assertEqual(f.revdiff(0, nullrev),
562 b'\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00')
507 b'\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00')
563
508
564 requests = [
565 revisiondeltarequest(node, nullid, nullid, nullid, nullid, False),
566 ]
567 gen = f.emitrevisiondeltas(requests)
568
569 delta = next(gen)
570
571 self.assertEqual(delta.node, node)
572 self.assertEqual(delta.p1node, nullid)
573 self.assertEqual(delta.p2node, nullid)
574 self.assertEqual(delta.linknode, nullid)
575 self.assertEqual(delta.basenode, nullid)
576 self.assertIsNone(delta.baserevisionsize)
577 self.assertEqual(delta.revision, fulltext)
578 self.assertIsNone(delta.delta)
579
580 with self.assertRaises(StopIteration):
581 next(gen)
582
583 # Emitting a single revision works.
509 # Emitting a single revision works.
584 gen = f.emitrevisions([node])
510 gen = f.emitrevisions([node])
585 rev = next(gen)
511 rev = next(gen)
@@ -697,56 +623,6 b' class ifiledatatests(basetestcase):'
697 b'\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x02' +
623 b'\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x02' +
698 fulltext2)
624 fulltext2)
699
625
700 requests = [
701 revisiondeltarequest(node0, nullid, nullid, b'\x01' * 20, nullid,
702 False),
703 revisiondeltarequest(node1, node0, nullid, b'\x02' * 20, node0,
704 False),
705 revisiondeltarequest(node2, node1, nullid, b'\x03' * 20, node1,
706 False),
707 ]
708 gen = f.emitrevisiondeltas(requests)
709
710 delta = next(gen)
711
712 self.assertEqual(delta.node, node0)
713 self.assertEqual(delta.p1node, nullid)
714 self.assertEqual(delta.p2node, nullid)
715 self.assertEqual(delta.linknode, b'\x01' * 20)
716 self.assertEqual(delta.basenode, nullid)
717 self.assertIsNone(delta.baserevisionsize)
718 self.assertEqual(delta.revision, fulltext0)
719 self.assertIsNone(delta.delta)
720
721 delta = next(gen)
722
723 self.assertEqual(delta.node, node1)
724 self.assertEqual(delta.p1node, node0)
725 self.assertEqual(delta.p2node, nullid)
726 self.assertEqual(delta.linknode, b'\x02' * 20)
727 self.assertEqual(delta.basenode, node0)
728 self.assertIsNone(delta.baserevisionsize)
729 self.assertIsNone(delta.revision)
730 self.assertEqual(delta.delta,
731 b'\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x01' +
732 fulltext1)
733
734 delta = next(gen)
735
736 self.assertEqual(delta.node, node2)
737 self.assertEqual(delta.p1node, node1)
738 self.assertEqual(delta.p2node, nullid)
739 self.assertEqual(delta.linknode, b'\x03' * 20)
740 self.assertEqual(delta.basenode, node1)
741 self.assertIsNone(delta.baserevisionsize)
742 self.assertIsNone(delta.revision)
743 self.assertEqual(delta.delta,
744 b'\x00\x00\x00\x00\x00\x00\x04\x01\x00\x00\x04\x02' +
745 fulltext2)
746
747 with self.assertRaises(StopIteration):
748 next(gen)
749
750 # Nodes should be emitted in order.
626 # Nodes should be emitted in order.
751 gen = f.emitrevisions([node0, node1, node2], revisiondata=True)
627 gen = f.emitrevisions([node0, node1, node2], revisiondata=True)
752
628
@@ -510,54 +510,6 b' class filestorage(object):'
510 return mdiff.textdiff(self.revision(node1, raw=True),
510 return mdiff.textdiff(self.revision(node1, raw=True),
511 self.revision(node2, raw=True))
511 self.revision(node2, raw=True))
512
512
513 def emitrevisiondeltas(self, requests):
514 for request in requests:
515 node = request.node
516 rev = self.rev(node)
517
518 if request.basenode == nullid:
519 baserev = nullrev
520 elif request.basenode is not None:
521 baserev = self.rev(request.basenode)
522 else:
523 # This is a test extension and we can do simple things
524 # for choosing a delta parent.
525 baserev = self.deltaparent(rev)
526
527 if baserev != nullrev and not self._candelta(baserev, rev):
528 baserev = nullrev
529
530 revision = None
531 delta = None
532 baserevisionsize = None
533
534 if self.iscensored(baserev) or self.iscensored(rev):
535 try:
536 revision = self.revision(node, raw=True)
537 except error.CensoredNodeError as e:
538 revision = e.tombstone
539
540 if baserev != nullrev:
541 baserevisionsize = self.rawsize(baserev)
542
543 elif baserev == nullrev:
544 revision = self.revision(node, raw=True)
545 else:
546 delta = self.revdiff(baserev, rev)
547
548 extraflags = revlog.REVIDX_ELLIPSIS if request.ellipsis else 0
549
550 yield simplestorerevisiondelta(
551 node=node,
552 p1node=request.p1node,
553 p2node=request.p2node,
554 linknode=request.linknode,
555 basenode=self.node(baserev),
556 flags=self.flags(rev) | extraflags,
557 baserevisionsize=baserevisionsize,
558 revision=revision,
559 delta=delta)
560
561 def heads(self, start=None, stop=None):
513 def heads(self, start=None, stop=None):
562 # This is copied from revlog.py.
514 # This is copied from revlog.py.
563 if start is None and stop is None:
515 if start is None and stop is None:
@@ -21,7 +21,6 b' from mercurial.thirdparty.zope.interface'
21 verify as ziverify,
21 verify as ziverify,
22 )
22 )
23 from mercurial import (
23 from mercurial import (
24 changegroup,
25 bundlerepo,
24 bundlerepo,
26 filelog,
25 filelog,
27 httppeer,
26 httppeer,
@@ -206,8 +205,6 b' def main():'
206
205
207 ziverify.verifyClass(repository.irevisiondelta,
206 ziverify.verifyClass(repository.irevisiondelta,
208 revlog.revlogrevisiondelta)
207 revlog.revlogrevisiondelta)
209 ziverify.verifyClass(repository.irevisiondeltarequest,
210 changegroup.revisiondeltarequest)
211
208
212 rd = revlog.revlogrevisiondelta(
209 rd = revlog.revlogrevisiondelta(
213 node=b'',
210 node=b'',
@@ -221,14 +218,6 b' def main():'
221 delta=None)
218 delta=None)
222 checkzobject(rd)
219 checkzobject(rd)
223
220
224 rdr = changegroup.revisiondeltarequest(
225 node=b'',
226 linknode=b'',
227 p1node=b'',
228 p2node=b'',
229 basenode=b'')
230 checkzobject(rdr)
231
232 ziverify.verifyClass(repository.iverifyproblem,
221 ziverify.verifyClass(repository.iverifyproblem,
233 revlog.revlogproblem)
222 revlog.revlogproblem)
234 checkzobject(revlog.revlogproblem())
223 checkzobject(revlog.revlogproblem())
General Comments 0
You need to be logged in to leave comments. Login now