•HashMap delete with backwards shift; no key/value compaction yet
This commit is contained in:
parent
ce9f460e2c
commit
95f5e65b6c
@ -686,12 +686,12 @@ B hashmap_lookup(B* vars, B w, B x) {
|
||||
void hashmap_set(B* vars, B w, B x) {
|
||||
HashMap* map = c(HashMap, vars[2]);
|
||||
u64* hp = map->a; u64 sh = map->sh;
|
||||
usz i = map->pop;
|
||||
if (i>>(64-3-sh)>7 || hp[map->sz-1]!=empty) { // keep load <= 7/8
|
||||
if (map->pop>>(64-3-sh)>7 || hp[map->sz-1]!=empty) { // keep load <= 7/8
|
||||
map=hashmap_resize(map);
|
||||
vars[2] = tag(map, OBJ_TAG);
|
||||
hp=map->a; sh=map->sh;
|
||||
}
|
||||
usz i = IA(vars[0]);
|
||||
B* keys = harr_ptr(vars[0]);
|
||||
HASHMAP_INSERT(
|
||||
w,
|
||||
@ -701,3 +701,24 @@ void hashmap_set(B* vars, B w, B x) {
|
||||
vars[0] = vec_addN(vars[0], w);
|
||||
vars[1] = vec_addN(vars[1], x);
|
||||
}
|
||||
|
||||
void hashmap_delete(B* vars, B x) {
|
||||
HashMap* map = c(HashMap, vars[2]);
|
||||
u64* hp = map->a; u64 sh = map->sh;
|
||||
B kb = vars[0]; B* keys = harr_ptr(kb);
|
||||
HASHMAP_FIND(x,
|
||||
dec(x);
|
||||
do {
|
||||
u64 jp=j; j++;
|
||||
u=hp[j]; if (u>>sh==j) u=empty;
|
||||
hp[jp]=u;
|
||||
} while (u!=empty);
|
||||
B vb = vars[1];
|
||||
if (!reusable(kb)) { vars[0]=kb=taga(cpyHArr(kb)); keys=harr_ptr(kb); }
|
||||
if (!reusable(vb)) { vars[1]=vb=taga(cpyHArr(vb)); }
|
||||
usz p = --(map->pop); dec(keys[i]); keys[i]=bi_N;
|
||||
B* s = harr_ptr(vb)+i; dec(*s); *s=bi_N;
|
||||
return;
|
||||
)
|
||||
thrM("(hashmap).Delete: key not found");
|
||||
}
|
||||
|
||||
@ -711,16 +711,19 @@ static Body* hashmap_ns;
|
||||
static B hashmap_getName; static NFnDesc* hashmap_getDesc;
|
||||
static B hashmap_hasName; static NFnDesc* hashmap_hasDesc;
|
||||
static B hashmap_setName; static NFnDesc* hashmap_setDesc;
|
||||
static B hashmap_deleteName; static NFnDesc* hashmap_deleteDesc;
|
||||
static B hashmap_countName; static NFnDesc* hashmap_countDesc;
|
||||
// Hash object handling defined in search.c
|
||||
extern B hashmap_build(B keys, usz n);
|
||||
extern B hashmap_lookup(B* vars, B w, B x);
|
||||
extern void hashmap_set(B* vars, B w, B x);
|
||||
extern void hashmap_delete(B* vars, B x);
|
||||
extern usz hashmap_count(B hash);
|
||||
#define VARS c(NS,nfn_objU(t))->sc->vars
|
||||
B hashmap_get_c1(B t, B x ) { return hashmap_lookup(VARS, bi_N, x); }
|
||||
B hashmap_get_c2(B t, B w, B x) { return hashmap_lookup(VARS, w, x); }
|
||||
B hashmap_set_c2(B t, B w, B x) { hashmap_set(VARS, w, x); return inc(nfn_objU(t)); }
|
||||
B hashmap_delete_c1(B t, B x ) { hashmap_delete(VARS, x); return inc(nfn_objU(t)); }
|
||||
B hashmap_count_c1(B t, B x) { dec(x); return m_usz(hashmap_count(VARS[2])); }
|
||||
B hashmap_has_c1(B t, B x) {
|
||||
B l = hashmap_lookup(VARS, bi_noVar, x);
|
||||
@ -729,12 +732,13 @@ B hashmap_has_c1(B t, B x) {
|
||||
}
|
||||
#undef VARS
|
||||
static NOINLINE void hashmap_init() {
|
||||
hashmap_ns = m_nnsDesc("keys", "vals", "hash", "get", "has", "set", "count");
|
||||
hashmap_ns = m_nnsDesc("keys", "vals", "hash", "get", "has", "set", "delete", "count");
|
||||
NSDesc* d = hashmap_ns->nsDesc;
|
||||
for (usz i = 0; i < 3; i++) d->expGIDs[i] = -1;
|
||||
hashmap_getName = m_c8vec_0("get"); gc_add(hashmap_getName); hashmap_getDesc = registerNFn(m_c8vec_0("(hashmap).Get"), hashmap_get_c1, hashmap_get_c2);
|
||||
hashmap_hasName = m_c8vec_0("has"); gc_add(hashmap_hasName); hashmap_hasDesc = registerNFn(m_c8vec_0("(hashmap).Has"), hashmap_has_c1, c2_bad);
|
||||
hashmap_setName = m_c8vec_0("set"); gc_add(hashmap_setName); hashmap_setDesc = registerNFn(m_c8vec_0("(hashmap).Set"), c1_bad, hashmap_set_c2);
|
||||
hashmap_deleteName = m_c8vec_0("delete"); gc_add(hashmap_deleteName); hashmap_deleteDesc = registerNFn(m_c8vec_0("(hashmap).Delete"), hashmap_delete_c1, c2_bad);
|
||||
hashmap_countName = m_c8vec_0("count"); gc_add(hashmap_countName); hashmap_countDesc = registerNFn(m_c8vec_0("(hashmap).Count"), hashmap_count_c1, c2_bad);
|
||||
}
|
||||
B hashMap_c2(B t, B w, B x) {
|
||||
@ -744,9 +748,9 @@ B hashMap_c2(B t, B w, B x) {
|
||||
if (hashmap_ns==NULL) hashmap_init();
|
||||
w = taga(toHArr(w)); x = taga(toHArr(x));
|
||||
B h = hashmap_build(w, n);
|
||||
B ns = m_nns(hashmap_ns, w, x, h, m_nfn(hashmap_getDesc, bi_N), m_nfn(hashmap_hasDesc, bi_N), m_nfn(hashmap_setDesc, bi_N), m_nfn(hashmap_countDesc, bi_N));
|
||||
B ns = m_nns(hashmap_ns, w, x, h, m_nfn(hashmap_getDesc, bi_N), m_nfn(hashmap_hasDesc, bi_N), m_nfn(hashmap_setDesc, bi_N), m_nfn(hashmap_deleteDesc, bi_N), m_nfn(hashmap_countDesc, bi_N));
|
||||
Scope* sc = c(NS,ns)->sc;
|
||||
for (usz i = 3; i < 7; i++) nfn_swapObj(sc->vars[i], incG(ns));
|
||||
for (usz i = 3; i < 8; i++) nfn_swapObj(sc->vars[i], incG(ns));
|
||||
return ns;
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user