package dev.inmo.micro_utils.repos.cache.cache import dev.inmo.micro_utils.pagination.utils.getAllWithNextPaging import dev.inmo.micro_utils.repos.* import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock open class SimpleKVCache( protected val cachedValuesCount: Int, private val kvParent: KeyValueRepo = MapKeyValueRepo() ) : KVCache, KeyValueRepo by kvParent { protected open val cacheQueue = ArrayDeque(cachedValuesCount) protected val syncMutex = Mutex() protected suspend fun makeUnset(toUnset: List) { cacheQueue.removeAll(toUnset) kvParent.unset(toUnset) } override suspend fun set(toSet: Map) { syncMutex.withLock { for ((k, v) in toSet) { if (cacheQueue.size >= cachedValuesCount) { cacheQueue.removeFirstOrNull() ?.let { kvParent.unset(it) } } cacheQueue.addLast(k) kvParent.set(k, v) } } } override suspend fun unset(toUnset: List) { syncMutex.withLock { makeUnset(toUnset) } } } inline fun KVCache( cachedValuesCount: Int, kvParent: KeyValueRepo = MapKeyValueRepo() ) = SimpleKVCache(cachedValuesCount, kvParent)