@@ -240,7 +240,9 @@ def test_map_collision_2(self):
240240 # <Key name:E hash:362244>: 'e'
241241 # <Key name:B hash:101>: 'b'
242242
243- def test_map_stress (self ):
243+
244+
245+ def test_map_stress_01 (self ):
244246 COLLECTION_SIZE = 7000
245247 TEST_ITERS_EVERY = 647
246248 CRASH_HASH_EVERY = 97
@@ -330,6 +332,78 @@ def test_map_stress(self):
330332 self .assertEqual (len (h ), 0 )
331333 self .assertEqual (list (h .items ()), [])
332334
335+ def test_map_stress_02 (self ):
336+ COLLECTION_SIZE = 20000
337+ TEST_ITERS_EVERY = 647
338+ CRASH_HASH_EVERY = 97
339+ DELETE_EVERY = 3
340+ CRASH_EQ_EVERY = 11
341+
342+ h = self .Map ()
343+ d = dict ()
344+
345+ for i in range (COLLECTION_SIZE // 2 ):
346+ key = KeyStr (i )
347+
348+ if not (i % CRASH_HASH_EVERY ):
349+ with HashKeyCrasher (error_on_hash = True ):
350+ with self .assertRaises (HashingError ):
351+ h .set (key , i )
352+
353+ h = h .set (key , i )
354+
355+ if not (i % CRASH_EQ_EVERY ):
356+ with HashKeyCrasher (error_on_eq = True ):
357+ with self .assertRaises (EqError ):
358+ h .get (KeyStr (i )) # really trigger __eq__
359+
360+ d [key ] = i
361+ self .assertEqual (len (d ), len (h ))
362+
363+ if not (i % TEST_ITERS_EVERY ):
364+ self .assertEqual (set (h .items ()), set (d .items ()))
365+ self .assertEqual (len (h .items ()), len (d .items ()))
366+
367+ with h .mutate () as m :
368+ for i in range (COLLECTION_SIZE // 2 , COLLECTION_SIZE ):
369+ key = KeyStr (i )
370+
371+ if not (i % CRASH_HASH_EVERY ):
372+ with HashKeyCrasher (error_on_hash = True ):
373+ with self .assertRaises (HashingError ):
374+ m [key ] = i
375+
376+ m [key ] = i
377+
378+ if not (i % CRASH_EQ_EVERY ):
379+ with HashKeyCrasher (error_on_eq = True ):
380+ with self .assertRaises (EqError ):
381+ m [KeyStr (i )]
382+
383+ d [key ] = i
384+ self .assertEqual (len (d ), len (m ))
385+
386+ if not (i % DELETE_EVERY ):
387+ del m [key ]
388+ del d [key ]
389+
390+ self .assertEqual (len (d ), len (m ))
391+
392+ h = m .finish ()
393+
394+ self .assertEqual (len (h ), len (d ))
395+ self .assertEqual (set (h .items ()), set (d .items ()))
396+
397+ with h .mutate () as m :
398+ for key in list (d ):
399+ del d [key ]
400+ del m [key ]
401+ self .assertEqual (len (m ), len (d ))
402+ h = m .finish ()
403+
404+ self .assertEqual (len (h ), len (d ))
405+ self .assertEqual (set (h .items ()), set (d .items ()))
406+
333407 def test_map_delete_1 (self ):
334408 A = HashKey (100 , 'A' )
335409 B = HashKey (101 , 'B' )
@@ -1235,6 +1309,67 @@ def test_map_mut_19(self):
12351309 m2 = m .update ({'a' : 20 })
12361310 self .assertEqual (len (m2 ), 2 )
12371311
1312+ def test_map_mut_20 (self ):
1313+ # Issue 24:
1314+
1315+ h = self .Map ()
1316+
1317+ for i in range (19 ):
1318+ # Create more than 16 keys to trigger the root bitmap
1319+ # node to be converted into an array node
1320+ h = h .set (HashKey (i , i ), i )
1321+
1322+
1323+ h = h .set (HashKey (18 , '18-collision' ), 18 )
1324+
1325+ with h .mutate () as m :
1326+ del m [HashKey (18 , 18 )]
1327+ del m [HashKey (18 , '18-collision' )]
1328+
1329+ # The pre-issue-24 code failed to update the number of array
1330+ # node element, so at this point it would be greater than it
1331+ # actually is.
1332+ h = m .finish ()
1333+
1334+ # Any of the below operations shouldn't crash the debug build.
1335+ with h .mutate () as m :
1336+ for i in range (18 ):
1337+ del m [HashKey (i , i )]
1338+ h = m .finish ()
1339+ h = h .set (HashKey (21 , 21 ), 21 )
1340+ h = h .set (HashKey (22 , 22 ), 22 )
1341+
1342+ def test_map_mut_21 (self ):
1343+ # Issue 24:
1344+ # Array nodes, while in mutation, failed to increment the
1345+ # internal count of elements when adding a new key to it.
1346+ # Because the internal count
1347+
1348+ h = self .Map ()
1349+
1350+ for i in range (18 ):
1351+ # Create more than 16 keys to trigger the root bitmap
1352+ # node to be converted into an array node
1353+ h = h .set (HashKey (i , i ), i )
1354+
1355+ with h .mutate () as m :
1356+ # Add one new key to the array node
1357+ m [HashKey (18 , 18 )] = 18
1358+ # Add another key -- after this the old code failed
1359+ # to increment the number of elements in the mutated
1360+ # array node.
1361+ m [HashKey (19 , 19 )] = 19
1362+ h = m .finish ()
1363+
1364+ for i in range (20 ):
1365+ # Start deleting keys one by one. Because array node
1366+ # element count was accounted incorrectly (smaller by 1
1367+ # than it actually is, the mutation for "del h[18]" would
1368+ # create an empty array node, clipping the "19" key).
1369+ # Before the issue #24 fix, the below line would crash
1370+ # on i=19.
1371+ h = h .delete (HashKey (i , i ))
1372+
12381373 def test_map_mut_stress (self ):
12391374 COLLECTION_SIZE = 7000
12401375 TEST_ITERS_EVERY = 647
0 commit comments