diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/client/StarboundClient.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/client/StarboundClient.kt index c9cb3d3a..8f19fc62 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/client/StarboundClient.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/client/StarboundClient.kt @@ -613,7 +613,7 @@ class StarboundClient : Closeable { } val tileRenderers = TileRenderers(this) - var world: ClientWorld? = ClientWorld(this, 0L, Vector2i(16000, 8000), true) + var world: ClientWorld? = ClientWorld(this, 0L, Vector2i(3000, 2000), true) init { clearColor = RGBAColor.SLATE_GRAY diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/util/HashTableInterner.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/util/HashTableInterner.kt index d6fdafb2..60a45470 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/util/HashTableInterner.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/util/HashTableInterner.kt @@ -147,9 +147,10 @@ class HashTableInterner(private val segmentBits: Int = log(Runtime.getR val mask = size - 1 val mem = arrayOfNulls>(size) var stored = 0 + var collisions = 0 private fun hash(e: Any): Int { - return HashCommon.mix(e.hashCode().rotateRight(segmentBits)) and mask + return HashCommon.mix(e.hashCode()).rotateRight(segmentBits) and mask } fun remove(ref: Ref): Boolean { @@ -161,11 +162,15 @@ class HashTableInterner(private val segmentBits: Int = log(Runtime.getR return false } else if (search === ref) { mem[hash] = search.nextEntry + if (mem[hash] != null) check(--collisions >= 0) { "Collision count turned negative" } check(--stored >= 0) { "Stored count turned negative" } return true } else { return search.remove(ref).also { - if (it) check(--stored >= 0) { "Stored count turned negative" } + if (it) { + check(--stored >= 0) { "Stored count turned negative" } + check(--collisions >= 0) { "Collision count turned negative" } + } } } } @@ -179,8 +184,10 @@ class HashTableInterner(private val segmentBits: Int = log(Runtime.getR if (existing == null) mem[hash] = ref - else + else { existing.insert(ref) + collisions++ + } } fun cleanup(): Int { @@ -212,10 +219,9 @@ class HashTableInterner(private val segmentBits: Int = log(Runtime.getR return new } - fun search(sample: T): T? { + fun search(sample: T, hash: Int): T? { val mem = mem - val hash = hash(sample) - var search = mem[hash] + var search = mem[hash and mask] while (search != null) { val get = search.get() @@ -231,17 +237,18 @@ class HashTableInterner(private val segmentBits: Int = log(Runtime.getR } override fun intern(sample: T): T { - val hash = HashCommon.mix(sample.hashCode()) + var hash = HashCommon.mix(sample.hashCode()) val segmentIndex = hash and actualSegmentBits var segment = segments[segmentIndex] - val find = segment.search(sample) + hash = hash.rotateRight(segmentBits) + val find = segment.search(sample, hash) if (find != null) return find locks[segmentIndex].withLock { segment = segments[segmentIndex] - val find = segment.search(sample) + val find = segment.search(sample, hash) if (find != null) return find if (segment.stored >= segment.mem.size * 0.75f) { diff --git a/src/test/kotlin/ru/dbotthepony/kstarbound/test/InternerTest.kt b/src/test/kotlin/ru/dbotthepony/kstarbound/test/InternerTest.kt index 2ae4cd25..8097f850 100644 --- a/src/test/kotlin/ru/dbotthepony/kstarbound/test/InternerTest.kt +++ b/src/test/kotlin/ru/dbotthepony/kstarbound/test/InternerTest.kt @@ -23,6 +23,8 @@ object InternerTest { val s1 = "String$v" val s2 = "String$v" + check(s1 !== s2) + if (interner.intern(s1) !== interner.intern(s2)) { misses.incrementAndGet() }