Add hash.djb2 hash.jenkins; Add container.Bloom_Filter; Add container.Ring

This commit is contained in:
gingerBill
2020-06-16 12:53:57 +01:00
parent f70939ab4f
commit 5edb1e8a28
5 changed files with 347 additions and 144 deletions
+80
View File
@@ -0,0 +1,80 @@
package container
import "core:mem"
Bloom_Hash_Proc :: #type proc(data: []byte) -> u32;
Bloom_Hash :: struct {
hash_proc: Bloom_Hash_Proc,
next: ^Bloom_Hash,
}
Bloom_Filter :: struct {
allocator: mem.Allocator,
hash: ^Bloom_Hash,
bits: []byte,
}
bloom_filter_init :: proc(b: ^Bloom_Filter, size: int, allocator := context.allocator) {
b.allocator = allocator;
b.bits = make([]byte, size, allocator);
}
bloom_filter_destroy :: proc(b: ^Bloom_Filter) {
context.allocator = b.allocator;
delete(b.bits);
for b.hash != nil {
hash := b.hash;
b.hash = b.hash.next;
free(hash);
}
}
bloom_filter_add_hash_proc :: proc(b: ^Bloom_Filter, hash_proc: Bloom_Hash_Proc) {
context.allocator = b.allocator;
h := new(Bloom_Hash);
h.hash_proc = hash_proc;
head := &b.hash;
for head^ != nil {
head = &(head^.next);
}
head^ = h;
}
bloom_filter_add :: proc(b: ^Bloom_Filter, item: []byte) {
#no_bounds_check for h := b.hash; h != nil; h = h.next {
hash := h.hash_proc(item);
hash %= u32(len(b.bits) * 8);
b.bits[hash >> 3] |= 1 << (hash & 3);
}
}
bloom_filter_add_string :: proc(b: ^Bloom_Filter, item: string) {
bloom_filter_add(b, transmute([]byte)item);
}
bloom_filter_add_raw :: proc(b: ^Bloom_Filter, data: rawptr, size: int) {
item := mem.slice_ptr((^byte)(data), size);
bloom_filter_add(b, item);
}
bloom_filter_test :: proc(b: ^Bloom_Filter, item: []byte) -> bool {
#no_bounds_check for h := b.hash; h != nil; h = h.next {
hash := h.hash_proc(item);
hash %= u32(len(b.bits) * 8);
if (b.bits[hash >> 3] & (1 << (hash & 3)) == 0) {
return false;
}
}
return true;
}
bloom_filter_test_string :: proc(b: ^Bloom_Filter, item: string) -> bool {
return bloom_filter_test(b, transmute([]byte)item);
}
bloom_filter_test_raw :: proc(b: ^Bloom_Filter, data: rawptr, size: int) -> bool {
item := mem.slice_ptr((^byte)(data), size);
return bloom_filter_test(b, item);
}
+73
View File
@@ -0,0 +1,73 @@
package container
Ring :: struct(T: typeid) {
next, prev: ^Ring,
value: T,
}
ring_init :: proc(r: ^$R/Ring) -> ^R {
r.prev, r.next = r, r;
return r;
}
ring_next :: proc(r: ^$R/Ring) -> ^R {
if r.next == nil {
return ring_init(r);
}
return r.next;
}
ring_prev :: proc(r: ^$R/Ring) -> ^R {
if r.prev == nil {
return ring_init(r);
}
return r.prev;
}
ring_move :: proc(r: ^$R/Ring, n: int) -> ^R {
if r.next == nil {
return ring_init(r);
}
switch {
case n < 0:
for _ in n..<0 {
r = r.prev;
}
case n > 0:
for _ in 0..<n {
r = r.next;
}
}
return r;
}
ring_link :: proc(r, s: ^$R/Ring) -> ^R {
n := ring_next(r);
if s != nil {
p := ring_prev(s);
r.next = s;
s.prev = r;
n.prev = p;
p.next = n;
}
return n;
}
ring_unlink :: proc(r: ^$R/Ring, n: int) -> ^R {
if n <= 0 {
return nil;
}
return ring_link(r, ring_move(r, n+1));
}
ring_len :: proc(r: ^$R/Ring) -> int {
n := 0;
if r != nil {
n = 1;
for p := ring_next(p); p != r; p = p.next {
n += 1;
}
}
return n;
}