map: make DenseArray.has_index not assume string keys (#7284)
parent
4324be9bd8
commit
ae460a2208
|
@ -100,7 +100,10 @@ mut:
|
||||||
cap int
|
cap int
|
||||||
len int
|
len int
|
||||||
deletes u32 // count
|
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]
|
[inline]
|
||||||
|
@ -115,6 +118,7 @@ fn new_dense_array(key_bytes int, value_bytes int) DenseArray {
|
||||||
cap: cap
|
cap: cap
|
||||||
len: 0
|
len: 0
|
||||||
deletes: 0
|
deletes: 0
|
||||||
|
all_deleted: 0
|
||||||
data: malloc(cap * slot_bytes)
|
data: malloc(cap * slot_bytes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,9 +136,7 @@ fn (d &DenseArray) value(i int) voidptr {
|
||||||
|
|
||||||
[inline]
|
[inline]
|
||||||
fn (d &DenseArray) has_index(i int) bool {
|
fn (d &DenseArray) has_index(i int) bool {
|
||||||
// assume string keys for now
|
return d.deletes == 0 || unsafe {d.all_deleted[i]} == 0
|
||||||
pkey := unsafe {&string(d.key(i))}
|
|
||||||
return pkey.str != 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push element to array and return index
|
// Push element to array and return index
|
||||||
|
@ -145,10 +147,17 @@ fn (mut d DenseArray) push(key voidptr, value voidptr) int {
|
||||||
d.cap += d.cap >> 3
|
d.cap += d.cap >> 3
|
||||||
unsafe {
|
unsafe {
|
||||||
d.data = v_realloc(d.data, d.slot_bytes * d.cap)
|
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
|
push_index := d.len
|
||||||
unsafe {
|
unsafe {
|
||||||
|
if d.deletes != 0 {
|
||||||
|
d.all_deleted[push_index] = 0
|
||||||
|
}
|
||||||
ptr := d.key(push_index)
|
ptr := d.key(push_index)
|
||||||
C.memcpy(ptr, key, d.key_bytes)
|
C.memcpy(ptr, key, d.key_bytes)
|
||||||
C.memcpy(byteptr(ptr) + d.key_bytes, value, d.value_bytes)
|
C.memcpy(byteptr(ptr) + d.key_bytes, value, d.value_bytes)
|
||||||
|
@ -175,6 +184,8 @@ fn (mut d DenseArray) zeros_to_end() {
|
||||||
}
|
}
|
||||||
free(tmp_buf)
|
free(tmp_buf)
|
||||||
d.deletes = 0
|
d.deletes = 0
|
||||||
|
// TODO: reallocate instead as more deletes are likely
|
||||||
|
free(d.all_deleted)
|
||||||
d.len = count
|
d.len = count
|
||||||
d.cap = if count < 8 { 8 } else { count }
|
d.cap = if count < 8 { 8 } else { count }
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -468,12 +479,14 @@ pub fn (mut m map) delete(key string) {
|
||||||
index += 2
|
index += 2
|
||||||
}
|
}
|
||||||
m.len--
|
m.len--
|
||||||
unsafe {
|
if m.key_values.deletes == 0 {
|
||||||
m.metas[index] = 0
|
m.key_values.all_deleted = C.calloc(1, m.cap) // sets to 0
|
||||||
}
|
}
|
||||||
m.key_values.deletes++
|
m.key_values.deletes++
|
||||||
// Mark key as deleted
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
m.key_values.all_deleted[kv_index] = 1
|
||||||
|
m.metas[index] = 0
|
||||||
|
// Mark key as deleted
|
||||||
(*pkey).free()
|
(*pkey).free()
|
||||||
C.memset(pkey, 0, sizeof(string))
|
C.memset(pkey, 0, sizeof(string))
|
||||||
}
|
}
|
||||||
|
@ -484,7 +497,6 @@ pub fn (mut m map) delete(key string) {
|
||||||
if m.key_values.deletes >= (m.key_values.len >> 1) {
|
if m.key_values.deletes >= (m.key_values.len >> 1) {
|
||||||
m.key_values.zeros_to_end()
|
m.key_values.zeros_to_end()
|
||||||
m.rehash()
|
m.rehash()
|
||||||
m.key_values.deletes = 0
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -525,7 +537,14 @@ pub fn (d DenseArray) clone() DenseArray {
|
||||||
cap: d.cap
|
cap: d.cap
|
||||||
len: d.len
|
len: d.len
|
||||||
deletes: d.deletes
|
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
|
// FIXME clone each key
|
||||||
return res
|
return res
|
||||||
|
@ -568,6 +587,7 @@ pub fn (m &map) free() {
|
||||||
(*pkey).free()
|
(*pkey).free()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
unsafe {free(m.key_values.all_deleted)}
|
||||||
}
|
}
|
||||||
unsafe {free(m.key_values.data)}
|
unsafe {free(m.key_values.data)}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
fn unique_strings(arr_len int, str_len int) []string {
|
fn unique_strings(arr_len int, str_len int) []string {
|
||||||
mut arr := []string{}
|
mut arr := []string{cap: arr_len}
|
||||||
for arr.len < arr_len {
|
for arr.len < arr_len {
|
||||||
str := rand.string(str_len)
|
str := rand.string(str_len)
|
||||||
if str !in arr {
|
if str !in arr {
|
||||||
|
|
Loading…
Reference in New Issue