From 2e4984162b6bf40b492748d64de0659a41c63b7e Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Thu, 17 Aug 2023 22:55:44 +0700 Subject: [PATCH] Add manual invalidation to counter lazies --- .../core/util/AtomicallyInvalidatedLazy.kt | 14 +++++++---- .../otm/core/util/CounterInvalidatedLazy.kt | 25 ++++++++++++++++--- .../mc/otm/core/util/InvalidableLazy.kt | 5 ++++ 3 files changed, 35 insertions(+), 9 deletions(-) create mode 100644 src/main/kotlin/ru/dbotthepony/mc/otm/core/util/InvalidableLazy.kt diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/AtomicallyInvalidatedLazy.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/AtomicallyInvalidatedLazy.kt index 76b16fe62..d8c7c0593 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/AtomicallyInvalidatedLazy.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/AtomicallyInvalidatedLazy.kt @@ -7,7 +7,7 @@ import java.util.function.IntSupplier /** * If synchronization is not required, [CounterInvalidatedLazy] should be used instead. */ -class AtomicallyInvalidatedLazy(private val invalidator: IntSupplier, private val initializer: () -> V) : Lazy { +class AtomicallyInvalidatedLazy(private val invalidator: IntSupplier, private val initializer: () -> V) : InvalidableLazy { constructor(invalidator: AtomicInteger, initializer: () -> V) : this(invalidator::get, initializer) @Volatile @@ -18,10 +18,7 @@ class AtomicallyInvalidatedLazy(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(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 } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/CounterInvalidatedLazy.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/CounterInvalidatedLazy.kt index eb277cdc3..aa398a7fd 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/CounterInvalidatedLazy.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/CounterInvalidatedLazy.kt @@ -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 countingLazy(invalidator: IntSupplier, initializer: () -> V): Lazy { +fun countingLazy(invalidator: IntSupplier, initializer: () -> V): InvalidableLazy { if (invalidator is IntCounter) { return SmartCounterInvalidatedLazy(invalidator, initializer) } @@ -17,12 +17,21 @@ fun countingLazy(invalidator: IntSupplier, initializer: () -> V): Lazy { 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 countingLazy(invalidator: AtomicInteger, initializer: () -> V): InvalidableLazy { + 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(private val invalidator: IntSupplier, private val initializer: () -> V) : Lazy { +class CounterInvalidatedLazy(private val invalidator: IntSupplier, private val initializer: () -> V) : InvalidableLazy { constructor(invalidator: AtomicInteger, initializer: () -> V) : this(invalidator::get, initializer) private var thisCounter = -1 @@ -44,6 +53,10 @@ class CounterInvalidatedLazy(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(private val invalidator: IntSupplier, private va * * For synchronized use case, [AtomicallyInvalidatedLazy] should be used */ -class SmartCounterInvalidatedLazy(invalidator: IntCounter, private val initializer: () -> V) : Lazy { +class SmartCounterInvalidatedLazy(invalidator: IntCounter, private val initializer: () -> V) : InvalidableLazy { init { invalidator.addListener(IntConsumer { stored = Companion @@ -72,6 +85,10 @@ class SmartCounterInvalidatedLazy(invalidator: IntCounter, private val initia return stored } + override fun invalidate() { + this.stored = Companion + } + override fun isInitialized(): Boolean { return stored !== Companion } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/InvalidableLazy.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/InvalidableLazy.kt new file mode 100644 index 000000000..f6c16c449 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/InvalidableLazy.kt @@ -0,0 +1,5 @@ +package ru.dbotthepony.mc.otm.core.util + +interface InvalidableLazy : Lazy { + fun invalidate() +}