Massively improve memory usage of world tiles
This commit is contained in:
parent
949ed802ad
commit
064689fc25
@ -116,7 +116,7 @@ fun main() {
|
||||
|
||||
val rand = Random()
|
||||
|
||||
for (i in 0 .. 128) {
|
||||
for (i in 0 until 0) {
|
||||
val item = ItemEntity(client.world!!, Registries.items.keys.values.random().value)
|
||||
|
||||
item.position = Vector2d(225.0 - i, 785.0)
|
||||
|
@ -613,7 +613,7 @@ class StarboundClient : Closeable {
|
||||
}
|
||||
|
||||
val tileRenderers = TileRenderers(this)
|
||||
var world: ClientWorld? = ClientWorld(this, 0L, Vector2i(3000, 2000), true)
|
||||
var world: ClientWorld? = ClientWorld(this, 0L, Vector2i(16000, 8000), true)
|
||||
|
||||
init {
|
||||
clearColor = RGBAColor.SLATE_GRAY
|
||||
|
@ -9,11 +9,13 @@ import java.lang.ref.WeakReference
|
||||
import java.util.concurrent.locks.LockSupport
|
||||
import java.util.concurrent.locks.ReentrantLock
|
||||
import kotlin.concurrent.withLock
|
||||
import kotlin.math.log
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
// hand-rolled interner, which has similar performance to ConcurrentHashMap
|
||||
// (given there is no strong congestion, otherwise it performs somewhere above Caffeine interner),
|
||||
// while yielding significantly better memory utilization than both
|
||||
class HashTableInterner<T : Any>(private val segmentBits: Int) : Interner<T> {
|
||||
class HashTableInterner<T : Any>(private val segmentBits: Int = log(Runtime.getRuntime().availableProcessors().toDouble(), 2.0).roundToInt().coerceAtLeast(4)) : Interner<T> {
|
||||
companion object {
|
||||
private val interners = ArrayList<WeakReference<HashTableInterner<*>>>()
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
package ru.dbotthepony.kstarbound.world.api
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Interner
|
||||
import ru.dbotthepony.kstarbound.util.HashTableInterner
|
||||
import java.io.DataInputStream
|
||||
|
||||
sealed class AbstractCell {
|
||||
@ -23,7 +25,10 @@ sealed class AbstractCell {
|
||||
stream.skipNBytes(1 + 2 + 1 + 1 + 1 + 1)
|
||||
}
|
||||
|
||||
val EMPTY = ImmutableCell(AbstractTileState.EMPTY, AbstractTileState.EMPTY, AbstractLiquidState.EMPTY, 0, 0, 0, false)
|
||||
val NULL = ImmutableCell(AbstractTileState.NULL, AbstractTileState.NULL, AbstractLiquidState.EMPTY, 0, 0, 0, false)
|
||||
@JvmStatic
|
||||
protected val POOL: Interner<ImmutableCell> = HashTableInterner()
|
||||
|
||||
val EMPTY: ImmutableCell = POOL.intern(ImmutableCell(AbstractTileState.EMPTY, AbstractTileState.EMPTY, AbstractLiquidState.EMPTY, 0, 0, 0, false))
|
||||
val NULL: ImmutableCell = POOL.intern(ImmutableCell(AbstractTileState.NULL, AbstractTileState.NULL, AbstractLiquidState.EMPTY, 0, 0, 0, false))
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
package ru.dbotthepony.kstarbound.world.api
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Interner
|
||||
import ru.dbotthepony.kstarbound.Registry
|
||||
import ru.dbotthepony.kstarbound.defs.tile.BuiltinMetaMaterials
|
||||
import ru.dbotthepony.kstarbound.defs.tile.MaterialModifier
|
||||
import ru.dbotthepony.kstarbound.defs.tile.TileDefinition
|
||||
import ru.dbotthepony.kstarbound.util.HashTableInterner
|
||||
import java.io.DataInputStream
|
||||
|
||||
sealed class AbstractTileState {
|
||||
@ -21,7 +23,10 @@ sealed class AbstractTileState {
|
||||
stream.skipNBytes(2 + 1 + 1 + 2 + 1)
|
||||
}
|
||||
|
||||
val EMPTY = ImmutableTileState(BuiltinMetaMaterials.EMPTY)
|
||||
val NULL = ImmutableTileState(BuiltinMetaMaterials.NULL)
|
||||
@JvmStatic
|
||||
protected val POOL: Interner<ImmutableTileState> = HashTableInterner()
|
||||
|
||||
val EMPTY: ImmutableTileState = POOL.intern(ImmutableTileState(BuiltinMetaMaterials.EMPTY))
|
||||
val NULL: ImmutableTileState = POOL.intern(ImmutableTileState(BuiltinMetaMaterials.NULL))
|
||||
}
|
||||
}
|
||||
|
@ -29,10 +29,7 @@ data class MutableCell(
|
||||
}
|
||||
|
||||
override fun immutable(): ImmutableCell {
|
||||
val result = ImmutableCell(foreground.immutable(), background.immutable(), liquid.immutable(), dungeonId, biome, envBiome, isIndestructible)
|
||||
if (result == NULL) return NULL
|
||||
if (result == EMPTY) return EMPTY
|
||||
return result
|
||||
return POOL.intern(ImmutableCell(foreground.immutable(), background.immutable(), liquid.immutable(), dungeonId, biome, envBiome, isIndestructible))
|
||||
}
|
||||
|
||||
override fun mutable(): MutableCell {
|
||||
|
@ -15,10 +15,7 @@ data class MutableTileState(
|
||||
override var modifierHueShift: Float = 0f,
|
||||
) : AbstractTileState() {
|
||||
override fun immutable(): ImmutableTileState {
|
||||
val result = ImmutableTileState(material, modifier, color, hueShift, modifierHueShift)
|
||||
if (result == NULL) return NULL
|
||||
if (result == EMPTY) return EMPTY
|
||||
return result
|
||||
return POOL.intern(ImmutableTileState(material, modifier, color, hueShift, modifierHueShift))
|
||||
}
|
||||
|
||||
override fun mutable(): MutableTileState {
|
||||
|
Loading…
Reference in New Issue
Block a user