import kotlinx.coroutines.sync.withLock
import java.time.Instant
import java.util.concurrent.ConcurrentHashMap
-import java.util.concurrent.atomic.AtomicLong
-import java.util.concurrent.atomic.AtomicReference
-import kotlin.math.max
val StoragePathAttributeKey = AttributeKey<StoragePath>("Mechyrdia.StoragePath")
abstract class FileDependentCache<T : Any> {
private inner class Entry(updated: Instant?, data: T?) {
- private val updatedAtomic = AtomicLong(updated?.toEpochMilli() ?: Long.MIN_VALUE)
- val updated: Instant
- get() = Instant.ofEpochMilli(updatedAtomic.get())
-
- private val dataAtomic = AtomicReference(data)
- val data: T?
- get() = dataAtomic.get()
+ private var updated: Instant = updated ?: Instant.MIN
+ var data: T? = data
+ private set
private val updateLock = Mutex()
private fun clear() {
- updatedAtomic.set(Long.MIN_VALUE)
- dataAtomic.set(null)
+ updated = Instant.MIN
+ data = null
}
suspend fun updateIfNeeded(path: StoragePath): Entry {
return updateLock.withLock {
- FileStorage.instance.statFile(path)?.updated?.toEpochMilli()?.let { fileUpdated ->
- if (updatedAtomic.getAndUpdate { max(it, fileUpdated) } < fileUpdated)
- dataAtomic.set(processFile(path))
+ FileStorage.instance.statFile(path)?.updated?.let { fileUpdated ->
+ if (updated < fileUpdated) {
+ updated = fileUpdated
+ data = processFile(path)
+ }
this
} ?: apply { clear() }
}