commonMain.org.jetbrains.letsPlot.livemap.containers.LruCache.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of livemap-jvm Show documentation
Show all versions of livemap-jvm Show documentation
A part of the Lets-Plot library.
The newest version!
/*
* Copyright (c) 2019. JetBrains s.r.o.
* Use of this source code is governed by the MIT license that can be found in the LICENSE file.
*/
package org.jetbrains.letsPlot.livemap.containers
class LruCache(private val limit: Int) {
val values: List
get() {
val resultList = ArrayList()
var node: Node? = head ?: return emptyList()
while (node != null) {
resultList.add(node.myItem)
node = node.myNext
}
return resultList
}
private val map = HashMap>()
private var head: Node? = null
private var tail: Node? = null
private fun nodeToHead(node: Node) {
if (node !== head) {
if (node === tail) {
tail = node.myPrev
}
node.myPrev?.myNext = node.myNext
node.myNext?.myPrev = node.myPrev
node.myNext = head
head!!.myPrev = node
head = node
}
}
operator fun get(key: K): E? {
return map[key]?.let { node ->
nodeToHead(node)
node.myItem
}
}
fun put(key: K, value: E) {
map[key]
?.let {
it.myItem = value
nodeToHead(it)
}
?:let {
if (map.isNotEmpty()) {
head!!.myPrev = Node(key, value, null, head)
head!!.myPrev
} else {
tail = Node(key, value, null, null)
tail
}.let {
requireNotNull(it)
head = it
}
map[key] = head!!
}
if (map.size > limit) {
tail?.let {
tail = it.myPrev
tail!!.myNext = null
map.remove(it.myKey)
}
}
}
fun getOrPut(key: K, defaultValue: () -> E): E {
val value = get(key)
return if (value != null) {
value
} else {
val answer = defaultValue()
put(key, answer)
answer
}
}
fun containsKey(key: K): Boolean = map.containsKey(key)
private class Node internal constructor(
internal val myKey: K,
internal var myItem: E,
internal var myPrev: Node?,
internal var myNext: Node?
)
}