@@ -87,8 +87,8 @@ def _generic_test(self, cls, make_value, sha):
8787 del idx
8888
8989 def test_nsindex (self ):
90- self ._generic_test (NSIndex , lambda x : (x , x , x , x ),
91- 'c9fe5878800d2a0691b667c665a00d4a186e204e891076d6b109016940742bed ' )
90+ self ._generic_test (NSIndex , lambda x : (x , x , x ),
91+ '7d70671d0b7e9d2f51b2691ecf35184b9f8ecc1202cceb2748c905c8fc04c256 ' )
9292
9393 def test_chunkindex (self ):
9494 self ._generic_test (ChunkIndex , lambda x : (x , x ),
@@ -153,6 +153,70 @@ def test_chunkindex_summarize(self):
153153 assert chunks == 1 + 2 + 3
154154 assert unique_chunks == 3
155155
156+ def test_flags (self ):
157+ idx = NSIndex ()
158+ key = H (0 )
159+ self .assert_raises (KeyError , idx .flags , key , 0 )
160+ idx [key ] = 0 , 0 , 0 # create entry
161+ # check bit 0 and 1, should be both 0 after entry creation
162+ self .assert_equal (idx .flags (key , mask = 3 ), 0 )
163+ # set bit 0
164+ idx .flags (key , mask = 1 , value = 1 )
165+ self .assert_equal (idx .flags (key , mask = 1 ), 1 )
166+ # set bit 1
167+ idx .flags (key , mask = 2 , value = 2 )
168+ self .assert_equal (idx .flags (key , mask = 2 ), 2 )
169+ # check both bit 0 and 1, both should be set
170+ self .assert_equal (idx .flags (key , mask = 3 ), 3 )
171+ # clear bit 1
172+ idx .flags (key , mask = 2 , value = 0 )
173+ self .assert_equal (idx .flags (key , mask = 2 ), 0 )
174+ # clear bit 0
175+ idx .flags (key , mask = 1 , value = 0 )
176+ self .assert_equal (idx .flags (key , mask = 1 ), 0 )
177+ # check both bit 0 and 1, both should be cleared
178+ self .assert_equal (idx .flags (key , mask = 3 ), 0 )
179+
180+ def test_flags_iteritems (self ):
181+ idx = NSIndex ()
182+ keys_flagged0 = {H (i ) for i in (1 , 2 , 3 , 42 )}
183+ keys_flagged1 = {H (i ) for i in (11 , 12 , 13 , 142 )}
184+ keys_flagged2 = {H (i ) for i in (21 , 22 , 23 , 242 )}
185+ keys_flagged3 = {H (i ) for i in (31 , 32 , 33 , 342 )}
186+ for key in keys_flagged0 :
187+ idx [key ] = 0 , 0 , 0 # create entry
188+ idx .flags (key , mask = 3 , value = 0 ) # not really necessary, unflagged is default
189+ for key in keys_flagged1 :
190+ idx [key ] = 0 , 0 , 0 # create entry
191+ idx .flags (key , mask = 3 , value = 1 )
192+ for key in keys_flagged2 :
193+ idx [key ] = 0 , 0 , 0 # create entry
194+ idx .flags (key , mask = 3 , value = 2 )
195+ for key in keys_flagged3 :
196+ idx [key ] = 0 , 0 , 0 # create entry
197+ idx .flags (key , mask = 3 , value = 3 )
198+ # check if we can iterate over all items
199+ k_all = {k for k , v in idx .iteritems ()}
200+ self .assert_equal (k_all , keys_flagged0 | keys_flagged1 | keys_flagged2 | keys_flagged3 )
201+ # check if we can iterate over the flagged0 items
202+ k0 = {k for k , v in idx .iteritems (mask = 3 , value = 0 )}
203+ self .assert_equal (k0 , keys_flagged0 )
204+ # check if we can iterate over the flagged1 items
205+ k1 = {k for k , v in idx .iteritems (mask = 3 , value = 1 )}
206+ self .assert_equal (k1 , keys_flagged1 )
207+ # check if we can iterate over the flagged2 items
208+ k1 = {k for k , v in idx .iteritems (mask = 3 , value = 2 )}
209+ self .assert_equal (k1 , keys_flagged2 )
210+ # check if we can iterate over the flagged3 items
211+ k1 = {k for k , v in idx .iteritems (mask = 3 , value = 3 )}
212+ self .assert_equal (k1 , keys_flagged3 )
213+ # check if we can iterate over the flagged1 + flagged3 items
214+ k1 = {k for k , v in idx .iteritems (mask = 1 , value = 1 )}
215+ self .assert_equal (k1 , keys_flagged1 | keys_flagged3 )
216+ # check if we can iterate over the flagged0 + flagged2 items
217+ k1 = {k for k , v in idx .iteritems (mask = 1 , value = 0 )}
218+ self .assert_equal (k1 , keys_flagged0 | keys_flagged2 )
219+
156220
157221class HashIndexExtraTestCase (BaseTestCase ):
158222 """These tests are separate because they should not become part of the selftest.
@@ -531,38 +595,38 @@ def test_bug_4829(self):
531595
532596 from struct import pack
533597
534- def HH (w , x , y , z ):
535- # make some 32byte long thing that depends on w, x, y, z.
536- # same w will mean a collision in the hashtable as bucket index is computed from
537- # first 4 bytes. giving a specific w targets bucket index w .
538- # x is to create different keys and does not go into the bucket index calculation.
539- # so, same w + different x --> collision
540- return pack ('<IIIIIIII' , w , x , y , z , 0 , 0 , 0 , 0 ) # 8 * 4 == 32
598+ def HH (x , y , z ):
599+ # make some 32byte long thing that depends on x, y, z.
600+ # same x will mean a collision in the hashtable as bucket index is computed from
601+ # first 4 bytes. giving a specific x targets bucket index x .
602+ # y is to create different keys and does not go into the bucket index calculation.
603+ # so, same x + different y --> collision
604+ return pack ('<IIIIIIII' , x , y , z , 0 , 0 , 0 , 0 , 0 ) # 8 * 4 == 32
541605
542606 idx = NSIndex ()
543607
544608 # create lots of colliding entries
545- for x in range (700 ): # stay below max load to not trigger resize
546- idx [HH (0 , x , 0 , 0 )] = (0 , x , 0 , 0 )
609+ for y in range (700 ): # stay below max load to not trigger resize
610+ idx [HH (0 , y , 0 )] = (0 , y , 0 )
547611
548612 assert idx .size () == 1031 * 48 + 18 # 1031 buckets + header
549613
550614 # delete lots of the collisions, creating lots of tombstones
551- for x in range (400 ): # stay above min load to not trigger resize
552- del idx [HH (0 , x , 0 , 0 )]
615+ for y in range (400 ): # stay above min load to not trigger resize
616+ del idx [HH (0 , y , 0 )]
553617
554618 # create lots of colliding entries, within the not yet used part of the hashtable
555- for x in range (330 ): # stay below max load to not trigger resize
556- # at x == 259 a resize will happen due to going beyond max EFFECTIVE load
619+ for y in range (330 ): # stay below max load to not trigger resize
620+ # at y == 259 a resize will happen due to going beyond max EFFECTIVE load
557621 # if the bug is present, that element will be inserted at the wrong place.
558622 # and because it will be at the wrong place, it can not be found again.
559- idx [HH (600 , x , 0 , 0 )] = 600 , x , 0 , 0
623+ idx [HH (600 , y , 0 )] = 600 , y , 0
560624
561625 # now check if hashtable contents is as expected:
562626
563- assert [idx .get (HH (0 , x , 0 , 0 )) for x in range (400 , 700 )] == [(0 , x , 0 , 0 ) for x in range (400 , 700 )]
627+ assert [idx .get (HH (0 , y , 0 )) for y in range (400 , 700 )] == [(0 , y , 0 ) for y in range (400 , 700 )]
564628
565- assert [HH (0 , x , 0 , 0 ) in idx for x in range (400 )] == [False for x in range (400 )] # deleted entries
629+ assert [HH (0 , y , 0 ) in idx for y in range (400 )] == [False for y in range (400 )] # deleted entries
566630
567631 # this will fail at HH(600, 259) if the bug is present.
568- assert [idx .get (HH (600 , x , 0 , 0 )) for x in range (330 )] == [(600 , x , 0 , 0 ) for x in range (330 )]
632+ assert [idx .get (HH (600 , y , 0 )) for y in range (330 )] == [(600 , y , 0 ) for y in range (330 )]
0 commit comments