builtin: map: fix memory leak

pull/5060/head
ka-weihe 2020-05-26 17:59:52 +02:00 committed by GitHub
parent 31ba64b409
commit 64173c792f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 12 additions and 5 deletions

View File

@ -60,7 +60,7 @@ much faster rehashing.
*/ */
const ( const (
// Number of bits from the hash stored for each entry // Number of bits from the hash stored for each entry
hashbits = 24 hashbits = 24
// Number of bits from the hash stored for rehashing // Number of bits from the hash stored for rehashing
max_cached_hashbits = 16 max_cached_hashbits = 16
@ -132,7 +132,6 @@ fn (mut d DenseArray) push(key string, value voidptr) u32 {
return push_index return push_index
} }
// Private function. Used to implement array[] operator
fn (d DenseArray) get(i int) voidptr { fn (d DenseArray) get(i int) voidptr {
$if !no_bounds_checking? { $if !no_bounds_checking? {
if i < 0 || i >= d.size { if i < 0 || i >= d.size {
@ -252,6 +251,11 @@ fn (mut m map) meta_greater(_index u32, _metas u32, kvi u32) {
m.metas[index] = meta m.metas[index] = meta
m.metas[index + 1] = kv_index m.metas[index + 1] = kv_index
probe_count := (meta >> hashbits) - 1 probe_count := (meta >> hashbits) - 1
m.ensure_extra_metas(probe_count)
}
[inline]
fn (mut m map) ensure_extra_metas(probe_count u32) {
if (probe_count << 1) == m.extra_metas { if (probe_count << 1) == m.extra_metas {
m.extra_metas += extra_metas_inc m.extra_metas += extra_metas_inc
mem_size := (m.cap + 2 + m.extra_metas) mem_size := (m.cap + 2 + m.extra_metas)
@ -264,7 +268,8 @@ fn (mut m map) meta_greater(_index u32, _metas u32, kvi u32) {
} }
} }
fn (mut m map) set(key string, value voidptr) { fn (mut m map) set(k string, value voidptr) {
key := k.clone()
load_factor := f32(m.size << 1) / f32(m.cap) load_factor := f32(m.size << 1) / f32(m.cap)
if load_factor > max_load_factor { if load_factor > max_load_factor {
m.expand() m.expand()
@ -385,6 +390,8 @@ pub fn (mut m map) delete(key string) {
m.size-- m.size--
m.metas[index] = 0 m.metas[index] = 0
m.key_values.deletes++ m.key_values.deletes++
// Mark key as deleted
m.key_values.keys[kv_index].free()
C.memset(&m.key_values.keys[kv_index], 0, sizeof(string)) C.memset(&m.key_values.keys[kv_index], 0, sizeof(string))
if m.key_values.size <= 32 { if m.key_values.size <= 32 {
return return
@ -410,7 +417,7 @@ pub fn (m &map) keys() []string {
if m.key_values.keys[i].str == 0 { if m.key_values.keys[i].str == 0 {
continue continue
} }
keys[j] = m.key_values.keys[i] keys[j] = m.key_values.keys[i].clone()
j++ j++
} }
return keys return keys