LRU Cache
A Least Recently Used Cache is typically implemented with a Doubly-Linked List and a Map:
class DoublyLinkedList {
private var head: Entry = Entry(0, 0)
private var tail: Entry = Entry(0, 0)
init {
head.next = tail
tail.previous = head
}
fun insertHead(entry: Entry) {
entry.previous = head
entry.next = head.next
head.next?.previous = entry
head.next = entry
}
fun remove(entry: Entry) {
entry.previous?.next = entry.next
entry.next?.previous = entry.previous
}
fun removeTail(): Int {
val node = tail.previous!!
val key = node.key
remove(node)
return key
}
}
class Entry(
val key: Int,
val value: Int,
var next: Entry? = null,
var previous: Entry? = null
)
class LRUCache(val capacity: Int) {
private val cache = mutableMapOf<Int, Entry>()
private val list = DoublyLinkedList()
operator fun get(key: Int): Int {
if (!cache.containsKey(key)) return -1
update(key, cache[key]!!)
return cache[key]!!.value
}
fun put(key: Int, value: Int) {
val n = Entry(key, value)
if (cache.containsKey(key)) {
list.remove(cache[key]!!)
} else if (cache.size >= capacity) {
val k = list.removeTail()
cache.remove(k)
}
list.insertHead(n)
cache[key] = n
}
private fun update(key: Int, n: Entry) {
list.remove(n)
list.insertHead(n)
cache[key] = n
}
}