@@ -116,54 +116,55 @@ def test_chunkindex_summarize(self):
116
116
assert chunks == 1 + 2 + 3
117
117
assert unique_chunks == 3
118
118
119
+
120
+ class HashIndexRefcountingTestCase (BaseTestCase ):
121
+ MAX_REF = 2 ** 31 - 1
122
+
119
123
def test_chunkindex_overflow (self ):
120
- max_ref = hashindex .MAX_REF
121
124
idx = ChunkIndex ()
122
- idx [H (1 )] = max_ref - 1 , 1 , 2
123
-
124
- refcount , * _ = idx .incref (H (1 ))
125
- assert refcount == max_ref
125
+ idx [H (1 )] = self .MAX_REF - 1 , 1 , 2
126
126
127
- refcount , * _ = idx .decref (H (1 ))
128
- assert refcount == max_ref
127
+ # 5 is arbitray, any number of incref/decrefs shouldn't move it once it maxes out
128
+ for i in range (5 ):
129
+ refcount , * _ = idx .incref (H (1 ))
130
+ assert refcount == self .MAX_REF
131
+ for i in range (5 ):
132
+ refcount , * _ = idx .decref (H (1 ))
133
+ assert refcount == self .MAX_REF
129
134
130
135
def test_chunkindex_merge_overflow1 (self ):
131
- # Check that it does not overflow at max_ref - 1
136
+ # Check that it does not overflow at 2**31-2
132
137
idx1 = ChunkIndex ()
133
- half = int (hashindex .MAX_REF / 2 )
134
- inverse_parity = 1 - hashindex .MAX_REF % 2
135
- # if max_ref is even, then the result is
136
- # 2 * floor(max_ref/2) - 1
137
- # ^^^^^^^^^^^^^^^^^^^^ = max_ref
138
- # if max_ref is odd, then
139
- # 2 * floor(max_ref/2) - 0
140
- # ^^^^^^^^^^^^^^^^^^^^ = max_ref - 1
141
- idx1 [H (1 )] = half - inverse_parity , 1 , 2
138
+ # n.b. 2**31-1 is odd
139
+ half = self .MAX_REF // 2
140
+ idx1 [H (1 )] = half , 1 , 2
142
141
idx2 = ChunkIndex ()
143
142
idx2 [H (1 )] = half , 1 , 2
144
143
idx1 .merge (idx2 )
145
144
refcount , * _ = idx1 [H (1 )]
146
- assert refcount == hashindex .MAX_REF - 1
145
+ assert refcount == self .MAX_REF - 1
146
+ refcount , * _ = idx1 .decref (H (1 ))
147
+ assert refcount == self .MAX_REF - 2
147
148
148
149
def test_chunkindex_merge_overflow2 (self ):
149
- # Check that it goes to max_ref even with values that are larged than max_ref themselves
150
150
idx1 = ChunkIndex ()
151
- idx1 [H (1 )] = 147483647 , 1 , 2
151
+ idx1 [H (1 )] = 2000000000 , 1 , 2
152
152
idx2 = ChunkIndex ()
153
153
idx2 [H (1 )] = 2000000000 , 1 , 2
154
154
idx1 .merge (idx2 )
155
155
refcount , * _ = idx1 [H (1 )]
156
- assert refcount == hashindex .MAX_REF
156
+ assert refcount == self .MAX_REF
157
157
158
158
def test_chunkindex_merge_overflow3 (self ):
159
+ # Check that merging maxes out right at 2**31-1
159
160
idx1 = ChunkIndex ()
160
- half = hashindex .MAX_REF / 2
161
+ half = self .MAX_REF / / 2
161
162
idx1 [H (1 )] = half + 1 , 1 , 2
162
163
idx2 = ChunkIndex ()
163
164
idx2 [H (1 )] = half , 1 , 2
164
165
idx1 .merge (idx2 )
165
166
refcount , * _ = idx1 [H (1 )]
166
- assert refcount == hashindex .MAX_REF
167
+ assert refcount == self .MAX_REF
167
168
168
169
def test_chunkindex_add (self ):
169
170
idx1 = ChunkIndex ()
@@ -178,16 +179,16 @@ def test_chunkindex_addinc(self):
178
179
idx1 .add (H (1 ), 2 , 3 , 4 )
179
180
assert idx1 [H (1 )] == (7 , 6 , 7 )
180
181
181
- def test_max_ref_transparent_inc (self ):
182
+ def test_transparent_inc (self ):
182
183
idx1 = ChunkIndex ()
183
- idx1 [H (1 )] = (2 ** 31 - 1 , 6 , 7 )
184
+ idx1 [H (1 )] = (self . MAX_REF , 6 , 7 )
184
185
idx1 .incref (H (1 ))
185
186
refcount , * _ = idx1 [H (1 )]
186
- assert refcount == hashindex .MAX_REF
187
+ assert refcount == self .MAX_REF
187
188
188
- def test_max_ref_transparent_dec (self ):
189
+ def test_transparent_dec (self ):
189
190
idx1 = ChunkIndex ()
190
- idx1 [H (1 )] = (2 ** 31 - 1 , 6 , 7 )
191
+ idx1 [H (1 )] = (self . MAX_REF , 6 , 7 )
191
192
idx1 .decref (H (1 ))
192
193
refcount , * _ = idx1 [H (1 )]
193
- assert refcount == hashindex .MAX_REF
194
+ assert refcount == self .MAX_REF
0 commit comments