Add cache implementation

This commit is contained in:
Alexander Nozik 2023-10-09 20:28:48 +03:00
parent ff4414d819
commit 4c8b6b7c64
Signed by: altavir
GPG Key ID: B10A55DCC7B9AEBB
5 changed files with 54 additions and 2 deletions

12
idiomatic.md Normal file
View File

@ -0,0 +1,12 @@
## Что такое "идиоматический"?
* Написанный при помощи [идиом](https://kotlinlang.org/docs/idioms.html).
* Использующий специфическую для Kotlin гибридную "парадигму" построения программы.
## Совершенно неофициальный манифест идиоматического Kotlin
* Разделяем состояние и поведения.
* Предпочитаем неизменяемое состояние изменяемому (но без фанатизма).
* Не используем наследование, если оно нужно только для уменьшения дупликации кода. Используем расширения вместо наследования.
* Не создаем классы там, где можно обойтись функцией.
* Используем скоупы для управлением области видимости полей и функций.

View File

@ -4,7 +4,7 @@
* Проверка параметров в публичном конструкторе или в фабричном методе с передачей в приватный конструктор * Проверка параметров в публичном конструкторе или в фабричном методе с передачей в приватный конструктор
* init блок или специальный метод init() в классах и object * init блок или специальный метод init() в классах и object
* Enum VS sealed * Enum VS sealed
* Когда использовать `T.() -> R`, а когда `(T) -> R`, а если два параметра, то `T.(T2) -> R`, `T2.(T) -> R`, или `(T, T2) -> R`
* Обновление кэша
* Выбор обработчика по объекту событию/полю объекта * Выбор обработчика по объекту событию/полю объекта
* Обновление кэша
* Когда использовать `T.() -> R`, а когда `(T) -> R`, а если два параметра, то `T.(T2) -> R`, `T2.(T) -> R`, или `(T, T2) -> R`
* `a.b!! -> a.b ?: error("b should be not a null")` * `a.b!! -> a.b ?: error("b should be not a null")`

View File

@ -0,0 +1,26 @@
class JvmLruCache<K, V>(val cacheSize: Int) : LinkedHashMap<K, V>() {
override fun removeEldestEntry(eldest: MutableMap.MutableEntry<K, V>?): Boolean = size >= cacheSize
}
class KotlinLruCache<K, V>(
val cacheSize: Int,
private val content: HashMap<K, V> = hashMapOf(),
) : MutableMap<K, V> by content {
private var deque = ArrayDeque<K>()
override fun put(key: K, value: V): V? {
val newValue = content.put(key, value)
//if it is a new value
if (newValue == null) {
deque.addLast(key)
while (size > cacheSize) {
val k = deque.removeFirst()
content.remove(k)
}
}
//do not use let here
return newValue
}
}

View File

View File

@ -0,0 +1,14 @@
import kotlin.test.Test
import kotlin.test.assertEquals
class KotlinLruCacheTest {
@Test
fun cacheOverflow() {
val cache = KotlinLruCache<Int, Int>(10)
repeat(12) {
cache[it] = it
}
assertEquals(10, cache.size)
}
}