All Downloads are FREE. Search and download functionalities are using the official Maven repository.

love.forte.simbot.utils.WeakMap.kt Maven / Gradle / Ivy

There is a newer version: 3.0.0.preview.0.4
Show newest version
package love.forte.simbot.utils

import java.lang.ref.Reference
import java.lang.ref.ReferenceQueue
import java.lang.ref.WeakReference


/**
 *
 * Value值为 weak 的 Map。
 *
 * @author ForteScarlet
 */
public class WeakMap(private val delegateMap: MutableMap>) : MutableMap {
    private val queue = ReferenceQueue()
    private inner class WeakReferenceWithKey(val key: K, value: V) : WeakReference(value, queue)

    init {
    }


    private fun checkWeak() {
        var polled: Reference? = queue.poll()
        while (polled != null) {
            if (polled is WeakMap<*, *>.WeakReferenceWithKey<*>) {
                remove(polled.key)
            }
            polled = queue.poll()
        }
    }



    override val size: Int get() = delegateMap.size
    override fun containsKey(key: K): Boolean = checkWeak().let { delegateMap.containsKey(key) }

    override fun containsValue(value: V): Boolean = checkWeak().let {
        delegateMap.values.any { it.get()?.equals(value) ?: false }
    }

    override fun get(key: K): V? {
        checkWeak()
        return delegateMap[key]?.get()
    }

    override fun isEmpty(): Boolean {
        checkWeak()
        return delegateMap.isEmpty()
    }

    @Suppress("UNCHECKED_CAST")
    override val entries: MutableSet>
        get() = checkWeak().let {
            delegateMap.entries.mapNotNull {
                val k = it.key
                val v = it.value.get() ?: return@mapNotNull null
                Entry(k, v) as MutableMap.MutableEntry
            }.toMutableSet()
        }
    override val keys: MutableSet
        get() = checkWeak().let { delegateMap.keys }

    override val values: MutableCollection
        get() = checkWeak().let { delegateMap.values.mapNotNull { it.get() } }.toMutableList()

    override fun clear() {
        delegateMap.clear()
    }

    override fun put(key: K, value: V): V? {
        return delegateMap.put(key, WeakReferenceWithKey(key, value))?.get()
    }

    override fun putAll(from: Map) {
        from.forEach { (k, u) -> put(k, u) }
    }

    override fun remove(key: K): V? {
        return delegateMap.remove(key)?.get()
    }
}

private class Entry(override val key: K, override var value: V) : MutableMap.MutableEntry {
    override fun setValue(newValue: V): V {
        val old = value
        value = newValue
        return old
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy