aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/erl_map.c
diff options
context:
space:
mode:
authorBjörn-Egil Dahlberg <[email protected]>2015-03-10 09:04:56 +0100
committerBjörn-Egil Dahlberg <[email protected]>2015-03-12 19:15:33 +0100
commit3fdd4046c4306256233984e289898f24324273f9 (patch)
tree89705f481c20aa74c20d2c81916a6d23d566bb97 /erts/emulator/beam/erl_map.c
parent7478569d0a7d619d600816f3a75e56922d8ed428 (diff)
downloadotp-3fdd4046c4306256233984e289898f24324273f9.tar.gz
otp-3fdd4046c4306256233984e289898f24324273f9.tar.bz2
otp-3fdd4046c4306256233984e289898f24324273f9.zip
erts: Add hashmap_iterator_prev to maps
Diffstat (limited to 'erts/emulator/beam/erl_map.c')
-rw-r--r--erts/emulator/beam/erl_map.c45
1 files changed, 45 insertions, 0 deletions
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];