diff options
author | Sverker Eriksson <[email protected]> | 2010-07-06 20:28:51 +0200 |
---|---|---|
committer | Sverker Eriksson <[email protected]> | 2010-07-07 14:31:58 +0200 |
commit | ac90c289ab5ce18395c5fa53c30b38bc5f50ae1d (patch) | |
tree | d2d5c15054299553fdef69113871fe17cf2f59be /erts | |
parent | 91078fbc7b0719150a0c7749a1de9e5c0c9bbdeb (diff) | |
download | otp-ac90c289ab5ce18395c5fa53c30b38bc5f50ae1d.tar.gz otp-ac90c289ab5ce18395c5fa53c30b38bc5f50ae1d.tar.bz2 otp-ac90c289ab5ce18395c5fa53c30b38bc5f50ae1d.zip |
Fix ets:select hanging on ordered_set with empty list as key.
erl_db_tree.c incorrectly used NIL (empty list) as "lastkey" to mark
start of the iteration. A real NIL key could then cause a
select or match iteration to be restarted over and over again if the
last key before a trap happended to be NIL.
Changed NIL to THE_NON_VALUE. Should be ok as the initial key value can
never be put into any continuation tuple.
Diffstat (limited to 'erts')
-rw-r--r-- | erts/emulator/beam/erl_db_tree.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/erts/emulator/beam/erl_db_tree.c b/erts/emulator/beam/erl_db_tree.c index b6b3cabafe..96e577ed90 100644 --- a/erts/emulator/beam/erl_db_tree.c +++ b/erts/emulator/beam/erl_db_tree.c @@ -1081,11 +1081,12 @@ static int db_select_continue_tree(Process *p, static int db_select_tree(Process *p, DbTable *tbl, Eterm pattern, int reverse, Eterm *ret) { + /* Strategy: Traverse backwards to build resulting list from tail to head */ DbTableTree *tb = &tbl->tree; DbTreeStack* stack; struct select_context sc; struct mp_info mpi; - Eterm lastkey = NIL; + Eterm lastkey = THE_NON_VALUE; Eterm key; Eterm continuation; unsigned sz; @@ -1293,7 +1294,7 @@ static int db_select_count_tree(Process *p, DbTable *tbl, DbTreeStack* stack; struct select_count_context sc; struct mp_info mpi; - Eterm lastkey = NIL; + Eterm lastkey = THE_NON_VALUE; Eterm key; Eterm continuation; unsigned sz; @@ -1395,7 +1396,7 @@ static int db_select_chunk_tree(Process *p, DbTable *tbl, DbTreeStack* stack; struct select_context sc; struct mp_info mpi; - Eterm lastkey = NIL; + Eterm lastkey = THE_NON_VALUE; Eterm key; Eterm continuation; unsigned sz; @@ -1636,7 +1637,7 @@ static int db_select_delete_tree(Process *p, DbTable *tbl, DbTableTree *tb = &tbl->tree; struct select_delete_context sc; struct mp_info mpi; - Eterm lastkey = NIL; + Eterm lastkey = THE_NON_VALUE; Eterm key; Eterm continuation; unsigned sz; @@ -2628,7 +2629,7 @@ static void traverse_backwards(DbTableTree *tb, { TreeDbTerm *this, *next; - if (lastkey == NIL) { + if (lastkey == THE_NON_VALUE) { stack->pos = stack->slot = 0; if (( this = tb->root ) == NULL) { return; @@ -2666,7 +2667,7 @@ static void traverse_forward(DbTableTree *tb, { TreeDbTerm *this, *next; - if (lastkey == NIL) { + if (lastkey == THE_NON_VALUE) { stack->pos = stack->slot = 0; if (( this = tb->root ) == NULL) { return; |