Update storage system to use hashmap for partitioning
This commit is contained in:
parent
a7d11dae3f
commit
6819866c48
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user