From 3fdd4046c4306256233984e289898f24324273f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Tue, 10 Mar 2015 09:04:56 +0100 Subject: erts: Add hashmap_iterator_prev to maps --- erts/emulator/beam/erl_map.c | 45 ++++++++++++++++++++++++++++++++++++++++++++ erts/emulator/beam/erl_map.h | 1 + 2 files changed, 46 insertions(+) (limited to 'erts') diff --git a/erts/emulator/beam/erl_map.c b/erts/emulator/beam/erl_map.c index 5eafa69b06..65a31d3680 100644 --- a/erts/emulator/beam/erl_map.c +++ b/erts/emulator/beam/erl_map.c @@ -1758,6 +1758,51 @@ Eterm* hashmap_iterator_next(ErtsWStack* s) { } } +Eterm* hashmap_iterator_prev(ErtsWStack* s) { + Eterm node, *ptr, hdr; + Uint32 sz,i; + + for (;;) { + ASSERT(!WSTACK_ISEMPTY((*s))); + node = (Eterm) WSTACK_POP((*s)); + if (is_non_value(node)) { + return NULL; + } + switch (primary_tag(node)) { + case TAG_PRIMARY_LIST: + return list_val(node); + + case TAG_PRIMARY_BOXED: + ptr = boxed_val(node); + hdr = *ptr; + ASSERT(is_header(hdr)); + switch(hdr & _HEADER_MAP_SUBTAG_MASK) { + case HAMT_SUBTAG_HEAD_ARRAY: + ptr++; + case HAMT_SUBTAG_NODE_ARRAY: + ptr++; + i = 0; + while(i < 16) { WSTACK_PUSH((*s), (UWord)ptr[i++]); } + break; + case HAMT_SUBTAG_HEAD_BITMAP: + ptr++; + case HAMT_SUBTAG_NODE_BITMAP: + sz = hashmap_bitcount(MAP_HEADER_VAL(hdr)); + ASSERT(sz < 17); + i = 0; + ptr++; + while(i < sz) { WSTACK_PUSH((*s), (UWord)ptr[i++]); } + break; + default: + erl_exit(1, "bad header"); + } + break; + + default: + erl_exit(1, "bad hamt node"); + } + } +} const Eterm *erts_hashmap_get(Uint32 hx, Eterm key, Eterm node) { Eterm *ptr, hdr; Eterm th[2]; diff --git a/erts/emulator/beam/erl_map.h b/erts/emulator/beam/erl_map.h index 659295184d..db22d461ce 100644 --- a/erts/emulator/beam/erl_map.h +++ b/erts/emulator/beam/erl_map.h @@ -102,6 +102,7 @@ int erts_validate_and_sort_map(map_t* map); Uint hashmap_over_estimated_heap_size(Uint n); void hashmap_iterator_init(struct ErtsWStack_* s, Eterm node); Eterm* hashmap_iterator_next(struct ErtsWStack_* s); +Eterm* hashmap_iterator_prev(struct ErtsWStack_* s); int hashmap_key_hash_cmp(Eterm* ap, Eterm* bp); Eterm erts_hashmap_from_array(ErtsHeapFactory*, Eterm *leafs, Uint n, int reject_dupkeys); const Eterm *erts_hashmap_get(Uint32 hx, Eterm key, Eterm map); -- cgit v1.2.3