We have been using kotlinx collections immutable for some years and we finally found a bug :worried:
I don't know exactly why it happens, but I can simulate it with the following code:
(1..1000).forEach { // the bug doesn't happen every time, so I put it inside a loop to make it easier to happen
val originalList = (1..40000)
.map {
listOf(
UUID.randomUUID().toString(),
UUID.randomUUID().toString()
)
}
val originalPersistentSet = originalList.flatten()
.toPersistentList()
.add(UUID.randomUUID().toString()) // this is the only element that shouldn't be removed
.toPersistentHashSet()
val firstLBatchToRemove = originalList.map { it[0] }.toPersistentHashSet()
val secondBatchToRemove = originalList.map { it[1] }.toPersistentHashSet()
val result = originalPersistentSet
// .minus(firstLBatchToRemove.plus(secondBatchToRemove).toPersistentHashSet()) // if I use this line instead of the next two, it seems that the bug doesn't happen anymore
.minus(firstLBatchToRemove)
.minus(secondBatchToRemove)
.toPersistentHashSet()
result.size shouldBe 1 // always true, as it should be
shouldNotThrowAny { println(result.first()) } // This assert fails once in a while throwing `NoSuchElementException`
delay(1.seconds)
}
Basically, after two minus operations in a "large" PersistentHashSet, I get a PersistentSet with size 1 (as expected in this test). Still, when I try to get the element, the following exception is thrown:
Collection is empty.
java.util.NoSuchElementException: Collection is empty.
at kotlin.collections.CollectionsKt___CollectionsKt.first(_Collections.kt:201)
at com.collections.PersistentHashSetTest$1$2.invokeSuspend(PersistentHashSetTest.kt:59) // my test class
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
It long as I can tell, it is a bug exclusively on PersistentHashSet.
I've applied the same tests using PersistentSet, HashSet, and Lists (immutable or not) and it worked just fine.
Hope I have explained it successfully, please tell me if I can help more somehow.
Hi everyone.
We have been using kotlinx collections immutable for some years and we finally found a bug :worried: I don't know exactly why it happens, but I can simulate it with the following code:
Basically, after two
minus
operations in a "large" PersistentHashSet, I get a PersistentSet with size 1 (as expected in this test). Still, when I try to get the element, the following exception is thrown:It long as I can tell, it is a bug exclusively on PersistentHashSet. I've applied the same tests using
PersistentSet
,HashSet
, and Lists (immutable or not) and it worked just fine.Hope I have explained it successfully, please tell me if I can help more somehow.