map: comments and renaming
parent
bb5793d485
commit
3bb6b6c8b2
|
@ -141,8 +141,7 @@ fn (d DenseArray) get(i int) voidptr {
|
||||||
return byteptr(d.keys) + i * int(sizeof(string))
|
return byteptr(d.keys) + i * int(sizeof(string))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move all zeros to the end of the array
|
// Move all zeros to the end of the array and resize array
|
||||||
// and resize array
|
|
||||||
fn (mut d DenseArray) zeros_to_end() {
|
fn (mut d DenseArray) zeros_to_end() {
|
||||||
mut tmp_value := malloc(d.value_bytes)
|
mut tmp_value := malloc(d.value_bytes)
|
||||||
mut count := u32(0)
|
mut count := u32(0)
|
||||||
|
@ -168,10 +167,10 @@ fn (mut d DenseArray) zeros_to_end() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct map {
|
pub struct map {
|
||||||
// Byte size of value
|
// Number of bytes of a value
|
||||||
value_bytes int
|
value_bytes int
|
||||||
mut:
|
mut:
|
||||||
// highest even index in the hashtable
|
// Highest even index in the hashtable
|
||||||
cap u32
|
cap u32
|
||||||
// Number of cached hashbits left for rehasing
|
// Number of cached hashbits left for rehasing
|
||||||
cached_hashbits byte
|
cached_hashbits byte
|
||||||
|
@ -180,8 +179,8 @@ mut:
|
||||||
// Array storing key-values (ordered)
|
// Array storing key-values (ordered)
|
||||||
key_values DenseArray
|
key_values DenseArray
|
||||||
// Pointer to meta-data:
|
// Pointer to meta-data:
|
||||||
// Odd indices store kv_index.
|
// - Odd indices store kv_index.
|
||||||
// Even indices store probe_count and hashbits.
|
// - Even indices store probe_count and hashbits.
|
||||||
metas &u32
|
metas &u32
|
||||||
// Extra metas that allows for no ranging when incrementing
|
// Extra metas that allows for no ranging when incrementing
|
||||||
// index in the hashmap
|
// index in the hashmap
|
||||||
|
@ -268,6 +267,9 @@ fn (mut m map) ensure_extra_metas(probe_count u32) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Insert new element to the map. The element is inserted if its key is
|
||||||
|
// not equivalent to the key of any other element already in the container.
|
||||||
|
// If the key already exists, its value is changed to the value of the new element.
|
||||||
fn (mut m map) set(k string, value voidptr) {
|
fn (mut m map) set(k string, value voidptr) {
|
||||||
key := k.clone()
|
key := k.clone()
|
||||||
load_factor := f32(m.len << 1) / f32(m.cap)
|
load_factor := f32(m.len << 1) / f32(m.cap)
|
||||||
|
@ -307,6 +309,11 @@ fn (mut m map) expand() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A rehash is the reconstruction of the hash table:
|
||||||
|
// All the elements in the container are rearranged according
|
||||||
|
// to their hash value into the newly sized key-value container.
|
||||||
|
// Rehashes are performed when the load_factor is going to surpass
|
||||||
|
// the max_load_factor in an operation.
|
||||||
fn (mut m map) rehash() {
|
fn (mut m map) rehash() {
|
||||||
meta_bytes := sizeof(u32) * (m.cap + 2 + m.extra_metas)
|
meta_bytes := sizeof(u32) * (m.cap + 2 + m.extra_metas)
|
||||||
m.metas = &u32(C.realloc(m.metas, meta_bytes))
|
m.metas = &u32(C.realloc(m.metas, meta_bytes))
|
||||||
|
@ -321,6 +328,8 @@ fn (mut m map) rehash() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This method works like rehash. However, instead of rehashing the
|
||||||
|
// key completely, it uses the bits cached in `metas`.
|
||||||
fn (mut m map) cached_rehash(old_cap u32) {
|
fn (mut m map) cached_rehash(old_cap u32) {
|
||||||
old_metas := m.metas
|
old_metas := m.metas
|
||||||
m.metas = &u32(vcalloc(int(sizeof(u32) * (m.cap + 2 + m.extra_metas))))
|
m.metas = &u32(vcalloc(int(sizeof(u32) * (m.cap + 2 + m.extra_metas))))
|
||||||
|
@ -343,7 +352,36 @@ fn (mut m map) cached_rehash(old_cap u32) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (m map) get3(key string, zero voidptr) voidptr {
|
// This method is used for assignment operators. If the argument-key
|
||||||
|
// does not exist in the map, it's added to the map along with the zero/dafault value.
|
||||||
|
// If the key exists, its respective value is returned.
|
||||||
|
fn (mut m map) get_and_set(key string, zero voidptr) voidptr {
|
||||||
|
for {
|
||||||
|
mut index,mut meta := m.key_to_index(key)
|
||||||
|
for {
|
||||||
|
if meta == m.metas[index] {
|
||||||
|
kv_index := m.metas[index + 1]
|
||||||
|
if fast_string_eq(key, m.key_values.keys[kv_index]) {
|
||||||
|
return voidptr(m.key_values.values + kv_index * u32(m.value_bytes))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
index += 2
|
||||||
|
meta += probe_inc
|
||||||
|
if meta > m.metas[index] { break }
|
||||||
|
}
|
||||||
|
// Key not found, insert key with zero-value
|
||||||
|
m.set(key, zero)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Delete this (was used for bootstrap)
|
||||||
|
fn (mut m map) get2(key string, zero voidptr) voidptr {
|
||||||
|
return m.get_and_set(key, zero)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If `key` matches the key of an element in the container,
|
||||||
|
// the method returns a reference to its mapped value.
|
||||||
|
// If not, a zero/default value is returned.
|
||||||
|
fn (m map) get(key string, zero voidptr) voidptr {
|
||||||
mut index,mut meta := m.key_to_index(key)
|
mut index,mut meta := m.key_to_index(key)
|
||||||
for {
|
for {
|
||||||
if meta == m.metas[index] {
|
if meta == m.metas[index] {
|
||||||
|
@ -358,26 +396,12 @@ fn (m map) get3(key string, zero voidptr) voidptr {
|
||||||
}
|
}
|
||||||
return zero
|
return zero
|
||||||
}
|
}
|
||||||
|
// Delete this (was used for bootstrap)
|
||||||
fn (mut m map) get2(key string, zero voidptr) voidptr {
|
fn (m map) get3(key string, zero voidptr) voidptr {
|
||||||
for {
|
return m.get(key, zero)
|
||||||
mut index,mut meta := m.key_to_index(key)
|
|
||||||
for {
|
|
||||||
if meta == m.metas[index] {
|
|
||||||
kv_index := m.metas[index + 1]
|
|
||||||
if fast_string_eq(key, m.key_values.keys[kv_index]) {
|
|
||||||
return voidptr(m.key_values.values + kv_index * u32(m.value_bytes))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
index += 2
|
|
||||||
meta += probe_inc
|
|
||||||
if meta > m.metas[index] { break }
|
|
||||||
}
|
|
||||||
// set zero if not found
|
|
||||||
m.set(key, zero)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checks whether a particular key exists in the map.
|
||||||
fn (m map) exists(key string) bool {
|
fn (m map) exists(key string) bool {
|
||||||
mut index,mut meta := m.key_to_index(key)
|
mut index,mut meta := m.key_to_index(key)
|
||||||
for {
|
for {
|
||||||
|
@ -394,6 +418,7 @@ fn (m map) exists(key string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Removes the mapping of a particular key from the map.
|
||||||
pub fn (mut m map) delete(key string) {
|
pub fn (mut m map) delete(key string) {
|
||||||
mut index,mut meta := m.key_to_index(key)
|
mut index,mut meta := m.key_to_index(key)
|
||||||
index,meta = m.meta_less(index, meta)
|
index,meta = m.meta_less(index, meta)
|
||||||
|
@ -428,6 +453,7 @@ pub fn (mut m map) delete(key string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns all keys in the map.
|
||||||
// TODO: add optimization in case of no deletes
|
// TODO: add optimization in case of no deletes
|
||||||
pub fn (m &map) keys() []string {
|
pub fn (m &map) keys() []string {
|
||||||
mut keys := [''].repeat(m.len)
|
mut keys := [''].repeat(m.len)
|
||||||
|
|
|
@ -838,7 +838,7 @@ fn (mut g Gen) for_in(it ast.ForInStmt) {
|
||||||
g.writeln('for (int $idx = 0; $idx < ${keys_tmp}.len; $idx++) {')
|
g.writeln('for (int $idx = 0; $idx < ${keys_tmp}.len; $idx++) {')
|
||||||
g.writeln('\t$key_styp $key = (($key_styp*)${keys_tmp}.data)[$idx];')
|
g.writeln('\t$key_styp $key = (($key_styp*)${keys_tmp}.data)[$idx];')
|
||||||
if it.val_var != '_' {
|
if it.val_var != '_' {
|
||||||
g.write('\t$val_styp ${c_name(it.val_var)} = (*($val_styp*)map_get3(')
|
g.write('\t$val_styp ${c_name(it.val_var)} = (*($val_styp*)map_get(')
|
||||||
g.expr(it.cond)
|
g.expr(it.cond)
|
||||||
g.writeln(', $key, &($val_styp[]){ $zero }));')
|
g.writeln(', $key, &($val_styp[]){ $zero }));')
|
||||||
}
|
}
|
||||||
|
@ -2245,7 +2245,7 @@ fn (mut g Gen) index_expr(node ast.IndexExpr) {
|
||||||
g.write(', &($elem_type_str[]) { ')
|
g.write(', &($elem_type_str[]) { ')
|
||||||
} else if g.inside_map_postfix || g.inside_map_infix {
|
} else if g.inside_map_postfix || g.inside_map_infix {
|
||||||
zero := g.type_default(info.value_type)
|
zero := g.type_default(info.value_type)
|
||||||
g.write('(*($elem_type_str*)map_get2(')
|
g.write('(*($elem_type_str*)map_get_and_set(')
|
||||||
if !left_is_ptr {
|
if !left_is_ptr {
|
||||||
g.write('&')
|
g.write('&')
|
||||||
}
|
}
|
||||||
|
@ -2255,7 +2255,7 @@ fn (mut g Gen) index_expr(node ast.IndexExpr) {
|
||||||
g.write(', &($elem_type_str[]){ $zero }))\n')
|
g.write(', &($elem_type_str[]){ $zero }))\n')
|
||||||
} else {
|
} else {
|
||||||
zero := g.type_default(info.value_type)
|
zero := g.type_default(info.value_type)
|
||||||
g.write('(*($elem_type_str*)map_get3(')
|
g.write('(*($elem_type_str*)map_get(')
|
||||||
g.expr(node.left)
|
g.expr(node.left)
|
||||||
g.write(', ')
|
g.write(', ')
|
||||||
g.expr(node.index)
|
g.expr(node.index)
|
||||||
|
@ -4140,7 +4140,7 @@ fn (mut g Gen) gen_str_for_map(info table.Map, styp, str_fn_name string) {
|
||||||
g.auto_str_funcs.writeln('\t\tstring key = (*(string*)DenseArray_get(m.key_values, i));')
|
g.auto_str_funcs.writeln('\t\tstring key = (*(string*)DenseArray_get(m.key_values, i));')
|
||||||
g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, _STR("\'%.*s\\000\'", 2, key));')
|
g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, _STR("\'%.*s\\000\'", 2, key));')
|
||||||
g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, tos_lit(": "));')
|
g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, tos_lit(": "));')
|
||||||
g.auto_str_funcs.write('\t$val_styp it = (*($val_styp*)map_get3(')
|
g.auto_str_funcs.write('\t$val_styp it = (*($val_styp*)map_get(')
|
||||||
g.auto_str_funcs.write('m, (*(string*)DenseArray_get(m.key_values, i))')
|
g.auto_str_funcs.write('m, (*(string*)DenseArray_get(m.key_values, i))')
|
||||||
g.auto_str_funcs.write(', ')
|
g.auto_str_funcs.write(', ')
|
||||||
g.auto_str_funcs.writeln(' &($val_styp[]) { $zero }));')
|
g.auto_str_funcs.writeln(' &($val_styp[]) { $zero }));')
|
||||||
|
|
Loading…
Reference in New Issue