1 | module builtin |
2 | |
3 | fn C.wyhash(&byte, u64, u64, &u64) u64 |
4 | |
5 | fn C.wyhash64(u64, u64) u64 |
6 | |
7 | // fast_string_eq is intended to be fast when |
8 | // the strings are very likely to be equal |
9 | // TODO: add branch prediction hints |
10 | [inline] |
11 | fn fast_string_eq(a string, b string) bool { |
12 | if a.len != b.len { |
13 | return false |
14 | } |
15 | unsafe { |
16 | return C.memcmp(a.str, b.str, b.len) == 0 |
17 | } |
18 | } |
19 | |
20 | fn map_hash_string(pkey voidptr) u64 { |
21 | key := *unsafe { &string(pkey) } |
22 | return C.wyhash(key.str, u64(key.len), 0, &u64(C._wyp)) |
23 | } |
24 | |
25 | fn map_hash_int_1(pkey voidptr) u64 { |
26 | return C.wyhash64(*unsafe { &u8(pkey) }, 0) |
27 | } |
28 | |
29 | fn map_hash_int_2(pkey voidptr) u64 { |
30 | return C.wyhash64(*unsafe { &u16(pkey) }, 0) |
31 | } |
32 | |
33 | fn map_hash_int_4(pkey voidptr) u64 { |
34 | return C.wyhash64(*unsafe { &u32(pkey) }, 0) |
35 | } |
36 | |
37 | fn map_hash_int_8(pkey voidptr) u64 { |
38 | return C.wyhash64(*unsafe { &u64(pkey) }, 0) |
39 | } |
40 | |
41 | // Move all zeros to the end of the array and resize array |
42 | fn (mut d DenseArray) zeros_to_end() { |
43 | // TODO alloca? |
44 | mut tmp_value := unsafe { malloc(d.value_bytes) } |
45 | mut tmp_key := unsafe { malloc(d.key_bytes) } |
46 | mut count := 0 |
47 | for i in 0 .. d.len { |
48 | if d.has_index(i) { |
49 | // swap (TODO: optimize) |
50 | unsafe { |
51 | if count != i { |
52 | // Swap keys |
53 | C.memcpy(tmp_key, d.key(count), d.key_bytes) |
54 | C.memcpy(d.key(count), d.key(i), d.key_bytes) |
55 | C.memcpy(d.key(i), tmp_key, d.key_bytes) |
56 | // Swap values |
57 | C.memcpy(tmp_value, d.value(count), d.value_bytes) |
58 | C.memcpy(d.value(count), d.value(i), d.value_bytes) |
59 | C.memcpy(d.value(i), tmp_value, d.value_bytes) |
60 | } |
61 | } |
62 | count++ |
63 | } |
64 | } |
65 | unsafe { |
66 | free(tmp_value) |
67 | free(tmp_key) |
68 | d.deletes = 0 |
69 | // TODO: reallocate instead as more deletes are likely |
70 | free(d.all_deleted) |
71 | } |
72 | d.len = count |
73 | old_cap := d.cap |
74 | d.cap = if count < 8 { 8 } else { count } |
75 | unsafe { |
76 | d.values = realloc_data(d.values, d.value_bytes * old_cap, d.value_bytes * d.cap) |
77 | d.keys = realloc_data(d.keys, d.key_bytes * old_cap, d.key_bytes * d.cap) |
78 | } |
79 | } |