Skip to content

Commit 9a7ed01

Browse files
committed
Moving hash into terrain
1 parent 8377fbe commit 9a7ed01

File tree

4 files changed

+77
-83
lines changed

4 files changed

+77
-83
lines changed

src/server/terrain/biomes.zig

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ const Vec3f = main.vec.Vec3f;
1111
const Vec3d = main.vec.Vec3d;
1212
const structures_zig = @import("structures.zig");
1313
const SimpleStructureModel = structures_zig.SimpleStructureModel;
14-
const StructureTable = structures_zig.StructureTable;
1514

1615
const Stripe = struct { // MARK: Stripe
1716
direction: ?Vec3d,
@@ -283,7 +282,7 @@ pub const Biome = struct { // MARK: Biome
283282
}
284283

285284
fn getCheckSum(self: *Biome) u64 {
286-
return main.utils.Hash.hashGeneric(self.*);
285+
return terrain.hashGeneric(self.*);
287286
}
288287
};
289288

src/server/terrain/structures.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ pub const SimpleStructureModel = struct { // MARK: SimpleStructureModel
6161
self.generate = main.utils.castFunctionSelfToAnyopaque(Generator.generate);
6262
self.hashFunction = main.utils.castFunctionSelfToAnyopaque(struct {
6363
fn hash(ptr: *Generator) u64 {
64-
return main.utils.Hash.hashGeneric(ptr.*);
64+
return terrain.hashGeneric(ptr.*);
6565
}
6666
}.hash);
6767
self.generationMode = Generator.generationMode;

src/server/terrain/terrain.zig

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,81 @@ pub const StructureMap = @import("StructureMap.zig");
2424

2525
pub const structure_building_blocks = @import("structure_building_blocks.zig");
2626

27+
pub fn hashGeneric(input: anytype) u64 {
28+
const T = @TypeOf(input);
29+
return switch(@typeInfo(T)) {
30+
.bool => hashCombine(hashInt(@intFromBool(input)), 0xbf58476d1ce4e5b9),
31+
.@"enum" => hashCombine(hashInt(@as(u64, @intFromEnum(input))), 0x94d049bb133111eb),
32+
.int, .float => blk: {
33+
const value = @as(std.meta.Int(.unsigned, @bitSizeOf(T)), @bitCast(input));
34+
break :blk hashInt(@as(u64, value));
35+
},
36+
.@"struct" => blk: {
37+
if(@hasDecl(T, "getHash")) {
38+
break :blk input.getHash();
39+
}
40+
var result: u64 = hashGeneric(@typeName(T));
41+
inline for(@typeInfo(T).@"struct".fields) |field| {
42+
const keyHash = hashGeneric(@as([]const u8, field.name));
43+
const valueHash = hashGeneric(@field(input, field.name));
44+
const keyValueHash = hashCombine(keyHash, valueHash);
45+
result = hashCombine(result, keyValueHash);
46+
}
47+
break :blk result;
48+
},
49+
.optional => if(input) |_input| hashGeneric(_input) else 0,
50+
.pointer => switch(@typeInfo(T).pointer.size) {
51+
.one => blk: {
52+
if(@typeInfo(@typeInfo(T).pointer.child) == .@"fn") break :blk 0;
53+
if(@typeInfo(T).pointer.child == Biome) return hashGeneric(input.id);
54+
if(@typeInfo(T).pointer.child == anyopaque) break :blk 0;
55+
if(@typeInfo(T).pointer.child == structures) return hashGeneric(input.id);
56+
break :blk hashGeneric(input.*);
57+
},
58+
.slice => blk: {
59+
var result: u64 = hashInt(input.len);
60+
for(input) |val| {
61+
const valueHash = hashGeneric(val);
62+
result = hashCombine(result, valueHash);
63+
}
64+
break :blk result;
65+
},
66+
else => @compileError("Unsupported type " ++ @typeName(T)),
67+
},
68+
.array => blk: {
69+
var result: u64 = 0xbf58476d1ce4e5b9;
70+
for(input) |val| {
71+
const valueHash = hashGeneric(val);
72+
result = hashCombine(result, valueHash);
73+
}
74+
break :blk result;
75+
},
76+
.vector => blk: {
77+
var result: u64 = 0x94d049bb133111eb;
78+
inline for(0..@typeInfo(T).vector.len) |i| {
79+
const valueHash = hashGeneric(input[i]);
80+
result = hashCombine(result, valueHash);
81+
}
82+
break :blk result;
83+
},
84+
else => @compileError("Unsupported type " ++ @typeName(T)),
85+
};
86+
}
87+
88+
// https://stackoverflow.com/questions/5889238/why-is-xor-the-default-way-to-combine-hashes
89+
pub fn hashCombine(left: u64, right: u64) u64 {
90+
return left ^ (right +% 0x517cc1b727220a95 +% (left << 6) +% (left >> 2));
91+
}
92+
93+
// https://stackoverflow.com/questions/664014/what-integer-hash-function-are-good-that-accepts-an-integer-hash-key
94+
pub fn hashInt(input: u64) u64 {
95+
var x = input;
96+
x = (x ^ (x >> 30))*%0xbf58476d1ce4e5b9;
97+
x = (x ^ (x >> 27))*%0x94d049bb133111eb;
98+
x = x ^ (x >> 31);
99+
return x;
100+
}
101+
27102
/// A generator for setting the actual Blocks in each Chunk.
28103
pub const BlockGenerator = struct {
29104
init: *const fn(parameters: ZonElement) void,

src/utils.zig

Lines changed: 0 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -9,86 +9,6 @@ const NeverFailingAllocator = main.heap.NeverFailingAllocator;
99
pub const file_monitor = @import("utils/file_monitor.zig");
1010
pub const VirtualList = @import("utils/virtual_mem.zig").VirtualList;
1111

12-
pub const Hash = struct {
13-
const Biome = main.server.terrain.biomes;
14-
const Structures = main.server.terrain.structures;
15-
16-
pub fn hashGeneric(input: anytype) u64 {
17-
const T = @TypeOf(input);
18-
return switch(@typeInfo(T)) {
19-
.bool => hashCombine(hashInt(@intFromBool(input)), 0xbf58476d1ce4e5b9),
20-
.@"enum" => hashCombine(hashInt(@as(u64, @intFromEnum(input))), 0x94d049bb133111eb),
21-
.int, .float => blk: {
22-
const value = @as(std.meta.Int(.unsigned, @bitSizeOf(T)), @bitCast(input));
23-
break :blk hashInt(@as(u64, value));
24-
},
25-
.@"struct" => blk: {
26-
if(@hasDecl(T, "getHash")) {
27-
break :blk input.getHash();
28-
}
29-
var result: u64 = hashGeneric(@typeName(T));
30-
inline for(@typeInfo(T).@"struct".fields) |field| {
31-
const keyHash = hashGeneric(@as([]const u8, field.name));
32-
const valueHash = hashGeneric(@field(input, field.name));
33-
const keyValueHash = hashCombine(keyHash, valueHash);
34-
result = hashCombine(result, keyValueHash);
35-
}
36-
break :blk result;
37-
},
38-
.optional => if(input) |_input| hashGeneric(_input) else 0,
39-
.pointer => switch(@typeInfo(T).pointer.size) {
40-
.one => blk: {
41-
if(@typeInfo(@typeInfo(T).pointer.child) == .@"fn") break :blk 0;
42-
if(@typeInfo(T).pointer.child == Biome) return hashGeneric(input.id);
43-
if(@typeInfo(T).pointer.child == anyopaque) break :blk 0;
44-
if(@typeInfo(T).pointer.child == Structures) return hashGeneric(input.id);
45-
break :blk hashGeneric(input.*);
46-
},
47-
.slice => blk: {
48-
var result: u64 = hashInt(input.len);
49-
for(input) |val| {
50-
const valueHash = hashGeneric(val);
51-
result = hashCombine(result, valueHash);
52-
}
53-
break :blk result;
54-
},
55-
else => @compileError("Unsupported type " ++ @typeName(T)),
56-
},
57-
.array => blk: {
58-
var result: u64 = 0xbf58476d1ce4e5b9;
59-
for(input) |val| {
60-
const valueHash = hashGeneric(val);
61-
result = hashCombine(result, valueHash);
62-
}
63-
break :blk result;
64-
},
65-
.vector => blk: {
66-
var result: u64 = 0x94d049bb133111eb;
67-
inline for(0..@typeInfo(T).vector.len) |i| {
68-
const valueHash = hashGeneric(input[i]);
69-
result = hashCombine(result, valueHash);
70-
}
71-
break :blk result;
72-
},
73-
else => @compileError("Unsupported type " ++ @typeName(T)),
74-
};
75-
}
76-
77-
// https://stackoverflow.com/questions/5889238/why-is-xor-the-default-way-to-combine-hashes
78-
pub fn hashCombine(left: u64, right: u64) u64 {
79-
return left ^ (right +% 0x517cc1b727220a95 +% (left << 6) +% (left >> 2));
80-
}
81-
82-
// https://stackoverflow.com/questions/664014/what-integer-hash-function-are-good-that-accepts-an-integer-hash-key
83-
pub fn hashInt(input: u64) u64 {
84-
var x = input;
85-
x = (x ^ (x >> 30))*%0xbf58476d1ce4e5b9;
86-
x = (x ^ (x >> 27))*%0x94d049bb133111eb;
87-
x = x ^ (x >> 31);
88-
return x;
89-
}
90-
};
91-
9212
pub const Compression = struct { // MARK: Compression
9313
pub fn deflate(allocator: NeverFailingAllocator, data: []const u8, level: std.compress.flate.deflate.Level) []u8 {
9414
var result = main.List(u8).init(allocator);

0 commit comments

Comments
 (0)