mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-28 10:20:05 +00:00
Add intrinsics.type_hasher_proc; Make map work with generic hasher procedure
This commit is contained in:
@@ -42,7 +42,8 @@ Platform_Endianness :: enum u8 {
|
||||
Big = 2,
|
||||
}
|
||||
|
||||
Equal_Proc :: distinct proc "contextless" (rawptr, rawptr) -> bool;
|
||||
Equal_Proc :: distinct proc "contextless" (rawptr, rawptr) -> bool;
|
||||
Hasher_Proc :: distinct proc "contextless" (data: rawptr, seed: uintptr) -> uintptr;
|
||||
|
||||
Type_Info_Struct_Soa_Kind :: enum u8 {
|
||||
None = 0,
|
||||
@@ -125,6 +126,8 @@ Type_Info_Map :: struct {
|
||||
key: ^Type_Info,
|
||||
value: ^Type_Info,
|
||||
generated_struct: ^Type_Info,
|
||||
key_equal: Equal_Proc,
|
||||
key_hasher: Hasher_Proc,
|
||||
};
|
||||
Type_Info_Bit_Field :: struct {
|
||||
names: []string,
|
||||
|
||||
@@ -11,31 +11,11 @@ Map_Hash :: struct {
|
||||
key_ptr: rawptr, // address of Map_Entry_Header.key
|
||||
}
|
||||
|
||||
__get_map_hash :: proc "contextless" (k: ^$K) -> Map_Hash {
|
||||
key := k;
|
||||
map_hash: Map_Hash;
|
||||
|
||||
T :: intrinsics.type_core_type(K);
|
||||
|
||||
__get_map_hash :: proc "contextless" (k: ^$K) -> (map_hash: Map_Hash) {
|
||||
hasher := intrinsics.type_hasher_proc(K);
|
||||
map_hash.key_ptr = k;
|
||||
|
||||
when intrinsics.type_is_integer(T) {
|
||||
map_hash.hash = default_hash_ptr(key, size_of(T));
|
||||
} else when intrinsics.type_is_rune(T) {
|
||||
map_hash.hash = default_hash_ptr(key, size_of(T));
|
||||
} else when intrinsics.type_is_pointer(T) {
|
||||
map_hash.hash = default_hash_ptr(key, size_of(T));
|
||||
} else when intrinsics.type_is_float(T) {
|
||||
map_hash.hash = default_hash_ptr(key, size_of(T));
|
||||
} else when intrinsics.type_is_string(T) {
|
||||
#assert(T == string);
|
||||
str := (^string)(key)^;
|
||||
map_hash.hash = default_hash_string(str);
|
||||
} else {
|
||||
#panic("Unhandled map key type");
|
||||
}
|
||||
|
||||
return map_hash;
|
||||
map_hash.hash = hasher(k, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
__get_map_hash_from_entry :: proc "contextless" (h: Map_Header, entry: ^Map_Entry_Header) -> (hash: Map_Hash) {
|
||||
@@ -96,6 +76,42 @@ default_hash_ptr :: inline proc "contextless" (data: rawptr, size: int) -> uintp
|
||||
return default_hash(transmute([]byte)(s));
|
||||
}
|
||||
|
||||
_default_hasher_const :: inline proc "contextless" (data: rawptr, seed: uintptr, $N: uint) -> uintptr {
|
||||
h := u64(seed) + 0xcbf29ce484222325;
|
||||
p := uintptr(data);
|
||||
inline for _ in 0..<N {
|
||||
b := u64((^byte)(p)^);
|
||||
h = (h ~ b) * 0x100000001b3;
|
||||
p += 1;
|
||||
}
|
||||
return uintptr(h);
|
||||
}
|
||||
_default_hasher_n :: inline proc "contextless" (data: rawptr, seed: uintptr, N: int) -> uintptr {
|
||||
h := u64(seed) + 0xcbf29ce484222325;
|
||||
p := uintptr(data);
|
||||
for _ in 0..<N {
|
||||
b := u64((^byte)(p)^);
|
||||
h = (h ~ b) * 0x100000001b3;
|
||||
p += 1;
|
||||
}
|
||||
return uintptr(h);
|
||||
}
|
||||
|
||||
default_hasher1 :: proc "contextless" (data: rawptr, seed: uintptr) -> uintptr { return inline _default_hasher_const(data, seed, 1); }
|
||||
default_hasher2 :: proc "contextless" (data: rawptr, seed: uintptr) -> uintptr { return inline _default_hasher_const(data, seed, 2); }
|
||||
default_hasher4 :: proc "contextless" (data: rawptr, seed: uintptr) -> uintptr { return inline _default_hasher_const(data, seed, 4); }
|
||||
default_hasher8 :: proc "contextless" (data: rawptr, seed: uintptr) -> uintptr { return inline _default_hasher_const(data, seed, 8); }
|
||||
default_hasher16 :: proc "contextless" (data: rawptr, seed: uintptr) -> uintptr { return inline _default_hasher_const(data, seed, 16); }
|
||||
default_hasher_string :: proc "contextless" (data: rawptr, seed: uintptr) -> uintptr {
|
||||
h := u64(seed) + 0xcbf29ce484222325;
|
||||
str := (^[]byte)(data)^;
|
||||
for b in str {
|
||||
h = (h ~ u64(b)) * 0x100000001b3;
|
||||
}
|
||||
return uintptr(h);
|
||||
}
|
||||
|
||||
|
||||
|
||||
source_code_location_hash :: proc(s: Source_Code_Location) -> uintptr {
|
||||
hash := _fnv64a(transmute([]byte)s.file_path);
|
||||
|
||||
Reference in New Issue
Block a user