~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test__simple_set.py

Merge the 2.1-static-tuple-no-use branch, but restore the
functionality to btree that involves using StaticTuple instead of tuple().
At this point, I'm leaving out the changes to string interning, as that
can easily be considered a separate patch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
    tests,
25
25
    )
26
26
 
27
 
from bzrlib.tests import (
28
 
    test__static_tuple,
29
 
    )
30
 
try:
31
 
    from bzrlib import _simple_set_pyx as _module
32
 
except ImportError:
33
 
    _module = None
34
 
try:
35
 
    from bzrlib._static_tuple_c import StaticTuple
36
 
except ImportError:
37
 
    from bzrlib._static_tuple_py import StaticTuple
 
27
try:
 
28
    from bzrlib import _simple_set_pyx
 
29
except ImportError:
 
30
    _simple_set_pyx = None
38
31
 
39
32
 
40
33
# Even though this is an extension, we don't permute the tests for a python
41
34
# version. As the plain python version is just a dict or set
42
35
 
43
 
class _CompiledStaticTupleInterned(tests.Feature):
 
36
class _CompiledSimpleSet(tests.Feature):
44
37
 
45
38
    def _probe(self):
46
 
        if _module is None:
 
39
        if _simple_set_pyx is None:
47
40
            return False
48
41
        return True
49
42
 
50
43
    def feature_name(self):
51
44
        return 'bzrlib._simple_set_pyx'
52
45
 
53
 
CompiledStaticTupleInterned = _CompiledStaticTupleInterned()
54
 
 
55
 
 
56
 
class TestStaticTupleInterned(tests.TestCase):
57
 
 
58
 
    _test_needs_features = [CompiledStaticTupleInterned, 
59
 
                            test__static_tuple.CompiledStaticTuple]
 
46
CompiledSimpleSet = _CompiledSimpleSet()
 
47
 
 
48
 
 
49
class TestSimpleSet(tests.TestCase):
 
50
 
 
51
    _test_needs_features = [CompiledSimpleSet]
 
52
    module = _simple_set_pyx
60
53
 
61
54
    def assertIn(self, obj, container):
