You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

51 lines
1.5 KiB
Kotlin

package moe.odango.index.utils
class MergeMap<T> {
private var bucketIndex = 0L
private val buckets: MutableMap<Long, MutableSet<T>> = mutableMapOf()
private val bucketIndexByItem: MutableMap<T, Long> = mutableMapOf()
fun add(a: T, b: T) {
val bucketA = bucketIndexByItem[a]
val bucketB = bucketIndexByItem[b]
if (bucketA == null && bucketB == null) {
bucketIndexByItem[a] = bucketIndex
bucketIndexByItem[b] = bucketIndex
buckets[bucketIndex] = mutableSetOf(a, b)
bucketIndex++
return
}
if (bucketB == bucketA) {
return
}
if (bucketA == null && bucketB != null) {
bucketIndexByItem[a] = bucketB
buckets.getOrPut(bucketB, ::mutableSetOf).add(a)
return
}
if (bucketB == null && bucketA != null) {
bucketIndexByItem[b] = bucketA
buckets.getOrPut(bucketA, ::mutableSetOf).add(b)
return
}
// Always false :)
if (bucketA == null || bucketB == null) return
val bucket = buckets.getOrPut(bucketB, ::mutableSetOf)
buckets.getOrPut(bucketA, ::mutableSetOf).addAll(bucket)
for (item in bucket) {
bucketIndexByItem[item] = bucketA
}
}
operator fun get(item: T): Set<T>? {
return buckets[bucketIndexByItem[item] ?: return null]
}
operator fun iterator(): Iterator<Set<T>> = buckets.values.iterator()
}