parent
999fe846e5
commit
89ef316db3
|
@ -194,6 +194,8 @@ fn (mut d DenseArray) zeros_to_end() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct map {
|
pub struct map {
|
||||||
|
// Number of bytes of a key
|
||||||
|
key_bytes int
|
||||||
// Number of bytes of a value
|
// Number of bytes of a value
|
||||||
value_bytes int
|
value_bytes int
|
||||||
mut:
|
mut:
|
||||||
|
@ -219,12 +221,14 @@ pub mut:
|
||||||
|
|
||||||
fn new_map_1(value_bytes int) map {
|
fn new_map_1(value_bytes int) map {
|
||||||
metasize := int(sizeof(u32) * (init_capicity + extra_metas_inc))
|
metasize := int(sizeof(u32) * (init_capicity + extra_metas_inc))
|
||||||
|
key_bytes := int(sizeof(string))
|
||||||
return map{
|
return map{
|
||||||
|
key_bytes: key_bytes
|
||||||
value_bytes: value_bytes
|
value_bytes: value_bytes
|
||||||
cap: init_cap
|
cap: init_cap
|
||||||
cached_hashbits: max_cached_hashbits
|
cached_hashbits: max_cached_hashbits
|
||||||
shift: init_log_capicity
|
shift: init_log_capicity
|
||||||
key_values: new_dense_array(int(sizeof(string)), value_bytes)
|
key_values: new_dense_array(key_bytes, value_bytes)
|
||||||
metas: &u32(vcalloc(metasize))
|
metas: &u32(vcalloc(metasize))
|
||||||
extra_metas: extra_metas_inc
|
extra_metas: extra_metas_inc
|
||||||
len: 0
|
len: 0
|
||||||
|
@ -240,7 +244,14 @@ fn new_map_init(n int, value_bytes int, keys &string, values voidptr) map {
|
||||||
}
|
}
|
||||||
|
|
||||||
[inline]
|
[inline]
|
||||||
fn (m &map) key_to_index(key string) (u32, u32) {
|
fn (m &map) keys_eq(a voidptr, b voidptr) bool {
|
||||||
|
// assume string for now
|
||||||
|
return fast_string_eq(*&string(a), *&string(b))
|
||||||
|
}
|
||||||
|
|
||||||
|
[inline]
|
||||||
|
fn (m &map) key_to_index(pkey voidptr) (u32, u32) {
|
||||||
|
key := *&string(pkey)
|
||||||
hash := hash.wyhash_c(key.str, u64(key.len), 0)
|
hash := hash.wyhash_c(key.str, u64(key.len), 0)
|
||||||
index := hash & m.cap
|
index := hash & m.cap
|
||||||
meta := ((hash >> m.shift) & hash_mask) | probe_inc
|
meta := ((hash >> m.shift) & hash_mask) | probe_inc
|
||||||
|
@ -311,15 +322,15 @@ fn (mut m map) set(k string, value voidptr) {
|
||||||
if load_factor > max_load_factor {
|
if load_factor > max_load_factor {
|
||||||
m.expand()
|
m.expand()
|
||||||
}
|
}
|
||||||
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)
|
||||||
// While we might have a match
|
// While we might have a match
|
||||||
for meta == unsafe {m.metas[index]} {
|
for meta == unsafe {m.metas[index]} {
|
||||||
kv_index := int(unsafe {m.metas[index + 1]})
|
kv_index := int(unsafe {m.metas[index + 1]})
|
||||||
pkey := unsafe {&string(m.key_values.key(kv_index))}
|
pkey := unsafe {m.key_values.key(kv_index)}
|
||||||
if fast_string_eq(key, *pkey) {
|
if m.keys_eq(&key, pkey) {
|
||||||
unsafe {
|
unsafe {
|
||||||
pval := pkey + 1 // skip string
|
pval := byteptr(pkey) + m.key_bytes
|
||||||
C.memcpy(pval, value, m.value_bytes)
|
C.memcpy(pval, value, m.value_bytes)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
@ -327,7 +338,7 @@ fn (mut m map) set(k string, value voidptr) {
|
||||||
index += 2
|
index += 2
|
||||||
meta += probe_inc
|
meta += probe_inc
|
||||||
}
|
}
|
||||||
kv_index := m.key_values.push(key, value)
|
kv_index := m.key_values.push(&key, value)
|
||||||
m.meta_greater(index, meta, u32(kv_index))
|
m.meta_greater(index, meta, u32(kv_index))
|
||||||
m.len++
|
m.len++
|
||||||
}
|
}
|
||||||
|
@ -363,8 +374,8 @@ fn (mut m map) rehash() {
|
||||||
if !m.key_values.has_index(i) {
|
if !m.key_values.has_index(i) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
pkey := unsafe {&string(m.key_values.key(i))}
|
pkey := unsafe {m.key_values.key(i)}
|
||||||
mut index, mut meta := m.key_to_index(*pkey)
|
mut index, mut meta := m.key_to_index(pkey)
|
||||||
index, meta = m.meta_less(index, meta)
|
index, meta = m.meta_less(index, meta)
|
||||||
m.meta_greater(index, meta, u32(i))
|
m.meta_greater(index, meta, u32(i))
|
||||||
}
|
}
|
||||||
|
@ -398,12 +409,12 @@ fn (mut m map) cached_rehash(old_cap u32) {
|
||||||
// If the key exists, its respective value is returned.
|
// If the key exists, its respective value is returned.
|
||||||
fn (mut m map) get_and_set(key string, zero voidptr) voidptr {
|
fn (mut m map) get_and_set(key string, zero voidptr) voidptr {
|
||||||
for {
|
for {
|
||||||
mut index, mut meta := m.key_to_index(key)
|
mut index, mut meta := m.key_to_index(&key)
|
||||||
for {
|
for {
|
||||||
if meta == unsafe {m.metas[index]} {
|
if meta == unsafe {m.metas[index]} {
|
||||||
kv_index := int(unsafe {m.metas[index + 1]})
|
kv_index := int(unsafe {m.metas[index + 1]})
|
||||||
pkey := unsafe {&string(m.key_values.key(kv_index))}
|
pkey := unsafe {m.key_values.key(kv_index)}
|
||||||
if fast_string_eq(key, *pkey) {
|
if m.keys_eq(&key, pkey) {
|
||||||
return unsafe {byteptr(pkey) + m.key_values.key_bytes}
|
return unsafe {byteptr(pkey) + m.key_values.key_bytes}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -424,12 +435,12 @@ fn (mut m map) get_and_set(key string, zero voidptr) voidptr {
|
||||||
// the method returns a reference to its mapped value.
|
// the method returns a reference to its mapped value.
|
||||||
// If not, a zero/default value is returned.
|
// If not, a zero/default value is returned.
|
||||||
fn (m map) get(key string, zero voidptr) voidptr {
|
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 == unsafe {m.metas[index]} {
|
if meta == unsafe {m.metas[index]} {
|
||||||
kv_index := int(unsafe {m.metas[index + 1]})
|
kv_index := int(unsafe {m.metas[index + 1]})
|
||||||
pkey := unsafe {&string(m.key_values.key(kv_index))}
|
pkey := unsafe {m.key_values.key(kv_index)}
|
||||||
if fast_string_eq(key, *pkey) {
|
if m.keys_eq(&key, pkey) {
|
||||||
return unsafe {byteptr(pkey) + m.key_values.key_bytes}
|
return unsafe {byteptr(pkey) + m.key_values.key_bytes}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -444,12 +455,12 @@ fn (m map) get(key string, zero voidptr) voidptr {
|
||||||
|
|
||||||
// Checks whether a particular key exists in the map.
|
// 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 {
|
||||||
if meta == unsafe {m.metas[index]} {
|
if meta == unsafe {m.metas[index]} {
|
||||||
kv_index := int(unsafe {m.metas[index + 1]})
|
kv_index := int(unsafe {m.metas[index + 1]})
|
||||||
pkey := unsafe {&string(m.key_values.key(kv_index))}
|
pkey := unsafe {m.key_values.key(kv_index)}
|
||||||
if fast_string_eq(key, *pkey) {
|
if m.keys_eq(&key, pkey) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -464,13 +475,13 @@ fn (m map) exists(key string) bool {
|
||||||
|
|
||||||
// Removes the mapping of a particular key from the map.
|
// 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)
|
||||||
// Perform backwards shifting
|
// Perform backwards shifting
|
||||||
for meta == unsafe {m.metas[index]} {
|
for meta == unsafe {m.metas[index]} {
|
||||||
kv_index := int(unsafe {m.metas[index + 1]})
|
kv_index := int(unsafe {m.metas[index + 1]})
|
||||||
pkey := unsafe {&string(m.key_values.key(kv_index))}
|
pkey := unsafe {&string(m.key_values.key(kv_index))}
|
||||||
if fast_string_eq(key, *pkey) {
|
if m.keys_eq(&key, pkey) {
|
||||||
for (unsafe {m.metas[index + 2]} >> hashbits) > 1 {
|
for (unsafe {m.metas[index + 2]} >> hashbits) > 1 {
|
||||||
unsafe {
|
unsafe {
|
||||||
m.metas[index] = m.metas[index + 2] - probe_inc
|
m.metas[index] = m.metas[index + 2] - probe_inc
|
||||||
|
@ -554,6 +565,7 @@ pub fn (d DenseArray) clone() DenseArray {
|
||||||
pub fn (m map) clone() map {
|
pub fn (m map) clone() map {
|
||||||
metasize := int(sizeof(u32) * (m.cap + 2 + m.extra_metas))
|
metasize := int(sizeof(u32) * (m.cap + 2 + m.extra_metas))
|
||||||
res := map{
|
res := map{
|
||||||
|
key_bytes: m.key_bytes
|
||||||
value_bytes: m.value_bytes
|
value_bytes: m.value_bytes
|
||||||
cap: m.cap
|
cap: m.cap
|
||||||
cached_hashbits: m.cached_hashbits
|
cached_hashbits: m.cached_hashbits
|
||||||
|
|
Loading…
Reference in New Issue