diff options
Diffstat (limited to 'erts/emulator/beam')
-rw-r--r-- | erts/emulator/beam/erl_map.c | 54 | ||||
-rw-r--r-- | erts/emulator/beam/erl_map.h | 7 |
2 files changed, 24 insertions, 37 deletions
diff --git a/erts/emulator/beam/erl_map.c b/erts/emulator/beam/erl_map.c index e26b97d75c..97f94d90ac 100644 --- a/erts/emulator/beam/erl_map.c +++ b/erts/emulator/beam/erl_map.c @@ -453,18 +453,18 @@ Eterm erts_hashmap_from_array(Process *p, Eterm *leafs, Uint n) { } -Eterm erts_hashmap_from_ks_and_vs(Process *p, Eterm *ks, Eterm *vs, Uint n) { +Eterm erts_hashmap_from_ks_and_vs_extra(Process *p, Eterm *ks, Eterm *vs, Uint n, + Eterm key, Eterm value) { Uint32 sw, hx; - Uint i; + Uint i,sz; hxnode_t *hxns; Eterm *hp, res; - ASSERT(n > 0); - - hp = HAlloc(p, (2 * n)); + sz = (key == THE_NON_VALUE) ? n : (n + 1); + hp = HAlloc(p, 2 * sz); /* create tmp hx values and leaf ptrs */ - hxns = (hxnode_t *)erts_alloc(ERTS_ALC_T_TMP, n * sizeof(hxnode_t)); + hxns = (hxnode_t *)erts_alloc(ERTS_ALC_T_TMP, sz * sizeof(hxnode_t)); for(i = 0; i < n; i++) { hx = hashmap_make_hash(ks[i]); @@ -475,7 +475,16 @@ Eterm erts_hashmap_from_ks_and_vs(Process *p, Eterm *ks, Eterm *vs, Uint n) { hxns[i].i = i; } - res = hashmap_from_unsorted_array(p, hxns, n); + if (key != THE_NON_VALUE) { + hx = hashmap_make_hash(key); + swizzle32(sw,hx); + hxns[i].hx = sw; + hxns[i].val = CONS(hp, key, value); hp += 2; + hxns[i].skip = 1; + hxns[i].i = i; + } + + res = hashmap_from_unsorted_array(p, hxns, sz); erts_free(ERTS_ALC_T_TMP, (void *) hxns); ERTS_VERIFY_UNUSED_TEMP_ALLOC(p); @@ -1531,39 +1540,12 @@ Eterm erts_maps_put(Process *p, Eterm key, Eterm value, Eterm map) { /* the map will grow */ - if (n >= MAP_SMALL_MAP_LIMIT) { - hxnode_t *hxns; - Uint32 sw, hx; - Eterm tmp[2]; - + if (n > MAP_SMALL_MAP_LIMIT) { HRelease(p, shp + MAP_HEADER_SIZE + n, shp); - hp = HAlloc(p, (2 * (n + 1))); ks = map_get_keys(mp); vs = map_get_values(mp); - /* create tmp hx values and leaf ptrs */ - hxns = (hxnode_t *)erts_alloc(ERTS_ALC_T_TMP, (n + 1) * sizeof(hxnode_t)); - - for (i = 0; i < n; i++) { - hx = hashmap_restore_hash(tmp,0,ks[i]); - swizzle32(sw,hx); - hxns[i].hx = sw; - hxns[i].val = CONS(hp, ks[i], vs[i]); hp += 2; - hxns[i].skip = 1; - hxns[i].i = i; - } - - hx = hashmap_restore_hash(tmp,0,key); - swizzle32(sw,hx); - hxns[i].hx = sw; - hxns[i].val = CONS(hp, key, value); hp += 2; - hxns[i].skip = 1; - hxns[i].i = n; - - res = hashmap_from_unsorted_array(p, hxns, n + 1); - - erts_free(ERTS_ALC_T_TMP, (void *) hxns); - ERTS_VERIFY_UNUSED_TEMP_ALLOC(p); + res = erts_hashmap_from_ks_and_vs_extra(p,ks,vs,n,key,value); return res; } diff --git a/erts/emulator/beam/erl_map.h b/erts/emulator/beam/erl_map.h index 6a7b29fe86..d1e227183f 100644 --- a/erts/emulator/beam/erl_map.h +++ b/erts/emulator/beam/erl_map.h @@ -103,9 +103,14 @@ void hashmap_iterator_init(struct ErtsWStack_* s, Eterm node); Eterm* hashmap_iterator_next(struct ErtsWStack_* s); int hashmap_key_hash_cmp(Eterm* ap, Eterm* bp); Eterm erts_hashmap_from_array(Process *p, Eterm *leafs, Uint n); -Eterm erts_hashmap_from_ks_and_vs(Process *p, Eterm *ks, Eterm *vs, Uint n); const Eterm *erts_hashmap_get(Uint32 hx, Eterm key, Eterm map); +#define erts_hashmap_from_ks_and_vs(P, KS, VS, N) \ + erts_hashmap_from_ks_and_vs_extra((P), (KS), (VS), (N), THE_NON_VALUE, THE_NON_VALUE); + +Eterm erts_hashmap_from_ks_and_vs_extra(Process *p, Eterm *ks, Eterm *vs, Uint n, + Eterm k, Eterm v); + #if HALFWORD_HEAP const Eterm * erts_maps_get_rel(Eterm key, Eterm map, Eterm *map_base); |