147 lines
4.5 KiB
V
147 lines
4.5 KiB
V
|
// "noscan" versions of `map` initialization routines
|
||
|
//
|
||
|
// They are used when the compiler can proof that either the keys or the values or both
|
||
|
// do not contain any pointers. Such objects can be placed in a memory area that is not
|
||
|
// scanned by the garbage collector
|
||
|
|
||
|
module builtin
|
||
|
|
||
|
[inline]
|
||
|
fn new_dense_array_noscan(key_bytes int, key_noscan bool, value_bytes int, value_noscan bool) DenseArray {
|
||
|
cap := 8
|
||
|
keys := if key_noscan {
|
||
|
unsafe { malloc_noscan(cap * key_bytes) }
|
||
|
} else {
|
||
|
unsafe { malloc(cap * key_bytes) }
|
||
|
}
|
||
|
values := if value_noscan {
|
||
|
unsafe { malloc_noscan(cap * value_bytes) }
|
||
|
} else {
|
||
|
unsafe { malloc(cap * value_bytes) }
|
||
|
}
|
||
|
return DenseArray{
|
||
|
key_bytes: key_bytes
|
||
|
value_bytes: value_bytes
|
||
|
cap: cap
|
||
|
len: 0
|
||
|
deletes: 0
|
||
|
all_deleted: 0
|
||
|
keys: keys
|
||
|
values: values
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fn new_map_noscan_key(key_bytes int, value_bytes int, hash_fn MapHashFn, key_eq_fn MapEqFn, clone_fn MapCloneFn, free_fn MapFreeFn) map {
|
||
|
metasize := int(sizeof(u32) * (init_capicity + extra_metas_inc))
|
||
|
// for now assume anything bigger than a pointer is a string
|
||
|
has_string_keys := key_bytes > sizeof(voidptr)
|
||
|
return map{
|
||
|
key_bytes: key_bytes
|
||
|
value_bytes: value_bytes
|
||
|
even_index: init_even_index
|
||
|
cached_hashbits: max_cached_hashbits
|
||
|
shift: init_log_capicity
|
||
|
key_values: new_dense_array_noscan(key_bytes, true, value_bytes, false)
|
||
|
metas: unsafe { &u32(vcalloc_noscan(metasize)) }
|
||
|
extra_metas: extra_metas_inc
|
||
|
len: 0
|
||
|
has_string_keys: has_string_keys
|
||
|
hash_fn: hash_fn
|
||
|
key_eq_fn: key_eq_fn
|
||
|
clone_fn: clone_fn
|
||
|
free_fn: free_fn
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fn new_map_noscan_value(key_bytes int, value_bytes int, hash_fn MapHashFn, key_eq_fn MapEqFn, clone_fn MapCloneFn, free_fn MapFreeFn) map {
|
||
|
metasize := int(sizeof(u32) * (init_capicity + extra_metas_inc))
|
||
|
// for now assume anything bigger than a pointer is a string
|
||
|
has_string_keys := key_bytes > sizeof(voidptr)
|
||
|
return map{
|
||
|
key_bytes: key_bytes
|
||
|
value_bytes: value_bytes
|
||
|
even_index: init_even_index
|
||
|
cached_hashbits: max_cached_hashbits
|
||
|
shift: init_log_capicity
|
||
|
key_values: new_dense_array_noscan(key_bytes, false, value_bytes, true)
|
||
|
metas: unsafe { &u32(vcalloc_noscan(metasize)) }
|
||
|
extra_metas: extra_metas_inc
|
||
|
len: 0
|
||
|
has_string_keys: has_string_keys
|
||
|
hash_fn: hash_fn
|
||
|
key_eq_fn: key_eq_fn
|
||
|
clone_fn: clone_fn
|
||
|
free_fn: free_fn
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fn new_map_noscan_key_value(key_bytes int, value_bytes int, hash_fn MapHashFn, key_eq_fn MapEqFn, clone_fn MapCloneFn, free_fn MapFreeFn) map {
|
||
|
metasize := int(sizeof(u32) * (init_capicity + extra_metas_inc))
|
||
|
// for now assume anything bigger than a pointer is a string
|
||
|
has_string_keys := key_bytes > sizeof(voidptr)
|
||
|
return map{
|
||
|
key_bytes: key_bytes
|
||
|
value_bytes: value_bytes
|
||
|
even_index: init_even_index
|
||
|
cached_hashbits: max_cached_hashbits
|
||
|
shift: init_log_capicity
|
||
|
key_values: new_dense_array_noscan(key_bytes, true, value_bytes, true)
|
||
|
metas: unsafe { &u32(vcalloc_noscan(metasize)) }
|
||
|
extra_metas: extra_metas_inc
|
||
|
len: 0
|
||
|
has_string_keys: has_string_keys
|
||
|
hash_fn: hash_fn
|
||
|
key_eq_fn: key_eq_fn
|
||
|
clone_fn: clone_fn
|
||
|
free_fn: free_fn
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fn new_map_init_noscan_key(hash_fn MapHashFn, key_eq_fn MapEqFn, clone_fn MapCloneFn, free_fn MapFreeFn, n int, key_bytes int, value_bytes int, keys voidptr, values voidptr) map {
|
||
|
mut out := new_map_noscan_key(key_bytes, value_bytes, hash_fn, key_eq_fn, clone_fn,
|
||
|
free_fn)
|
||
|
// TODO pre-allocate n slots
|
||
|
mut pkey := &byte(keys)
|
||
|
mut pval := &byte(values)
|
||
|
for _ in 0 .. n {
|
||
|
unsafe {
|
||
|
out.set(pkey, pval)
|
||
|
pkey = pkey + key_bytes
|
||
|
pval = pval + value_bytes
|
||
|
}
|
||
|
}
|
||
|
return out
|
||
|
}
|
||
|
|
||
|
fn new_map_init_noscan_value(hash_fn MapHashFn, key_eq_fn MapEqFn, clone_fn MapCloneFn, free_fn MapFreeFn, n int, key_bytes int, value_bytes int, keys voidptr, values voidptr) map {
|
||
|
mut out := new_map_noscan_value(key_bytes, value_bytes, hash_fn, key_eq_fn, clone_fn,
|
||
|
free_fn)
|
||
|
// TODO pre-allocate n slots
|
||
|
mut pkey := &byte(keys)
|
||
|
mut pval := &byte(values)
|
||
|
for _ in 0 .. n {
|
||
|
unsafe {
|
||
|
out.set(pkey, pval)
|
||
|
pkey = pkey + key_bytes
|
||
|
pval = pval + value_bytes
|
||
|
}
|
||
|
}
|
||
|
return out
|
||
|
}
|
||
|
|
||
|
fn new_map_init_noscan_key_value(hash_fn MapHashFn, key_eq_fn MapEqFn, clone_fn MapCloneFn, free_fn MapFreeFn, n int, key_bytes int, value_bytes int, keys voidptr, values voidptr) map {
|
||
|
mut out := new_map_noscan_key_value(key_bytes, value_bytes, hash_fn, key_eq_fn, clone_fn,
|
||
|
free_fn)
|
||
|
// TODO pre-allocate n slots
|
||
|
mut pkey := &byte(keys)
|
||
|
mut pval := &byte(values)
|
||
|
for _ in 0 .. n {
|
||
|
unsafe {
|
||
|
out.set(pkey, pval)
|
||
|
pkey = pkey + key_bytes
|
||
|
pval = pval + value_bytes
|
||
|
}
|
||
|
}
|
||
|
return out
|
||
|
}
|