6
6
package tests.implementations.list
7
7
8
8
import kotlinx.collections.immutable.implementations.immutableMap.LOG_MAX_BRANCHING_FACTOR
9
+ import kotlinx.collections.immutable.implementations.immutableMap.MAX_SHIFT
9
10
import kotlinx.collections.immutable.implementations.immutableMap.PersistentHashMap
10
11
import kotlinx.collections.immutable.implementations.immutableMap.TrieNode
11
12
import tests.stress.IntWrapper
@@ -194,9 +195,17 @@ class HashMapTrieNodeTest {
194
195
//
195
196
// Remove (1, 1)
196
197
//
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
+ // -------------
200
209
//
201
210
@Test
202
211
fun collision () {
@@ -205,13 +214,22 @@ class HashMapTrieNodeTest {
205
214
val map = PersistentHashMap .emptyOf<IntWrapper , Int >().put(wrapper1, 1 ).put(wrapper2, 2 )
206
215
207
216
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
+ }
210
227
}
211
228
212
229
map.remove(wrapper1).node.accept { node: TrieNode <IntWrapper , Int >, shift: Int , hash: Int , dataMap: Int , nodeMap: Int ->
213
230
assertEquals(0 , shift)
214
- assertTrue(node.isCollision())
231
+ assertEquals(0b10 , dataMap)
232
+ assertEquals(0b0 , nodeMap)
215
233
assertTrue(arrayOf(wrapper2, 2 ) contentEquals node.buffer)
216
234
}
217
235
@@ -230,6 +248,10 @@ class HashMapTrieNodeTest {
230
248
// | 3, 3 | * | | 2, 2 | 3, 3 |
231
249
// --------|- -------------
232
250
// |
251
+ // *
252
+ // *
253
+ // *
254
+ // |
233
255
// -------------
234
256
// [ 2, 2 | 1, 1 ]
235
257
// -------------
@@ -241,6 +263,33 @@ class HashMapTrieNodeTest {
241
263
val wrapper3 = IntWrapper (3 , 0b1_00001 )
242
264
val map = PersistentHashMap .emptyOf<IntWrapper , Int >().put(wrapper1, 1 ).put(wrapper2, 2 ).put(wrapper3, 3 )
243
265
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
+
244
293
map.remove(wrapper1).node.accept { node: TrieNode <IntWrapper , Int >, shift: Int , hash: Int , dataMap: Int , nodeMap: Int ->
245
294
if (shift == 0 ) {
246
295
assertEquals(0b0 , dataMap)
@@ -267,6 +316,10 @@ class HashMapTrieNodeTest {
267
316
// | 3, 3 | * | | * |
268
317
// --------|- -|-
269
318
// | |
319
+ // * *
320
+ // * *
321
+ // * *
322
+ // | |
270
323
// ------------- -------------
271
324
// [ 2, 2 | 1, 1 ] [ 2, 2 | 1, 1 ]
272
325
// ------------- -------------
@@ -278,43 +331,20 @@ class HashMapTrieNodeTest {
278
331
val wrapper3 = IntWrapper (3 , 0b1_00001 )
279
332
val map = PersistentHashMap .emptyOf<IntWrapper , Int >().put(wrapper1, 1 ).put(wrapper2, 2 ).put(wrapper3, 3 )
280
333
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
-
302
334
map.remove(wrapper3).node.accept { node: TrieNode <IntWrapper , Int >, shift: Int , hash: Int , dataMap: Int , nodeMap: Int ->
303
335
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)
310
339
assertEquals(0b0 , dataMap)
311
- assertEquals(0b1 , nodeMap)
340
+ val mask = if (shift == 0 ) 0b10 else 0b1
341
+ assertEquals(mask, nodeMap)
312
342
}
313
343
else -> {
314
344
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)
318
348
}
319
349
}
320
350
}
0 commit comments