62
55
        self.assertTrue(obj in container,
76
69
        assertRefcount actually creates a new pointer, as does calling
77
70
        sys.getrefcount. So pass the expected value *before* the call.
78
71
        """
79
 
        # I don't understand why it is count+3 here, but it seems to be
80
 
        # correct. If I check in the calling function, with:
81
 
        # self.assertEqual(count+1, sys.getrefcount(obj))
82
 
        # Then it works fine. Something about passing it to assertRefcount is
83
 
        # actually double-incrementing (and decrementing) the refcount
84
 
        self.assertEqual(count+3, sys.getrefcount(obj))
 
72
        # I'm not sure why the offset is 3, but I've check that in the caller,
 
73
        # an offset of 1 works, which is expected. Not sure why assertRefcount
 
74
        # is incrementing/decrementing 2 times
 
75
        self.assertEqual(count, sys.getrefcount(obj)-3)
85
76
 
86
77
    def test_initial(self):
87
 
        obj = _module.SimpleSet()
 
78
        obj = self.module.SimpleSet()
88
79
        self.assertEqual(0, len(obj))
89
 
        st = StaticTuple('foo', 'bar')
 
80
        st = ('foo', 'bar')
90
81
        self.assertFillState(0, 0, 0x3ff, obj)
91
82
 
92
83
    def test__lookup(self):
98
89
        #  ('a', 'a'), ('f', '4'), ('p', 'r'), ('q', '1'), ('F', 'T'),
99
90
        #  ('Q', 'Q'), ('V', 'd'), ('7', 'C')
100
91
        # all collide @ 643
101
 
        obj = _module.SimpleSet()
102
 
        offset, val = obj._test_lookup(StaticTuple('a', 'a'))
103
 
        self.assertEqual(643, offset)
104
 
        self.assertEqual('<null>', val)
105
 
        offset, val = obj._test_lookup(StaticTuple('f', '4'))
106
 
        self.assertEqual(643, offset)
107
 
        self.assertEqual('<null>', val)
108
 
        offset, val = obj._test_lookup(StaticTuple('p', 'r'))
 
92
        obj = self.module.SimpleSet()
 
93
        offset, val = obj._test_lookup(('a', 'a'))
 
94
        self.assertEqual(643, offset)
 
95
        self.assertEqual('<null>', val)
 
96
        offset, val = obj._test_lookup(('f', '4'))
 
97
        self.assertEqual(643, offset)
 
98
        self.assertEqual('<null>', val)
 
99
        offset, val = obj._test_lookup(('p', 'r'))
109
100
        self.assertEqual(643, offset)
110
101
        self.assertEqual('<null>', val)
111
102
 
112
103
    def test_get_set_del_with_collisions(self):
113
 
        obj = _module.SimpleSet()
114
 
        k1 = StaticTuple('a', 'a')
115
 
        k2 = StaticTuple('f', '4') # collides
116
 
        k3 = StaticTuple('p', 'r')
117
 
        k4 = StaticTuple('q', '1')
 
104
        obj = self.module.SimpleSet()
 
105
        k1 = ('a', 'a')
 
106
        k2 = ('f', '4') # collides
 
107
        k3 = ('p', 'r')
 
108
        k4 = ('q', '1')
118
109
        self.assertEqual((643, '<null>'), obj._test_lookup(k1))
119
110
        self.assertEqual((643, '<null>'), obj._test_lookup(k2))
120
111
        self.assertEqual((643, '<null>'), obj._test_lookup(k3))
160
151
        self.assertNotIn(k4, obj)
161
152
 
162
153
    def test_add(self):
163
 
        obj = _module.SimpleSet()
 
154
        obj = self.module.SimpleSet()
164
155
        self.assertFillState(0, 0, 0x3ff, obj)
165
 
        k1 = StaticTuple('foo')
 
156
        # We use this clumsy notation, because otherwise the refcounts are off.
 
157
        # I'm guessing the python compiler sees it is a static tuple, and adds
 
158
        # it to the function variables, or somesuch
 
159
        k1 = tuple(['foo'])
166
160
        self.assertRefcount(1, k1)
167
161
        self.assertIs(k1, obj.add(k1))
168
162
        self.assertFillState(1, 1, 0x3ff, obj)
172
166
        self.assertIs(k1, ktest)
173
167
        del ktest
174
168
        self.assertRefcount(2, k1)
175
 
        k2 = StaticTuple('foo')
 
169
        k2 = tuple(['foo'])
176
170
        self.assertRefcount(1, k2)
177
171
        self.assertIsNot(k1, k2)
178
172
        # doesn't add anything, so the counters shouldn't be adjusted
188
182
        del obj[k1]
189
183
        self.assertFillState(0, 1, 0x3ff, obj)
190
184
        self.assertRefcount(1, k1)
191
 
        k3 = StaticTuple('bar')
 
185
        k3 = tuple(['bar'])
192
186
        self.assertRefcount(1, k3)
193
187
        self.assertIs(k3, obj.add(k3))
194
188
        self.assertFillState(1, 2, 0x3ff, obj)
200
194
        self.assertRefcount(2, k3)
201
195
 
202
196
    def test_discard(self):
203
 
        obj = _module.SimpleSet()
204
 
        k1 = StaticTuple('foo')
205
 
        k2 = StaticTuple('foo')
206
 
        k3 = StaticTuple('bar')
 
197
        obj = self.module.SimpleSet()
 
198
        k1 = tuple(['foo'])
 
199
        k2 = tuple(['foo'])
 
200
        k3 = tuple(['bar'])
207
201
        self.assertRefcount(1, k1)
208
202
        self.assertRefcount(1, k2)
209
203
        self.assertRefcount(1, k3)
217
211
        self.assertRefcount(1, k3)
218
212
 
219
213
    def test__delitem__(self):
220
 
        obj = _module.SimpleSet()
221
 
        k1 = StaticTuple('foo')
222
 
        k2 = StaticTuple('foo')
223
 
        k3 = StaticTuple('bar')
 
214
        obj = self.module.SimpleSet()
 
215
        k1 = tuple(['foo'])
 
216
        k2 = tuple(['foo'])
 
217
        k3 = tuple(['bar'])
224
218
        self.assertRefcount(1, k1)
225
219
        self.assertRefcount(1, k2)
226
220
        self.assertRefcount(1, k3)
234
228
        self.assertRefcount(1, k3)
235
229
 
236
230
    def test__resize(self):
237
 
        obj = _module.SimpleSet()
238
 
        k1 = StaticTuple('foo')
239
 
        k2 = StaticTuple('bar')
240
 
        k3 = StaticTuple('baz')
 
231
        obj = self.module.SimpleSet()
 
232
        k1 = ('foo',)
 
233
        k2 = ('bar',)
 
234
        k3 = ('baz',)
241
235
        obj.add(k1)
242
236
        obj.add(k2)
243
237
        obj.add(k3)
264
258
        self.assertEqual((591, '<null>'), obj._test_lookup(k2))
265
259
 
266
260
    def test_add_and_remove_lots_of_items(self):
267
 
        obj = _module.SimpleSet()
 
261
        obj = self.module.SimpleSet()
268
262
        chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890'
269
263
        for i in chars:
270
264
            for j in chars:
271
 
                k = StaticTuple(i, j)
 
265
                k = (i, j)
272
266
                obj.add(k)
273
267
        num = len(chars)*len(chars)
274
268
        self.assertFillState(num, num, 0x1fff, obj)
275
269
        # Now delete all of the entries and it should shrink again
276
270
        for i in chars:
277
271
            for j in chars:
278
 
                k = StaticTuple(i, j)
 
272
                k = (i, j)
279
273
                obj.discard(k)
280
274
        # It should be back to 1024 wide mask, though there may still be some
281
275
        # dummy values in there
284
278
        self.assertTrue(obj.fill < 1024 / 5)
285
279
 
286
280
    def test__iter__(self):
287
 
        obj = _module.SimpleSet()
288
 
        k1 = StaticTuple('1')
289
 
        k2 = StaticTuple('1', '2')
290
 
        k3 = StaticTuple('3', '4')
 
281
        obj = self.module.SimpleSet()
 
282
        k1 = ('1',)
 
283
        k2 = ('1', '2')
 
284
        k3 = ('3', '4')
291
285
        obj.add(k1)
292
286
        obj.add(k2)
293
287
        obj.add(k3)
297
291
        self.assertEqual(sorted([k1, k2, k3]), sorted(all))
298
292
        iterator = iter(obj)
299
293
        iterator.next()
300
 
        obj.add(StaticTuple('foo'))
 
294
        obj.add(('foo',))
301
295
        # Set changed size
302
296
        self.assertRaises(RuntimeError, iterator.next)
303
297
        # And even removing an item still causes it to fail