From 4c8b6b7c64bc432f03529d71c06b238f780013da Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Mon, 9 Oct 2023 20:28:48 +0300 Subject: [PATCH] Add cache implementation --- idiomatic.md | 12 ++++++++++++ questions.md | 4 ++-- src/main/kotlin/JvmLruCache.kt | 26 ++++++++++++++++++++++++++ src/main/kotlin/dataProcessing.kt | 0 src/test/kotlin/KotlinLruCacheTest.kt | 14 ++++++++++++++ 5 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 idiomatic.md create mode 100644 src/main/kotlin/JvmLruCache.kt create mode 100644 src/main/kotlin/dataProcessing.kt create mode 100644 src/test/kotlin/KotlinLruCacheTest.kt diff --git a/idiomatic.md b/idiomatic.md new file mode 100644 index 0000000..9f5f37d --- /dev/null +++ b/idiomatic.md @@ -0,0 +1,12 @@ +## Что такое "идиоматический"? + +* Написанный при помощи [идиом](https://kotlinlang.org/docs/idioms.html). +* Использующий специфическую для Kotlin гибридную "парадигму" построения программы. + +## Совершенно неофициальный манифест идиоматического Kotlin + +* Разделяем состояние и поведения. +* Предпочитаем неизменяемое состояние изменяемому (но без фанатизма). +* Не используем наследование, если оно нужно только для уменьшения дупликации кода. Используем расширения вместо наследования. +* Не создаем классы там, где можно обойтись функцией. +* Используем скоупы для управлением области видимости полей и функций. \ No newline at end of file diff --git a/questions.md b/questions.md index 71167c2..576c630 100644 --- a/questions.md +++ b/questions.md @@ -4,7 +4,7 @@ * Проверка параметров в публичном конструкторе или в фабричном методе с передачей в приватный конструктор * init блок или специальный метод init() в классах и object * 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")` \ No newline at end of file diff --git a/src/main/kotlin/JvmLruCache.kt b/src/main/kotlin/JvmLruCache.kt new file mode 100644 index 0000000..4eed6d4 --- /dev/null +++ b/src/main/kotlin/JvmLruCache.kt @@ -0,0 +1,26 @@ +class JvmLruCache(val cacheSize: Int) : LinkedHashMap() { + override fun removeEldestEntry(eldest: MutableMap.MutableEntry?): Boolean = size >= cacheSize +} + + +class KotlinLruCache( + val cacheSize: Int, + private val content: HashMap = hashMapOf(), +) : MutableMap by content { + + private var deque = ArrayDeque() + + 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 + } +} diff --git a/src/main/kotlin/dataProcessing.kt b/src/main/kotlin/dataProcessing.kt new file mode 100644 index 0000000..e69de29 diff --git a/src/test/kotlin/KotlinLruCacheTest.kt b/src/test/kotlin/KotlinLruCacheTest.kt new file mode 100644 index 0000000..f4e701f --- /dev/null +++ b/src/test/kotlin/KotlinLruCacheTest.kt @@ -0,0 +1,14 @@ +import kotlin.test.Test +import kotlin.test.assertEquals + +class KotlinLruCacheTest { + @Test + fun cacheOverflow() { + val cache = KotlinLruCache(10) + repeat(12) { + cache[it] = it + } + + assertEquals(10, cache.size) + } +} \ No newline at end of file