comparison tests/test-rust-ancestor.py @ 41188:006c9ce486fa

rust-cpython: bindings for MissingAncestors The exposition is rather straightforward, except for the remove_ancestors_from() method, which forces us to an inefficient conversion between Python sets and Rust HashSets. Two alternatives are proposed in comments: - changing the inner API to "emit" the revision numbers to discard this would be a substantial change, and it would be better only in the cases where there are more to retain than to discard - mutating the Python set directly: this would force us to define an abstract `RevisionSet` trait, and implement it both for plain `HashSet` and for a struct enclosing a Python set with the GIL marker `Python<'p>`, also a non trivial effort. The main (and seemingly only) caller of this method being `mercurial.setdiscovery`, which is currently undergoing serious refactoring, it's not clear whether these improvements would be worth the effort right now, so we're leaving it as-is. Also, in `get_bases()` (will also be used by `setdiscovery`), we'd prefer to build a Python set directly, but we resort to returning a tuple, waiting to hear back from our PR onto rust-cpython about that Differential Revision: https://phab.mercurial-scm.org/D5550
author Georges Racinet <georges.racinet@octobus.net>
date Fri, 30 Nov 2018 20:05:34 +0100
parents b31a41f24864
children 5257e6299d4c
comparison
equal deleted inserted replaced
41187:3bf6979a1785 41188:006c9ce486fa
9 rustext = None 9 rustext = None
10 else: 10 else:
11 # this would fail already without appropriate ancestor.__package__ 11 # this would fail already without appropriate ancestor.__package__
12 from mercurial.rustext.ancestor import ( 12 from mercurial.rustext.ancestor import (
13 AncestorsIterator, 13 AncestorsIterator,
14 LazyAncestors 14 LazyAncestors,
15 MissingAncestors,
15 ) 16 )
16 17
17 try: 18 try:
18 from mercurial.cext import parsers as cparsers 19 from mercurial.cext import parsers as cparsers
19 except ImportError: 20 except ImportError:
103 self.assertEqual(sys.getrefcount(idx), start_count) 104 self.assertEqual(sys.getrefcount(idx), start_count)
104 105
105 # let's check bool for an empty one 106 # let's check bool for an empty one
106 self.assertFalse(LazyAncestors(idx, [0], 0, False)) 107 self.assertFalse(LazyAncestors(idx, [0], 0, False))
107 108
109 def testmissingancestors(self):
110 idx = self.parseindex()
111 missanc = MissingAncestors(idx, [1])
112 self.assertTrue(missanc.hasbases())
113 self.assertEqual(missanc.missingancestors([3]), [2, 3])
114 missanc.addbases({2})
115 self.assertEqual(set(missanc.bases()), {1, 2})
116 self.assertEqual(missanc.missingancestors([3]), [3])
117
118 def testmissingancestorsremove(self):
119 idx = self.parseindex()
120 missanc = MissingAncestors(idx, [1])
121 revs = {0, 1, 2, 3}
122 missanc.removeancestorsfrom(revs)
123 self.assertEqual(revs, {2, 3})
124
108 def testrefcount(self): 125 def testrefcount(self):
109 idx = self.parseindex() 126 idx = self.parseindex()
110 start_count = sys.getrefcount(idx) 127 start_count = sys.getrefcount(idx)
111 128
112 # refcount increases upon iterator init... 129 # refcount increases upon iterator init...