66package tests.implementations.list
77
88import kotlinx.collections.immutable.implementations.immutableMap.LOG_MAX_BRANCHING_FACTOR
9+ import kotlinx.collections.immutable.implementations.immutableMap.MAX_SHIFT
910import kotlinx.collections.immutable.implementations.immutableMap.PersistentHashMap
1011import kotlinx.collections.immutable.implementations.immutableMap.TrieNode
1112import tests.stress.IntWrapper
@@ -194,9 +195,17 @@ class HashMapTrieNodeTest {
194195 //
195196 // Remove (1, 1)
196197 //
197- // ------------- ------
198- // [ 2, 2 | 1, 1 ] -> [ 2, 2 ]
199- // ------------- ------
198+ // --- ------
199+ // | * | | 2, 2 |
200+ // -|- ------
201+ // | ->
202+ // *
203+ // *
204+ // *
205+ // |
206+ // -------------
207+ // [ 2, 2 | 1, 1 ]
208+ // -------------
200209 //
201210 @Test
202211 fun collision () {
@@ -205,13 +214,22 @@ class HashMapTrieNodeTest {
205214 val map = PersistentHashMap .emptyOf<IntWrapper , Int >().put(wrapper1, 1 ).put(wrapper2, 2 )
206215
207216 map.node.accept { node: TrieNode <IntWrapper , Int >, shift: Int , hash: Int , dataMap: Int , nodeMap: Int ->
208- assertTrue(node.isCollision())
209- assertTrue(arrayOf(wrapper2, 2 , wrapper1, 1 ) contentEquals node.buffer)
217+ if (shift > MAX_SHIFT ) {
218+ assertEquals(1 , hash)
219+ assertEquals(0b0 , dataMap)
220+ assertEquals(0b0 , nodeMap)
221+ assertEquals(arrayOf<Any ?>(wrapper1, 1 , wrapper2, 2 ).map { it }, node.buffer.map { it })
222+ } else {
223+ assertEquals(0b0 , dataMap)
224+ val mask = if (shift == 0 ) 0b10 else 0b1
225+ assertEquals(mask, nodeMap)
226+ }
210227 }
211228
212229 map.remove(wrapper1).node.accept { node: TrieNode <IntWrapper , Int >, shift: Int , hash: Int , dataMap: Int , nodeMap: Int ->
213230 assertEquals(0 , shift)
214- assertTrue(node.isCollision())
231+ assertEquals(0b10 , dataMap)
232+ assertEquals(0b0 , nodeMap)
215233 assertTrue(arrayOf(wrapper2, 2 ) contentEquals node.buffer)
216234 }
217235
@@ -230,6 +248,10 @@ class HashMapTrieNodeTest {
230248 // | 3, 3 | * | | 2, 2 | 3, 3 |
231249 // --------|- -------------
232250 // |
251+ // *
252+ // *
253+ // *
254+ // |
233255 // -------------
234256 // [ 2, 2 | 1, 1 ]
235257 // -------------
@@ -241,6 +263,33 @@ class HashMapTrieNodeTest {
241263 val wrapper3 = IntWrapper (3 , 0b1_00001 )
242264 val map = PersistentHashMap .emptyOf<IntWrapper , Int >().put(wrapper1, 1 ).put(wrapper2, 2 ).put(wrapper3, 3 )
243265
266+ map.node.accept { node: TrieNode <IntWrapper , Int >, shift: Int , hash: Int , dataMap: Int , nodeMap: Int ->
267+ when (shift) {
268+ 0 -> {
269+ assertEquals(0 , hash)
270+ assertEquals(0b0 , dataMap)
271+ assertEquals(0b10 , nodeMap)
272+ }
273+ LOG_MAX_BRANCHING_FACTOR -> {
274+ assertEquals(1 , hash)
275+ assertEquals(0b10 , dataMap)
276+ assertEquals(0b1 , nodeMap)
277+ assertTrue(arrayOf<Any ?>(wrapper3, 3 ) contentEquals node.buffer.copyOf(2 ))
278+ }
279+ in LOG_MAX_BRANCHING_FACTOR + 1 .. MAX_SHIFT -> {
280+ assertEquals(1 , hash)
281+ assertEquals(0b0 , dataMap)
282+ assertEquals(0b1 , nodeMap)
283+ }
284+ else -> {
285+ assertEquals(1 , hash)
286+ assertEquals(0b0 , dataMap)
287+ assertEquals(0b0 , nodeMap)
288+ assertEquals(arrayOf<Any ?>(wrapper1, 1 , wrapper2, 2 ).map { it }, node.buffer.map { it })
289+ }
290+ }
291+ }
292+
244293 map.remove(wrapper1).node.accept { node: TrieNode <IntWrapper , Int >, shift: Int , hash: Int , dataMap: Int , nodeMap: Int ->
245294 if (shift == 0 ) {
246295 assertEquals(0b0 , dataMap)
@@ -267,6 +316,10 @@ class HashMapTrieNodeTest {
267316 // | 3, 3 | * | | * |
268317 // --------|- -|-
269318 // | |
319+ // * *
320+ // * *
321+ // * *
322+ // | |
270323 // ------------- -------------
271324 // [ 2, 2 | 1, 1 ] [ 2, 2 | 1, 1 ]
272325 // ------------- -------------
@@ -278,43 +331,20 @@ class HashMapTrieNodeTest {
278331 val wrapper3 = IntWrapper (3 , 0b1_00001 )
279332 val map = PersistentHashMap .emptyOf<IntWrapper , Int >().put(wrapper1, 1 ).put(wrapper2, 2 ).put(wrapper3, 3 )
280333
281- map.node.accept { node: TrieNode <IntWrapper , Int >, shift: Int , hash: Int , dataMap: Int , nodeMap: Int ->
282- when (shift) {
283- 0 -> {
284- assertEquals(0b0 , dataMap)
285- assertEquals(0b10 , nodeMap)
286- }
287- LOG_MAX_BRANCHING_FACTOR -> {
288- assertEquals(1 , hash)
289- assertEquals(0b10 , dataMap)
290- assertEquals(0b1 , nodeMap)
291- assertTrue(arrayOf<Any ?>(wrapper3, 3 ) contentEquals node.buffer.copyOf(2 ))
292- }
293- else -> {
294- assertEquals(1 , hash)
295- assertEquals(2 * LOG_MAX_BRANCHING_FACTOR , shift)
296- assertTrue(node.isCollision())
297- assertTrue(arrayOf<Any ?>(wrapper2, 2 , wrapper1, 1 ) contentEquals node.buffer)
298- }
299- }
300- }
301-
302334 map.remove(wrapper3).node.accept { node: TrieNode <IntWrapper , Int >, shift: Int , hash: Int , dataMap: Int , nodeMap: Int ->
303335 when (shift) {
304- 0 -> {
305- assertEquals(0b0 , dataMap)
306- assertEquals(0b10 , nodeMap)
307- }
308- LOG_MAX_BRANCHING_FACTOR -> {
309- assertEquals(1 , hash)
336+ in 0 .. MAX_SHIFT -> {
337+ val code = if (shift == 0 ) 0 else 1
338+ assertEquals(code, hash)
310339 assertEquals(0b0 , dataMap)
311- assertEquals(0b1 , nodeMap)
340+ val mask = if (shift == 0 ) 0b10 else 0b1
341+ assertEquals(mask, nodeMap)
312342 }
313343 else -> {
314344 assertEquals(1 , hash)
315- assertEquals(2 * LOG_MAX_BRANCHING_FACTOR , shift )
316- assertTrue(node.isCollision() )
317- assertTrue(arrayOf<Any ?>(wrapper2, 2 , wrapper1, 1 ) contentEquals node.buffer)
345+ assertEquals(0b0 , dataMap )
346+ assertEquals( 0b0 , nodeMap )
347+ assertTrue(arrayOf<Any ?>(wrapper1, 1 , wrapper2, 2 ) contentEquals node.buffer)
318348 }
319349 }
320350 }
0 commit comments