map: optimize free() and keys() (#7152)
parent
8adb1acf31
commit
5a7fdb0610
|
@ -56,7 +56,6 @@ find the index for their meta's in the new array. Instead of rehashing compl-
|
|||
etely, it simply uses the cached-hashbits stored in the meta, resulting in
|
||||
much faster rehashing.
|
||||
*/
|
||||
|
||||
const (
|
||||
// Number of bits from the hash stored for each entry
|
||||
hashbits = 24
|
||||
|
@ -224,9 +223,7 @@ fn new_map_1(value_bytes int) map {
|
|||
fn new_map_init(n int, value_bytes int, keys &string, values voidptr) map {
|
||||
mut out := new_map_1(value_bytes)
|
||||
for i in 0 .. n {
|
||||
unsafe {
|
||||
out.set(keys[i], byteptr(values) + i * value_bytes)
|
||||
}
|
||||
unsafe {out.set(keys[i], byteptr(values) + i * value_bytes)}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
@ -261,13 +258,11 @@ fn (mut m map) meta_greater(_index u32, _metas u32, kvi u32) {
|
|||
tmp_meta := m.metas[index]
|
||||
m.metas[index] = meta
|
||||
meta = tmp_meta
|
||||
}
|
||||
tmp_index := unsafe {m.metas[index + 1]}
|
||||
unsafe {
|
||||
tmp_index := m.metas[index + 1]
|
||||
m.metas[index + 1] = kv_index
|
||||
}
|
||||
kv_index = tmp_index
|
||||
}
|
||||
}
|
||||
index += 2
|
||||
meta += probe_inc
|
||||
}
|
||||
|
@ -335,8 +330,7 @@ fn (mut m map) expand() {
|
|||
m.shift += max_cached_hashbits
|
||||
m.cached_hashbits = max_cached_hashbits
|
||||
m.rehash()
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
m.cached_rehash(old_cap)
|
||||
m.cached_hashbits--
|
||||
}
|
||||
|
@ -385,9 +379,7 @@ fn (mut m map) cached_rehash(old_cap u32) {
|
|||
kv_index := unsafe {old_metas[i + 1]}
|
||||
m.meta_greater(index, meta, kv_index)
|
||||
}
|
||||
unsafe{
|
||||
free(old_metas)
|
||||
}
|
||||
unsafe {free(old_metas)}
|
||||
}
|
||||
|
||||
// This method is used for assignment operators. If the argument-key
|
||||
|
@ -406,7 +398,9 @@ fn (mut m map) get_and_set(key string, zero voidptr) voidptr {
|
|||
}
|
||||
index += 2
|
||||
meta += probe_inc
|
||||
if meta > unsafe {m.metas[index]} { break }
|
||||
if meta > unsafe {m.metas[index]} {
|
||||
break
|
||||
}
|
||||
}
|
||||
// Key not found, insert key with zero-value
|
||||
m.set(key, zero)
|
||||
|
@ -430,7 +424,9 @@ fn (m map) get(key string, zero voidptr) voidptr {
|
|||
}
|
||||
index += 2
|
||||
meta += probe_inc
|
||||
if meta > unsafe {m.metas[index]} { break }
|
||||
if meta > unsafe {m.metas[index]} {
|
||||
break
|
||||
}
|
||||
}
|
||||
return zero
|
||||
}
|
||||
|
@ -448,7 +444,9 @@ fn (m map) exists(key string) bool {
|
|||
}
|
||||
index += 2
|
||||
meta += probe_inc
|
||||
if meta > unsafe {m.metas[index]} { break }
|
||||
if meta > unsafe {m.metas[index]} {
|
||||
break
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
@ -496,10 +494,17 @@ pub fn (mut m map) delete(key string) {
|
|||
}
|
||||
|
||||
// Returns all keys in the map.
|
||||
// TODO: add optimization in case of no deletes
|
||||
pub fn (m &map) keys() []string {
|
||||
mut keys := []string{len: m.len}
|
||||
mut j := 0
|
||||
if m.key_values.deletes == 0 {
|
||||
for i := 0; i < m.key_values.len; i++ {
|
||||
pkey := unsafe {&string(m.key_values.key(i))}
|
||||
keys[j] = pkey.clone()
|
||||
j++
|
||||
}
|
||||
return keys
|
||||
}
|
||||
for i := 0; i < m.key_values.len; i++ {
|
||||
if !m.key_values.has_index(i) {
|
||||
continue
|
||||
|
@ -539,17 +544,21 @@ pub fn (m map) clone() map {
|
|||
extra_metas: m.extra_metas
|
||||
len: m.len
|
||||
}
|
||||
unsafe {
|
||||
C.memcpy(res.metas, m.metas, metasize)
|
||||
}
|
||||
unsafe {C.memcpy(res.metas, m.metas, metasize)}
|
||||
return res
|
||||
}
|
||||
|
||||
[unsafe]
|
||||
pub fn (m &map) free() {
|
||||
unsafe {free(m.metas)}
|
||||
if m.key_values.deletes == 0 {
|
||||
for i := 0; i < m.key_values.len; i++ {
|
||||
unsafe {
|
||||
free(m.metas)
|
||||
pkey := &string(m.key_values.key(i))
|
||||
(*pkey).free()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for i := 0; i < m.key_values.len; i++ {
|
||||
if !m.key_values.has_index(i) {
|
||||
continue
|
||||
|
@ -559,22 +568,6 @@ pub fn (m &map) free() {
|
|||
(*pkey).free()
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
free(m.key_values.data)
|
||||
}
|
||||
unsafe {free(m.key_values.data)}
|
||||
}
|
||||
|
||||
/*
|
||||
pub fn (m map_string) str() string {
|
||||
if m.len == 0 {
|
||||
return '{}'
|
||||
}
|
||||
mut sb := strings.new_builder(50)
|
||||
sb.writeln('{')
|
||||
for key, val in m {
|
||||
sb.writeln(' "$key" => "$val"')
|
||||
}
|
||||
sb.writeln('}')
|
||||
return sb.str()
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -1234,6 +1234,7 @@ fn (mut g Gen) for_in(it ast.ForInStmt) {
|
|||
g.expr(it.cond)
|
||||
g.writeln(';')
|
||||
g.writeln('for (int $idx = 0; $idx < ${atmp}.key_values.len; ++$idx) {')
|
||||
// TODO: don't have this check when the map has no deleted elements
|
||||
g.writeln('\tif (!DenseArray_has_index(&${atmp}.key_values, $idx)) {continue;}')
|
||||
if it.key_var != '_' {
|
||||
key_styp := g.typ(it.key_type)
|
||||
|
|
Loading…
Reference in New Issue