Update storage system to use hashmap for partitioning

This commit is contained in:
DBotThePony 2022-04-26 15:16:25 +07:00
parent a7d11dae3f
commit 6819866c48
4 changed files with 41 additions and 41 deletions

View File

@ -1,8 +1,6 @@
package ru.dbotthepony.mc.otm.block.entity
import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap
import it.unimi.dsi.fastutil.longs.Long2ObjectAVLTreeMap
import it.unimi.dsi.fastutil.longs.Long2ObjectFunction
import it.unimi.dsi.fastutil.objects.Object2ObjectAVLTreeMap
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
@ -72,7 +70,7 @@ private class ItemHandlerComponent(private val parent: IItemHandler) : IStorageC
private var scanned = arrayOfNulls<ItemStack>(0)
private var scannedMap = arrayOfNulls<TrackedTuple>(0)
private val partitioned = Long2ObjectAVLTreeMap<ArrayList<TrackedTuple>>()
private val tuples = HashMap<ItemStackWrapper, TrackedTuple>()
private val index = Object2ObjectAVLTreeMap<UUID, TrackedTuple>()
private fun removeTracked(slot: Int) {
@ -96,15 +94,8 @@ private class ItemHandlerComponent(private val parent: IItemHandler) : IStorageC
index.remove(scannedMap.id)
val listing = partitioned[scannedMap.stack.longHashCode] ?: throw IllegalStateException("Item listing is not present for ${scannedMap.stack}")
if (listing.remove(scannedMap)) {
if (listing.isEmpty()) {
partitioned.remove(scannedMap.stack.longHashCode)
}
} else {
throw IllegalStateException("Item listing for ${scannedMap.stack} did not contain $scannedMap")
}
val key = scannedMap.stack.key()
tuples.remove(key) ?: throw IllegalStateException("Item tuple is not present for slot $slot at ${scannedMap.stack}")
}
}
@ -124,24 +115,16 @@ private class ItemHandlerComponent(private val parent: IItemHandler) : IStorageC
private fun addTracked(slot: Int, stack: ItemStack) {
check(scannedMap[slot] == null) { "Already tracking slot $slot" }
val listing = partitioned.computeIfAbsent(ItemStackWrapper.longHashCode(stack.item), Long2ObjectFunction { ArrayList() })
var tuple: TrackedTuple? = null
for (storedTuple in listing) {
if (storedTuple.stack.sameItem(stack)) {
tuple = storedTuple
break
}
}
val storageStack = ItemStackWrapper(stack)
val key = storageStack.key()
var tuple: TrackedTuple? = tuples[key]
val added = tuple == null
var oldCount = ImpreciseFraction.ZERO
if (added) {
val storageStack = ItemStackWrapper(stack)
tuple = TrackedTuple(storageStack, UUID.randomUUID())
index[tuple.id] = tuple
listing.add(tuple)
tuples[key] = tuple
} else {
oldCount = tuple!!.stack.count
tuple.stack.count += stack.count

View File

@ -20,9 +20,9 @@ interface IItemMatteryDrive : IMatteryDrive<ItemStackWrapper> {
/**
* @param stack
* @return all items that match this itemstack
* @return [ItemStack] that match specified [stack] (item type, nbt tag)
*/
fun findItems(stack: ItemStack): Collection<IStorageTuple<ItemStackWrapper>>
fun findItems(stack: ItemStack): IStorageTuple<ItemStackWrapper>?
}
interface IItemViewListener {

View File

@ -12,7 +12,9 @@ import ru.dbotthepony.mc.otm.set
import ru.dbotthepony.mc.otm.storage.IStorageTuple
import ru.dbotthepony.mc.otm.storage.ItemStackWrapper
import ru.dbotthepony.mc.otm.storage.StorageStackType
import ru.dbotthepony.mc.otm.storage.key
import java.util.*
import kotlin.collections.ArrayList
class ItemMatteryDrive : AbstractMatteryDrive<ItemStackWrapper>, IItemMatteryDrive {
constructor(capacity: ImpreciseFraction, max_different_stacks: Int) : super(capacity, maxDifferentStacks = max_different_stacks)
@ -56,22 +58,19 @@ class ItemMatteryDrive : AbstractMatteryDrive<ItemStackWrapper>, IItemMatteryDri
}
override fun findItems(item: Item): List<IStorageTuple<ItemStackWrapper>> {
val list = tuples[ItemStackWrapper.longHashCode(item)]
return if (list != null) java.util.List.copyOf(list) else emptyList()
}
val list = ArrayList<IStorageTuple<ItemStackWrapper>>()
override fun findItems(stack: ItemStack): List<IStorageTuple<ItemStackWrapper>> {
val list = tuples[ItemStackWrapper.longHashCode(stack.item)] ?: return emptyList()
val buildList = ArrayList<IStorageTuple<ItemStackWrapper>>()
for (_stack in list) {
if (_stack.stack.sameItem(stack)) {
buildList.add(_stack)
for ((key, value) in tuples.entries) {
if (key.item.item === item) {
list.add(value)
}
}
return buildList
return list
}
override fun findItems(stack: ItemStack): IStorageTuple<ItemStackWrapper>? {
return tuples[ItemStackWrapper(stack).key()]
}
companion object {

View File

@ -4,6 +4,7 @@ import net.minecraft.world.item.Item
import net.minecraft.world.item.ItemStack
import net.minecraftforge.registries.ForgeRegistries
import net.minecraftforge.registries.ForgeRegistry
import org.jetbrains.annotations.ApiStatus
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
/**
@ -15,6 +16,7 @@ class ItemStackWrapper : IStorageStack {
*
* In most cases you want to use [stack] instead.
*/
@ApiStatus.Internal
val item: ItemStack
val registryName get() = item.item.registryName!!
private val hash: Int
@ -22,10 +24,24 @@ class ItemStackWrapper : IStorageStack {
override var count: ImpreciseFraction
set(value) { field = value.floor() }
constructor(item: ItemStack) {
/**
* [copy] as false is used internally for fast index construction, do not specify
* it unless you know what you are doing!
*/
@JvmOverloads
constructor(item: ItemStack, copy: Boolean = true) {
if (copy) {
this.item = item.copy()
} else {
this.item = item
}
this.count = ImpreciseFraction(item.count)
if (copy) {
this.item.count = 1
}
this.hash = item.tag.hashCode() xor item.item.hashCode()
}
@ -40,6 +56,8 @@ class ItemStackWrapper : IStorageStack {
return ItemStackWrapper(this)
}
fun sameItem(other: ItemStack) = ItemStack.isSameItemSameTags(item, other)
override fun equals(other: Any?): Boolean {
if (other === this)
return true