~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test__static_tuple_interned.py

Start working on more of the C api for StaticTupleInterner.

It is really nice to have the except -1 clauses, as suddenly you don't have
to manually check the return values of all of your functions. \o/

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
"""Tests for the StaticTupleInterned type."""
18
18
 
 
19
import sys
 
20
 
19
21
from bzrlib import (
20
22
    # _static_tuple_py,
21
23
    errors,
65
67
        self.assertTrue(obj not in container,
66
68
            'We found %s in %s' % (obj, container))
67
69
 
 
70
    def assertFillState(self, used, fill, mask, obj):
 
71
        self.assertEqual((used, fill, mask), (obj.used, obj.fill, obj.mask))
 
72
 
 
73
    def assertRefcount(self, count, obj):
 
74
        """Assert that the refcount for obj is what we expect.
 
75
 
 
76
        Note that this automatically adjusts for the fact that calling
 
77
        assertRefcount actually creates a new pointer, as does calling
 
78
        sys.getrefcount. So pass the expected value *before* the call.
 
79
        """
 
80
        # I don't understand why it is count+3 here, but it seems to be
 
81
        # correct. If I check in the calling function, with:
 
82
        # self.assertEqual(count+1, sys.getrefcount(obj))
 
83
        # Then it works fine. Something about passing it to assertRefcount is
 
84
        # actually double-incrementing (and decrementing) the refcount
 
85
        self.assertEqual(count+3, sys.getrefcount(obj))
 
86
 
68
87
    def test_initial(self):
69
88
        obj = _module.StaticTupleInterner()
70
89
        self.assertEqual(0, len(obj))
71
90
        st = StaticTuple('foo', 'bar')
72
 
        self.assertEqual(0, obj.used)
73
 
        self.assertEqual(0, obj.fill)
74
 
        self.assertEqual(0x3ff, obj.mask) # 1024 - 1
 
91
        self.assertFillState(0, 0, 0x3ff, obj)
75
92
 
76
93
    def test__lookup(self):
77
94
        # The tuple hash function is rather good at entropy. For all integers
103
120
        self.assertEqual((643, '<null>'), obj._test_lookup(k2))
104
121
        self.assertEqual((643, '<null>'), obj._test_lookup(k3))
105
122
        self.assertEqual((643, '<null>'), obj._test_lookup(k4))
106
 
        obj[k1] = k1
 
123
        obj.add(k1)
107
124
        self.assertIn(k1, obj)
108
125
        self.assertNotIn(k2, obj)
109
126
        self.assertNotIn(k3, obj)
113
130
        self.assertEqual((787, '<null>'), obj._test_lookup(k3))
114
131
        self.assertEqual((787, '<null>'), obj._test_lookup(k4))
115
132
        self.assertIs(k1, obj[k1])
116
 
        obj[k2] = k2
 
133
        obj.add(k2)
117
134
        self.assertIs(k2, obj[k2])
118
135
        self.assertEqual((643, k1), obj._test_lookup(k1))
119
136
        self.assertEqual((787, k2), obj._test_lookup(k2))
126
143
        self.assertEqual((787, k2), obj._test_lookup(('f', '4')))
127
144
        self.assertEqual((660, '<null>'), obj._test_lookup(('p', 'r')))
128
145
        self.assertEqual((180, '<null>'), obj._test_lookup(('q', '1')))
129
 
        obj[k3] = k3
 
146
        obj.add(k3)
130
147
        self.assertIs(k3, obj[k3])
131
148
        self.assertIn(k1, obj)
132
149
        self.assertIn(k2, obj)
142
159
        self.assertIn(k2, obj)
143
160
        self.assertIn(k3, obj)
144
161
        self.assertNotIn(k4, obj)
 
162
 
 
163
    def test_add(self):
 
164
        obj = _module.StaticTupleInterner()
 
165
        self.assertFillState(0, 0, 0x3ff, obj)
 
166
        k1 = StaticTuple('foo')
 
167
        self.assertRefcount(1, k1)
 
168
        self.assertIs(k1, obj.add(k1))
 
169
        self.assertFillState(1, 1, 0x3ff, obj)
 
170
        self.assertRefcount(2, k1)
 
171
        ktest = obj[k1]
 
172
        self.assertRefcount(3, k1)
 
173
        self.assertIs(k1, ktest)
 
174
        del ktest
 
175
        self.assertRefcount(2, k1)
 
176
        k2 = StaticTuple('foo')
 
177
        self.assertRefcount(1, k2)
 
178
        self.assertIsNot(k1, k2)
 
179
        # doesn't add anything, so the counters shouldn't be adjusted
 
180
        self.assertIs(k1, obj.add(k2))
 
181
        self.assertFillState(1, 1, 0x3ff, obj)
 
182
        self.assertRefcount(2, k1) # not changed
 
183
        self.assertRefcount(1, k2) # not incremented
 
184
        self.assertIs(k1, obj[k1])
 
185
        self.assertIs(k1, obj[k2])
 
186
        self.assertRefcount(2, k1)
 
187
        self.assertRefcount(1, k2)
 
188
        # Deleting an entry should remove the fill, but not the used
 
189
        del obj[k1]
 
190
        self.assertFillState(0, 1, 0x3ff, obj)
 
191
        self.assertRefcount(1, k1)
 
192
        k3 = StaticTuple('bar')
 
193
        self.assertRefcount(1, k3)
 
194
        self.assertIs(k3, obj.add(k3))
 
195
        self.assertFillState(1, 2, 0x3ff, obj)
 
196
        self.assertRefcount(2, k3)
 
197
        self.assertIs(k2, obj.add(k2))
 
198
        self.assertFillState(2, 2, 0x3ff, obj)
 
199
        self.assertRefcount(1, k1)
 
200
        self.assertRefcount(2, k2)
 
201
        self.assertRefcount(2, k3)
 
202
 
 
203
    def test_discard(self):
 
204
        obj = _module.StaticTupleInterner()
 
205
        k1 = StaticTuple('foo')
 
206
        k2 = StaticTuple('foo')
 
207
        k3 = StaticTuple('bar')
 
208
        self.assertRefcount(1, k1)
 
209
        self.assertRefcount(1, k2)
 
210
        self.assertRefcount(1, k3)
 
211
        obj.add(k1)
 
212
        self.assertRefcount(2, k1)
 
213
        self.assertEqual(0, obj.discard(k3))
 
214
        self.assertRefcount(1, k3)
 
215
        obj.add(k3)
 
216
        self.assertRefcount(2, k3)
 
217
        self.assertEqual(1, obj.discard(k3))
 
218
        self.assertRefcount(1, k3)
 
219
 
 
220
    def test__delitem__(self):
 
221
        obj = _module.StaticTupleInterner()
 
222
        k1 = StaticTuple('foo')
 
223
        k2 = StaticTuple('foo')
 
224
        k3 = StaticTuple('bar')
 
225
        self.assertRefcount(1, k1)
 
226
        self.assertRefcount(1, k2)
 
227
        self.assertRefcount(1, k3)
 
228
        obj.add(k1)
 
229
        self.assertRefcount(2, k1)
 
230
        self.assertRaises(KeyError, obj.__delitem__, k3)
 
231
        self.assertRefcount(1, k3)
 
232
        obj.add(k3)
 
233
        self.assertRefcount(2, k3)
 
234
        del obj[k3]
 
235
        self.assertRefcount(1, k3)