diff options
author | Sverker Eriksson <[email protected]> | 2017-03-09 16:23:04 +0100 |
---|---|---|
committer | Guilherme Andrade <[email protected]> | 2017-03-22 23:57:55 +0000 |
commit | 5e18e917f29ed46caffa1211eb52ade01d24366a (patch) | |
tree | e38aba943e590b5b9f18173d79493d4b0c2a257b | |
parent | 865f06f93db7a68533bbdc4c961dd45699d6a07f (diff) | |
download | otp-5e18e917f29ed46caffa1211eb52ade01d24366a.tar.gz otp-5e18e917f29ed46caffa1211eb52ade01d24366a.tar.bz2 otp-5e18e917f29ed46caffa1211eb52ade01d24366a.zip |
erts: Optimize ets:select_replace to not use heap
for temporary matchspec results.
ToDo: Would be even nicer if PAM could allocate and build
the ETS objects without extra copy_struct needed.
-rw-r--r-- | erts/emulator/beam/erl_db_hash.c | 3 | ||||
-rw-r--r-- | erts/emulator/beam/erl_db_tree.c | 11 | ||||
-rw-r--r-- | erts/emulator/beam/erl_db_util.c | 7 |
3 files changed, 17 insertions, 4 deletions
diff --git a/erts/emulator/beam/erl_db_hash.c b/erts/emulator/beam/erl_db_hash.c index 569419265b..92b833468d 100644 --- a/erts/emulator/beam/erl_db_hash.c +++ b/erts/emulator/beam/erl_db_hash.c @@ -2144,9 +2144,10 @@ static int mtraversal_select_replace_on_match_res(void* context_ptr, Sint slot_i #endif next = (**current_ptr_ptr)->next; hval = (**current_ptr_ptr)->hvalue; - new = replace_dbterm(tb, **current_ptr_ptr, match_res); + new = new_dbterm(tb, match_res); new->next = next; new->hvalue = hval; + free_term(tb, **current_ptr_ptr); **current_ptr_ptr = new; /* replace 'next' pointer in previous object */ *current_ptr_ptr = &((**current_ptr_ptr)->next); /* advance to next object */ return 1; diff --git a/erts/emulator/beam/erl_db_tree.c b/erts/emulator/beam/erl_db_tree.c index fadd63be34..60bf7fc979 100644 --- a/erts/emulator/beam/erl_db_tree.c +++ b/erts/emulator/beam/erl_db_tree.c @@ -3473,13 +3473,20 @@ static int doit_select_replace(DbTableTree *tb, TreeDbTerm **this, void *ptr, &(*this)->dbterm, NULL, 0); if (is_value(ret)) { + TreeDbTerm* new; + TreeDbTerm* old = *this; #ifdef DEBUG Eterm key = db_getkey(tb->common.keypos, ret); ASSERT(is_value(key)); ASSERT(cmp_key(tb, key, old) == 0); #endif - *this = replace_dbterm(tb, *this, ret); - sc->lastobj = (*this)->dbterm.tpl; + new = new_dbterm(tb, ret); + new->left = old->left; + new->right = old->right; + new->balance = old->balance; + sc->lastobj = new->dbterm.tpl; + *this = new; + free_term(tb, old); ++(sc->replaced); } if (--(sc->max) <= 0) { diff --git a/erts/emulator/beam/erl_db_util.c b/erts/emulator/beam/erl_db_util.c index d4dbe3d434..03cc11bdc4 100644 --- a/erts/emulator/beam/erl_db_util.c +++ b/erts/emulator/beam/erl_db_util.c @@ -5332,6 +5332,7 @@ void db_free_tmp_uncompressed(DbTerm* obj) Eterm db_match_dbterm(DbTableCommon* tb, Process* c_p, Binary* bprog, int all, DbTerm* obj, Eterm** hpp, Uint extra) { + enum erts_pam_run_flags flags; Uint32 dummy; Eterm res; @@ -5339,9 +5340,13 @@ Eterm db_match_dbterm(DbTableCommon* tb, Process* c_p, Binary* bprog, obj = db_alloc_tmp_uncompressed(tb, obj); } + flags = (hpp ? + ERTS_PAM_COPY_RESULT | ERTS_PAM_CONTIGUOUS_TUPLE : + ERTS_PAM_TMP_RESULT | ERTS_PAM_CONTIGUOUS_TUPLE); + res = db_prog_match(c_p, c_p, bprog, make_tuple(obj->tpl), NULL, 0, - ERTS_PAM_COPY_RESULT|ERTS_PAM_CONTIGUOUS_TUPLE, &dummy); + flags, &dummy); if (is_value(res) && hpp!=NULL) { *hpp = HAlloc(c_p, extra); |