diff options
author | Björn-Egil Dahlberg <[email protected]> | 2015-05-06 19:29:34 +0200 |
---|---|---|
committer | Björn-Egil Dahlberg <[email protected]> | 2015-05-07 10:17:21 +0200 |
commit | dc177967363d16c155042dbaa2c911f59f0efd55 (patch) | |
tree | 05643e592657ff127893191596aeeaae4ebff860 | |
parent | f436d84d990bb06e6bbbf55659d4f3a47bc1c556 (diff) | |
download | otp-dc177967363d16c155042dbaa2c911f59f0efd55.tar.gz otp-dc177967363d16c155042dbaa2c911f59f0efd55.tar.bz2 otp-dc177967363d16c155042dbaa2c911f59f0efd55.zip |
erts: ETS ordered_set cannot use it's optimization with Maps
The optimization cannot be used due to that the pattern cannot be ordered.
-rw-r--r-- | erts/emulator/beam/erl_db_tree.c | 2 | ||||
-rw-r--r-- | erts/emulator/beam/erl_db_util.c | 31 | ||||
-rw-r--r-- | erts/emulator/beam/erl_db_util.h | 1 |
3 files changed, 33 insertions, 1 deletions
diff --git a/erts/emulator/beam/erl_db_tree.c b/erts/emulator/beam/erl_db_tree.c index d90af46659..c7bccc78c3 100644 --- a/erts/emulator/beam/erl_db_tree.c +++ b/erts/emulator/beam/erl_db_tree.c @@ -2716,7 +2716,7 @@ static int key_given(DbTableTree *tb, Eterm pattern, TreeDbTerm **ret, *ret = this; return 1; } else if (partly_bound != NULL && key != am_Underscore && - db_is_variable(key) < 0) + db_is_variable(key) < 0 && !db_has_map(key)) *partly_bound = key; return 0; diff --git a/erts/emulator/beam/erl_db_util.c b/erts/emulator/beam/erl_db_util.c index 0fb1c397c9..be988f0621 100644 --- a/erts/emulator/beam/erl_db_util.c +++ b/erts/emulator/beam/erl_db_util.c @@ -3347,6 +3347,37 @@ int db_is_variable(Eterm obj) return N; } +/* check if node is (or contains) a map + * return 1 if node contains a map + * return 0 otherwise + */ + +int db_has_map(Eterm node) { + DECLARE_ESTACK(s); + + ESTACK_PUSH(s,node); + while (!ESTACK_ISEMPTY(s)) { + node = ESTACK_POP(s); + if (is_list(node)) { + while (is_list(node)) { + ESTACK_PUSH(s,CAR(list_val(node))); + node = CDR(list_val(node)); + } + ESTACK_PUSH(s,node); /* Non wellformed list or [] */ + } else if (is_tuple(node)) { + Eterm *tuple = tuple_val(node); + int arity = arityval(*tuple); + while(arity--) { + ESTACK_PUSH(s,*(++tuple)); + } + } else if is_map(node) { + DESTROY_ESTACK(s); + return 1; + } + } + DESTROY_ESTACK(s); + return 0; +} /* check if obj is (or contains) a variable */ /* return 1 if obj contains a variable or underscore */ diff --git a/erts/emulator/beam/erl_db_util.h b/erts/emulator/beam/erl_db_util.h index ca206c7f58..b2d5a306cb 100644 --- a/erts/emulator/beam/erl_db_util.h +++ b/erts/emulator/beam/erl_db_util.h @@ -342,6 +342,7 @@ void* db_store_term(DbTableCommon *tb, DbTerm* old, Uint offset, Eterm obj); void* db_store_term_comp(DbTableCommon *tb, DbTerm* old, Uint offset, Eterm obj); Eterm db_copy_element_from_ets(DbTableCommon* tb, Process* p, DbTerm* obj, Uint pos, Eterm** hpp, Uint extra); +int db_has_map(Eterm obj); int db_has_variable(Eterm obj); int db_is_variable(Eterm obj); void db_do_update_element(DbUpdateHandle* handle, |