mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-03 11:17:05 -04:00
(Probably) better hashGeneric
(#1187)
* Make hash function more complicated * Change seed value for array and vector hashes * Fix formatting issues * Fix formatting issues * Update src/server/terrain/biomes.zig
This commit is contained in:
parent
b13e835a21
commit
0472091d7c
@ -142,16 +142,22 @@ const Stripe = struct { // MARK: Stripe
|
|||||||
fn hashGeneric(input: anytype) u64 {
|
fn hashGeneric(input: anytype) u64 {
|
||||||
const T = @TypeOf(input);
|
const T = @TypeOf(input);
|
||||||
return switch(@typeInfo(T)) {
|
return switch(@typeInfo(T)) {
|
||||||
.bool => @intFromBool(input),
|
.bool => hashCombine(hashInt(@intFromBool(input)), 0xbf58476d1ce4e5b9),
|
||||||
.@"enum" => @intFromEnum(input),
|
.@"enum" => hashCombine(hashInt(@as(u64, @intFromEnum(input))), 0x94d049bb133111eb),
|
||||||
.int, .float => @as(std.meta.Int(.unsigned, @bitSizeOf(T)), @bitCast(input)),
|
.int, .float => blk: {
|
||||||
|
const value = @as(std.meta.Int(.unsigned, @bitSizeOf(T)), @bitCast(input));
|
||||||
|
break :blk hashInt(@as(u64, value));
|
||||||
|
},
|
||||||
.@"struct" => blk: {
|
.@"struct" => blk: {
|
||||||
if(@hasDecl(T, "getHash")) {
|
if(@hasDecl(T, "getHash")) {
|
||||||
break :blk input.getHash();
|
break :blk input.getHash();
|
||||||
}
|
}
|
||||||
var result: u64 = 0;
|
var result: u64 = hashGeneric(@typeName(T));
|
||||||
inline for(@typeInfo(T).@"struct".fields) |field| {
|
inline for(@typeInfo(T).@"struct".fields) |field| {
|
||||||
result ^= hashGeneric(@field(input, field.name))*%hashGeneric(@as([]const u8, field.name));
|
const keyHash = hashGeneric(@as([]const u8, field.name));
|
||||||
|
const valueHash = hashGeneric(@field(input, field.name));
|
||||||
|
const keyValueHash = hashCombine(keyHash, valueHash);
|
||||||
|
result = hashCombine(result, keyValueHash);
|
||||||
}
|
}
|
||||||
break :blk result;
|
break :blk result;
|
||||||
},
|
},
|
||||||
@ -164,25 +170,28 @@ fn hashGeneric(input: anytype) u64 {
|
|||||||
break :blk hashGeneric(input.*);
|
break :blk hashGeneric(input.*);
|
||||||
},
|
},
|
||||||
.slice => blk: {
|
.slice => blk: {
|
||||||
var result: u64 = 0;
|
var result: u64 = hashInt(input.len);
|
||||||
for(input) |val| {
|
for(input) |val| {
|
||||||
result = result*%33 +% hashGeneric(val);
|
const valueHash = hashGeneric(val);
|
||||||
|
result = hashCombine(result, valueHash);
|
||||||
}
|
}
|
||||||
break :blk result;
|
break :blk result;
|
||||||
},
|
},
|
||||||
else => @compileError("Unsupported type " ++ @typeName(T)),
|
else => @compileError("Unsupported type " ++ @typeName(T)),
|
||||||
},
|
},
|
||||||
.array => blk: {
|
.array => blk: {
|
||||||
var result: u64 = 0;
|
var result: u64 = 0xbf58476d1ce4e5b9;
|
||||||
for(input) |val| {
|
for(input) |val| {
|
||||||
result = result*%33 +% hashGeneric(val);
|
const valueHash = hashGeneric(val);
|
||||||
|
result = hashCombine(result, valueHash);
|
||||||
}
|
}
|
||||||
break :blk result;
|
break :blk result;
|
||||||
},
|
},
|
||||||
.vector => blk: {
|
.vector => blk: {
|
||||||
var result: u64 = 0;
|
var result: u64 = 0x94d049bb133111eb;
|
||||||
inline for(0..@typeInfo(T).vector.len) |i| {
|
inline for(0..@typeInfo(T).vector.len) |i| {
|
||||||
result = result*%33 +% hashGeneric(input[i]);
|
const valueHash = hashGeneric(input[i]);
|
||||||
|
result = hashCombine(result, valueHash);
|
||||||
}
|
}
|
||||||
break :blk result;
|
break :blk result;
|
||||||
},
|
},
|
||||||
@ -190,6 +199,20 @@ fn hashGeneric(input: anytype) u64 {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://stackoverflow.com/questions/5889238/why-is-xor-the-default-way-to-combine-hashes
|
||||||
|
fn hashCombine(left: u64, right: u64) u64 {
|
||||||
|
return left ^ (right +% 0x517cc1b727220a95 +% (left << 6) +% (left >> 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://stackoverflow.com/questions/664014/what-integer-hash-function-are-good-that-accepts-an-integer-hash-key
|
||||||
|
fn hashInt(input: u64) u64 {
|
||||||
|
var x = input;
|
||||||
|
x = (x ^ (x >> 30))*%0xbf58476d1ce4e5b9;
|
||||||
|
x = (x ^ (x >> 27))*%0x94d049bb133111eb;
|
||||||
|
x = x ^ (x >> 31);
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
pub const Interpolation = enum(u8) {
|
pub const Interpolation = enum(u8) {
|
||||||
none,
|
none,
|
||||||
linear,
|
linear,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user