package com.ustadmobile.libcache.util import com.ustadmobile.door.util.systemTimeInMillis import java.util.function.BiFunction /** * Basic implementation of a Least Recently Used map to run a memory cache */ class LruMap( private val delegate: MutableMap, private val maxItems: Int = 5_000, ): MutableMap by delegate { private val accessTimeMap: MutableMap = concurrentSafeMapOf() private fun trimIfNeeded() { if(size > maxItems) { val numItemsToDelete = maxItems - size val itemsToDelete = accessTimeMap.entries.sortedBy { it.value }.subList(0, numItemsToDelete) itemsToDelete.forEach { remove(it.key) accessTimeMap.remove(it.key) } } } override fun put(key: K, value: V): V? { accessTimeMap[key] = systemTimeInMillis() return delegate.put(key, value).also { trimIfNeeded() } } override fun putAll(from: Map) { from.forEach { accessTimeMap[it.key] = systemTimeInMillis() } return delegate.putAll(from).also { trimIfNeeded() } } override fun putIfAbsent(key: K, value: V): V? { accessTimeMap[key] = systemTimeInMillis() return delegate.putIfAbsent(key, value).also { trimIfNeeded() } } override fun get(key: K): V? { accessTimeMap[key] = systemTimeInMillis() return delegate.get(key).also { trimIfNeeded() } } override fun compute(key: K, remappingFunction: BiFunction): V? { return delegate.compute(key, remappingFunction).also { trimIfNeeded() } } }