aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2017-03-09 16:23:04 +0100
committerGuilherme Andrade <[email protected]>2017-03-22 23:57:55 +0000
commit5e18e917f29ed46caffa1211eb52ade01d24366a (patch)
treee38aba943e590b5b9f18173d79493d4b0c2a257b
parent865f06f93db7a68533bbdc4c961dd45699d6a07f (diff)
downloadotp-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.c3
-rw-r--r--erts/emulator/beam/erl_db_tree.c11
-rw-r--r--erts/emulator/beam/erl_db_util.c7
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);