Add manual invalidation to counter lazies

This commit is contained in:
DBotThePony 2023-08-17 22:55:44 +07:00
parent e6758f1e27
commit 2e4984162b
Signed by: DBot
GPG Key ID: DCC23B5715498507
3 changed files with 35 additions and 9 deletions

View File

@ -7,7 +7,7 @@ import java.util.function.IntSupplier
/**
* If synchronization is not required, [CounterInvalidatedLazy] should be used instead.
*/
class AtomicallyInvalidatedLazy<V>(private val invalidator: IntSupplier, private val initializer: () -> V) : Lazy<V> {
class AtomicallyInvalidatedLazy<V>(private val invalidator: IntSupplier, private val initializer: () -> V) : InvalidableLazy<V> {
constructor(invalidator: AtomicInteger, initializer: () -> V) : this(invalidator::get, initializer)
@Volatile
@ -18,10 +18,7 @@ class AtomicallyInvalidatedLazy<V>(private val invalidator: IntSupplier, private
override val value: V get() {
if (thisCounter != invalidator.asInt) {
lock.lock()
this.stored = Companion
thisCounter = invalidator.asInt
lock.unlock()
invalidate()
}
var stored = stored
@ -40,6 +37,13 @@ class AtomicallyInvalidatedLazy<V>(private val invalidator: IntSupplier, private
}
}
override fun invalidate() {
lock.lock()
this.stored = Companion
thisCounter = invalidator.asInt
lock.unlock()
}
override fun isInitialized(): Boolean {
return stored !== Companion && thisCounter == invalidator.asInt
}

View File

@ -7,9 +7,9 @@ import java.util.function.IntSupplier
/**
* This lazy is not synchronized, so in event of two or more threads accessing value behavior of this implementation is undefined
*
* For synchronized use case, [AtomicallyInvalidatedLazy] should be used
* For thread synchronized use case, [AtomicallyInvalidatedLazy] should be used
*/
fun <V> countingLazy(invalidator: IntSupplier, initializer: () -> V): Lazy<V> {
fun <V> countingLazy(invalidator: IntSupplier, initializer: () -> V): InvalidableLazy<V> {
if (invalidator is IntCounter) {
return SmartCounterInvalidatedLazy(invalidator, initializer)
}
@ -17,12 +17,21 @@ fun <V> countingLazy(invalidator: IntSupplier, initializer: () -> V): Lazy<V> {
return CounterInvalidatedLazy(invalidator, initializer)
}
/**
* This lazy is not synchronized, so in event of two or more threads accessing value behavior of this implementation is undefined
*
* For thread synchronized use case, [AtomicallyInvalidatedLazy] should be used
*/
fun <V> countingLazy(invalidator: AtomicInteger, initializer: () -> V): InvalidableLazy<V> {
return CounterInvalidatedLazy(invalidator, initializer)
}
/**
* This lazy is not synchronized, so in event of two or more threads accessing value behavior of this implementation is undefined
*
* For synchronized use case, [AtomicallyInvalidatedLazy] should be used
*/
class CounterInvalidatedLazy<V>(private val invalidator: IntSupplier, private val initializer: () -> V) : Lazy<V> {
class CounterInvalidatedLazy<V>(private val invalidator: IntSupplier, private val initializer: () -> V) : InvalidableLazy<V> {
constructor(invalidator: AtomicInteger, initializer: () -> V) : this(invalidator::get, initializer)
private var thisCounter = -1
@ -44,6 +53,10 @@ class CounterInvalidatedLazy<V>(private val invalidator: IntSupplier, private va
return stored !== Companion && thisCounter == invalidator.asInt
}
override fun invalidate() {
this.stored = Companion
}
private companion object
}
@ -52,7 +65,7 @@ class CounterInvalidatedLazy<V>(private val invalidator: IntSupplier, private va
*
* For synchronized use case, [AtomicallyInvalidatedLazy] should be used
*/
class SmartCounterInvalidatedLazy<V>(invalidator: IntCounter, private val initializer: () -> V) : Lazy<V> {
class SmartCounterInvalidatedLazy<V>(invalidator: IntCounter, private val initializer: () -> V) : InvalidableLazy<V> {
init {
invalidator.addListener(IntConsumer {
stored = Companion
@ -72,6 +85,10 @@ class SmartCounterInvalidatedLazy<V>(invalidator: IntCounter, private val initia
return stored
}
override fun invalidate() {
this.stored = Companion
}
override fun isInitialized(): Boolean {
return stored !== Companion
}

View File

@ -0,0 +1,5 @@
package ru.dbotthepony.mc.otm.core.util
interface InvalidableLazy<V> : Lazy<V> {
fun invalidate()
}