mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-10 18:44:05 +09:00
using proper hashing function
This commit is contained in:
@@ -8,7 +8,7 @@ import sun.misc.Unsafe
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
object UnsafeHelper {
|
object UnsafeHelper {
|
||||||
internal val unsafe: Unsafe
|
val unsafe: Unsafe
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val unsafeConstructor = Unsafe::class.java.getDeclaredConstructor()
|
val unsafeConstructor = Unsafe::class.java.getDeclaredConstructor()
|
||||||
|
|||||||
79
src/net/torvald/random/XXHash32.java
Normal file
79
src/net/torvald/random/XXHash32.java
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
package net.torvald.random;
|
||||||
|
|
||||||
|
import net.torvald.UnsafeHelper;
|
||||||
|
import net.torvald.terrarum.AppLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Code from https://richardstartin.github.io/posts/xxhash
|
||||||
|
* https://github.com/richardstartin/xxhash-benchmark
|
||||||
|
* Created by minjaesong on 2020-02-24
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class XXHash32 {
|
||||||
|
|
||||||
|
static final int PRIME1 = 0x9E3779B1;
|
||||||
|
static final int PRIME2 = 0x85EBCA77;
|
||||||
|
static final int PRIME3 = 0xC2B2AE3D;
|
||||||
|
static final int PRIME4 = 0x27D4EB2F;
|
||||||
|
static final int PRIME5 = 0x165667B1;
|
||||||
|
|
||||||
|
static final int ARRAY_ELEM_OFFSET = (AppLoader.is32BitJVM) ? 8 : 16;
|
||||||
|
|
||||||
|
public static int hash(byte[] data, int seed) {
|
||||||
|
int end = data.length;
|
||||||
|
int offset = 0;
|
||||||
|
int h32;
|
||||||
|
if (data.length >= 16) {
|
||||||
|
int limit = end - 16;
|
||||||
|
int v1 = seed + PRIME1 + PRIME2;
|
||||||
|
int v2 = seed + PRIME2;
|
||||||
|
int v3 = seed;
|
||||||
|
int v4 = seed - PRIME1;
|
||||||
|
|
||||||
|
do {
|
||||||
|
v1 += getInt(data, offset) * PRIME2;
|
||||||
|
v1 = Integer.rotateLeft(v1, 13);
|
||||||
|
v1 *= PRIME1;
|
||||||
|
offset += 4;
|
||||||
|
v2 += getInt(data, offset) * PRIME2;
|
||||||
|
v2 = Integer.rotateLeft(v2, 13);
|
||||||
|
v2 *= PRIME1;
|
||||||
|
offset += 4;
|
||||||
|
v3 += getInt(data, offset) * PRIME2;
|
||||||
|
v3 = Integer.rotateLeft(v3, 13);
|
||||||
|
v3 *= PRIME1;
|
||||||
|
offset += 4;
|
||||||
|
v4 += getInt(data, offset) * PRIME2;
|
||||||
|
v4 = Integer.rotateLeft(v4, 13);
|
||||||
|
v4 *= PRIME1;
|
||||||
|
offset += 4;
|
||||||
|
} while(offset <= limit);
|
||||||
|
|
||||||
|
h32 = Integer.rotateLeft(v1, 1) + Integer.rotateLeft(v2, 7) + Integer.rotateLeft(v3, 12) + Integer.rotateLeft(v4, 18);
|
||||||
|
} else {
|
||||||
|
h32 = seed + PRIME5;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(h32 += data.length; offset <= end - 4; offset += 4) {
|
||||||
|
h32 += getInt(data, offset) * PRIME3;
|
||||||
|
h32 = Integer.rotateLeft(h32, 17) * PRIME4;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(offset < end) {
|
||||||
|
h32 += (data[offset] & 255) * PRIME5;
|
||||||
|
h32 = Integer.rotateLeft(h32, 11) * PRIME1;
|
||||||
|
++offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
h32 ^= h32 >>> 15;
|
||||||
|
h32 *= PRIME2;
|
||||||
|
h32 ^= h32 >>> 13;
|
||||||
|
h32 *= PRIME3;
|
||||||
|
h32 ^= h32 >>> 16;
|
||||||
|
return h32;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static int getInt(byte[] data, int offset) {
|
||||||
|
return UnsafeHelper.INSTANCE.getUnsafe().getInt(data, offset + ARRAY_ELEM_OFFSET);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
package net.torvald.terrarum.blockproperties
|
package net.torvald.terrarum.blockproperties
|
||||||
|
|
||||||
import net.torvald.gdx.graphics.Cvec
|
import net.torvald.gdx.graphics.Cvec
|
||||||
|
import net.torvald.random.XXHash32
|
||||||
import net.torvald.terrarum.gameworld.fmod
|
import net.torvald.terrarum.gameworld.fmod
|
||||||
|
import net.torvald.terrarum.serialise.toLittle
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2016-02-16.
|
* Created by minjaesong on 2016-02-16.
|
||||||
@@ -58,8 +60,8 @@ class BlockProp {
|
|||||||
fun getLumCol(x: Int, y: Int) = if (dynamicLuminosityFunction == 0) {
|
fun getLumCol(x: Int, y: Int) = if (dynamicLuminosityFunction == 0) {
|
||||||
baseLumCol
|
baseLumCol
|
||||||
} else {
|
} else {
|
||||||
val offset = (x * 214013 + 2531011).ushr(16).fmod(BlockCodex.DYNAMIC_RANDOM_CASES)
|
val offset = XXHash32.hash(((x and 0xFFFF).shl(16) or (y and 0xFFFF)).toLittle(), 10000)
|
||||||
BlockCodex[BlockCodex.dynamicToVirtualMap[id]!! - offset]._lumCol
|
BlockCodex[BlockCodex.dynamicToVirtualMap[id]!! - offset.fmod(BlockCodex.DYNAMIC_RANDOM_CASES)]._lumCol
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
package net.torvald.terrarum.tests
|
package net.torvald.terrarum.tests
|
||||||
|
|
||||||
import net.torvald.random.HQRNG
|
import net.torvald.random.HQRNG
|
||||||
|
import net.torvald.random.XXHash32
|
||||||
|
import net.torvald.terrarum.blockproperties.BlockCodex
|
||||||
|
import net.torvald.terrarum.gameworld.fmod
|
||||||
|
import net.torvald.terrarum.serialise.toLittle
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -20,7 +24,7 @@ fun main(args: Array<String>) {
|
|||||||
|
|
||||||
println()
|
println()
|
||||||
|
|
||||||
val rng2 = com.sudoplay.joise.generator.HQRNG()
|
/*val rng2 = com.sudoplay.joise.generator.HQRNG()
|
||||||
|
|
||||||
repeat(512) {
|
repeat(512) {
|
||||||
println(rng2.getRange(0, 10))
|
println(rng2.getRange(0, 10))
|
||||||
@@ -29,4 +33,24 @@ fun main(args: Array<String>) {
|
|||||||
// getTarget: 0..(t-1) (exclusive)
|
// getTarget: 0..(t-1) (exclusive)
|
||||||
// getRange: low..high (inclusive)
|
// getRange: low..high (inclusive)
|
||||||
// get01: 0.0 until 1.0 (exclusive)
|
// get01: 0.0 until 1.0 (exclusive)
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for (tries in 0 until 16) {
|
||||||
|
repeat(BlockCodex.DYNAMIC_RANDOM_CASES + 12) { repeats ->
|
||||||
|
val x = 349 + repeats
|
||||||
|
val y = 9492 + tries
|
||||||
|
|
||||||
|
|
||||||
|
val offset = XXHash32.hash(((x and 0xFFFF).shl(16) or (y and 0xFFFF)).toLittle(), 10000)
|
||||||
|
|
||||||
|
//print("${offset.toString().padStart(2, '0')} ")
|
||||||
|
print("${offset.fmod(BlockCodex.DYNAMIC_RANDOM_CASES).toString().padStart(2, '0')} ")
|
||||||
|
}
|
||||||
|
println()
|
||||||
|
println()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user