Skip to content

Commit

Permalink
map: make DenseArray.has_index not assume string keys (#7284)
Browse files Browse the repository at this point in the history
  • Loading branch information
ntrel authored Dec 13, 2020
1 parent 4324be9 commit ae460a2
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 11 deletions.
40 changes: 30 additions & 10 deletions vlib/builtin/map.v
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,10 @@ mut:
cap int
len int
deletes u32 // count
data byteptr // array of interspersed key data and value data
// array allocated (with `cap` bytes) on first deletion
// has non-zero element when key deleted
all_deleted &byte
data byteptr // array of interleaved key data and value data
}

[inline]
Expand All @@ -115,7 +118,8 @@ fn new_dense_array(key_bytes int, value_bytes int) DenseArray {
cap: cap
len: 0
deletes: 0
data: malloc(cap * slot_bytes)
all_deleted: 0
data: malloc(cap * slot_bytes)
}
}

Expand All @@ -132,9 +136,7 @@ fn (d &DenseArray) value(i int) voidptr {

[inline]
fn (d &DenseArray) has_index(i int) bool {
// assume string keys for now
pkey := unsafe {&string(d.key(i))}
return pkey.str != 0
return d.deletes == 0 || unsafe {d.all_deleted[i]} == 0
}

// Push element to array and return index
Expand All @@ -145,10 +147,17 @@ fn (mut d DenseArray) push(key voidptr, value voidptr) int {
d.cap += d.cap >> 3
unsafe {
d.data = v_realloc(d.data, d.slot_bytes * d.cap)
if d.deletes != 0 {
d.all_deleted = v_realloc(d.all_deleted, d.cap)
C.memset(d.all_deleted + d.len, 0, d.cap - d.len)
}
}
}
push_index := d.len
unsafe {
if d.deletes != 0 {
d.all_deleted[push_index] = 0
}
ptr := d.key(push_index)
C.memcpy(ptr, key, d.key_bytes)
C.memcpy(byteptr(ptr) + d.key_bytes, value, d.value_bytes)
Expand All @@ -175,6 +184,8 @@ fn (mut d DenseArray) zeros_to_end() {
}
free(tmp_buf)
d.deletes = 0
// TODO: reallocate instead as more deletes are likely
free(d.all_deleted)
d.len = count
d.cap = if count < 8 { 8 } else { count }
unsafe {
Expand Down Expand Up @@ -468,12 +479,14 @@ pub fn (mut m map) delete(key string) {
index += 2
}
m.len--
unsafe {
m.metas[index] = 0
if m.key_values.deletes == 0 {
m.key_values.all_deleted = C.calloc(1, m.cap) // sets to 0
}
m.key_values.deletes++
// Mark key as deleted
unsafe {
m.key_values.all_deleted[kv_index] = 1
m.metas[index] = 0
// Mark key as deleted
(*pkey).free()
C.memset(pkey, 0, sizeof(string))
}
Expand All @@ -484,7 +497,6 @@ pub fn (mut m map) delete(key string) {
if m.key_values.deletes >= (m.key_values.len >> 1) {
m.key_values.zeros_to_end()
m.rehash()
m.key_values.deletes = 0
}
return
}
Expand Down Expand Up @@ -525,7 +537,14 @@ pub fn (d DenseArray) clone() DenseArray {
cap: d.cap
len: d.len
deletes: d.deletes
data: unsafe {memdup(d.data, d.cap * d.slot_bytes)}
all_deleted: 0
data: 0
}
unsafe {
if d.deletes != 0 {
res.all_deleted = memdup(d.all_deleted, d.cap)
}
res.data = memdup(d.data, d.cap * d.slot_bytes)
}
// FIXME clone each key
return res
Expand Down Expand Up @@ -568,6 +587,7 @@ pub fn (m &map) free() {
(*pkey).free()
}
}
unsafe {free(m.key_values.all_deleted)}
}
unsafe {free(m.key_values.data)}
}
2 changes: 1 addition & 1 deletion vlib/builtin/map_test.v
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const (
)

fn unique_strings(arr_len int, str_len int) []string {
mut arr := []string{}
mut arr := []string{cap: arr_len}
for arr.len < arr_len {
str := rand.string(str_len)
if str !in arr {
Expand Down

0 comments on commit ae460a2

Please sign in to comment.