From 7b317a2efb9a41fdc9d6489680013ee789020dc7 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Thu, 3 Aug 2023 17:25:01 +0700 Subject: [PATCH] CoW non empty indices in container --- .../mc/otm/container/MatteryContainer.kt | 59 ++++++++++++++++--- 1 file changed, 52 insertions(+), 7 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryContainer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryContainer.kt index a18991525..5a285fbe3 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryContainer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryContainer.kt @@ -26,10 +26,14 @@ import ru.dbotthepony.mc.otm.core.util.ItemValueCodec import ru.dbotthepony.mc.otm.core.util.VarIntValueCodec import ru.dbotthepony.mc.otm.network.synchronizer.FieldSynchronizer import ru.dbotthepony.mc.otm.network.synchronizer.IField +import java.lang.ref.PhantomReference +import java.lang.ref.ReferenceQueue import java.lang.ref.WeakReference import java.util.* +import java.util.concurrent.CopyOnWriteArrayList import java.util.function.Supplier import kotlin.NoSuchElementException +import kotlin.collections.ArrayList @Suppress("UNUSED") open class MatteryContainer(protected val watcher: Runnable, private val size: Int) : Container, Iterable, INBTSerializable { @@ -41,7 +45,16 @@ open class MatteryContainer(protected val watcher: Runnable, private val size: I private val slots = Array(size) { ItemStack.EMPTY } private val nonEmptyFlags = BitSet() - private val nonEmptyIndices = IntArrayList() + private var nonEmptyIndices = IntArrayList() + private var indicesReferences = 0 + + private fun cowIndices() { + if (indicesReferences != 0) { + nonEmptyIndices = IntArrayList(nonEmptyIndices) + indicesReferences = 0 + } + } + private val trackedSlots: Array = Array(size) { ItemStack.EMPTY } private val filters: Array = arrayOfNulls(size) private var filterSynchronizer: WeakReference>>? = null @@ -196,7 +209,7 @@ open class MatteryContainer(protected val watcher: Runnable, private val size: I Arrays.fill(slots, ItemStack.EMPTY) Arrays.fill(filters, null) nonEmptyFlags.clear() - nonEmptyIndices.clear() + nonEmptyIndices = IntArrayList() filterSynchronizer?.get()?.value?.clear() @@ -468,11 +481,13 @@ open class MatteryContainer(protected val watcher: Runnable, private val size: I if (slots[slot].isEmpty) { if (nonEmptyFlags[slot]) { nonEmptyFlags[slot] = false - nonEmptyIndices.removeInt(slot) + cowIndices() + nonEmptyIndices.rem(slot) } } else { if (!nonEmptyFlags[slot]) { nonEmptyFlags[slot] = true + cowIndices() nonEmptyIndices.addSorted(slot, IntComparators.NATURAL_COMPARATOR) } } @@ -484,7 +499,7 @@ open class MatteryContainer(protected val watcher: Runnable, private val size: I final override fun clearContent() { nonEmptyFlags.clear() - nonEmptyIndices.clear() + nonEmptyIndices = IntArrayList() Arrays.fill(trackedSlots, ItemStack.EMPTY) @@ -497,7 +512,11 @@ open class MatteryContainer(protected val watcher: Runnable, private val size: I } } - private inner class Iterator : MutableIterator { + private inner class Iterator : IContainerIterator { + init { + indicesReferences++ + } + private val parent = nonEmptyIndices.intIterator() private var lastIndex = -1 @@ -519,11 +538,37 @@ open class MatteryContainer(protected val watcher: Runnable, private val size: I setItem(lastIndex, ItemStack.EMPTY) lastIndex = -1 } + + override fun setChanged() { + if (lastIndex == -1) { + throw NoSuchElementException() + } + + setChanged(lastIndex) + } } - final override fun iterator(): MutableIterator { + private object EmptyIterator : IContainerIterator { + override fun hasNext(): Boolean { + return false + } + + override fun next(): ItemStack { + throw NoSuchElementException() + } + + override fun remove() { + throw NoSuchElementException() + } + + override fun setChanged() { + throw NoSuchElementException() + } + } + + final override fun iterator(): IContainerIterator { if (isEmpty) { - return ObjectIterators.EMPTY_ITERATOR as MutableIterator + return EmptyIterator } return Iterator()