Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:23
erlang
2061-erts-Refactor-ETS-matching.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 2061-erts-Refactor-ETS-matching.patch of Package erlang
From 709b4521019c30281281b4938a0f9354c747e037 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson <sverker@erlang.org> Date: Tue, 22 Sep 2020 20:22:26 +0200 Subject: [PATCH 1/2] erts: Refactor ETS matching Move out HAlloc of cons cell to the code that actualy needs it. --- erts/emulator/beam/erl_db_hash.c | 52 ++++++++++++++++++-------------- erts/emulator/beam/erl_db_tree.c | 14 ++++----- erts/emulator/beam/erl_db_util.c | 17 +++-------- erts/emulator/beam/erl_db_util.h | 4 +-- 4 files changed, 43 insertions(+), 44 deletions(-) diff --git a/erts/emulator/beam/erl_db_hash.c b/erts/emulator/beam/erl_db_hash.c index 79480a0c03..443827bc0c 100644 --- a/erts/emulator/beam/erl_db_hash.c +++ b/erts/emulator/beam/erl_db_hash.c @@ -1239,6 +1239,7 @@ struct traverse_context_t_ Eterm tid; Eterm* prev_continuation_tptr; enum DbIterSafety safety; + enum erts_pam_run_flags pam_flags; }; @@ -1250,7 +1251,6 @@ static int match_traverse(traverse_context_t* ctx, extra_match_validator_t extra_match_validator, /* Optional */ Sint chunk_size, /* If 0, no chunking */ Sint iterations_left, /* Nr. of iterations left */ - Eterm** hpp, /* Heap */ int lock_for_write, /* Set to 1 if we're going to delete or modify existing terms */ Eterm* ret) @@ -1326,7 +1326,7 @@ static int match_traverse(traverse_context_t* ctx, if (tb->common.compress) obj = db_alloc_tmp_uncompressed(&tb->common, obj); match_res = db_match_dbterm_uncompressed(&tb->common, ctx->p, mpi.mp, - obj, hpp, 2); + obj, ctx->pam_flags); saved_current = *current_ptr; if (ctx->on_match_res(ctx, slot_ix, ¤t_ptr, match_res)) { ++got; @@ -1396,7 +1396,6 @@ done: static int match_traverse_continue(traverse_context_t* ctx, Sint chunk_size, /* If 0, no chunking */ Sint iterations_left, /* Nr. of iterations left */ - Eterm** hpp, /* Heap */ Sint slot_ix, /* Slot index to resume traversal from */ Sint got, /* Matched terms counter */ Binary** mpp, /* Existing match program */ @@ -1451,7 +1450,7 @@ static int match_traverse_continue(traverse_context_t* ctx, if (tb->common.compress) obj = db_alloc_tmp_uncompressed(&tb->common, obj); match_res = db_match_dbterm_uncompressed(&tb->common, ctx->p, *mpp, - obj, hpp, 2); + obj, ctx->pam_flags); saved_current = *current_ptr; if (ctx->on_match_res(ctx, slot_ix, ¤t_ptr, match_res)) { ++got; @@ -1593,7 +1592,6 @@ static ERTS_INLINE int unpack_simple_continuation(Eterm continuation, typedef struct { traverse_context_t base; - Eterm* hp; Sint chunk_size; Eterm match_list; } select_chunk_context_t; @@ -1611,7 +1609,8 @@ static int select_chunk_on_match_res(traverse_context_t* ctx_base, Sint slot_ix, { select_chunk_context_t* ctx = (select_chunk_context_t*) ctx_base; if (is_value(match_res)) { - ctx->match_list = CONS(ctx->hp, match_res, ctx->match_list); + Eterm* hp = HAlloc(ctx->base.p, 2); + ctx->match_list = CONS(hp, match_res, ctx->match_list); return 1; } return 0; @@ -1638,6 +1637,7 @@ static int select_chunk_on_loop_ended(traverse_context_t* ctx_base, Eterm continuation; Eterm rest = NIL; Sint rest_size = 0; + Eterm* hp; if (got > ctx->chunk_size) { /* Split list in return value and 'rest' */ Eterm tmp = ctx->match_list; @@ -1653,29 +1653,29 @@ static int select_chunk_on_loop_ended(traverse_context_t* ctx_base, } if (rest != NIL || slot_ix >= 0) { /* Need more calls */ Eterm tid = ctx->base.tid; - ctx->hp = HAllocX(ctx->base.p, + hp = HAllocX(ctx->base.p, 3 + 7 + ERTS_MAGIC_REF_THING_SIZE, ERTS_MAGIC_REF_THING_SIZE); - mpb = erts_db_make_match_prog_ref(ctx->base.p, *mpp, &ctx->hp); + mpb = erts_db_make_match_prog_ref(ctx->base.p, *mpp, &hp); if (is_atom(tid)) tid = erts_db_make_tid(ctx->base.p, &ctx->base.tb->common); continuation = TUPLE6( - ctx->hp, + hp, tid, make_small(slot_ix), make_small(ctx->chunk_size), mpb, rest, make_small(rest_size)); *mpp = NULL; /* Otherwise the caller will destroy it */ - ctx->hp += 7; - *ret = TUPLE2(ctx->hp, ctx->match_list, continuation); + hp += 7; + *ret = TUPLE2(hp, ctx->match_list, continuation); return DB_ERROR_NONE; } else { /* All data is exhausted */ if (ctx->match_list != NIL) { /* No more data to search but still a result to return to the caller */ - ctx->hp = HAlloc(ctx->base.p, 3); - *ret = TUPLE2(ctx->hp, ctx->match_list, am_EOT); + hp = HAlloc(ctx->base.p, 3); + *ret = TUPLE2(hp, ctx->match_list, am_EOT); return DB_ERROR_NONE; } else { /* Reached the end of the ttable with no data to return */ *ret = am_EOT; @@ -1757,7 +1757,7 @@ static int db_select_chunk_hash(Process *p, DbTable *tbl, Eterm tid, ctx.base.tid = tid; ctx.base.prev_continuation_tptr = NULL; ctx.base.safety = safety; - ctx.hp = NULL; + ctx.base.pam_flags = ERTS_PAM_COPY_RESULT; ctx.chunk_size = chunk_size; ctx.match_list = NIL; @@ -1766,7 +1766,7 @@ static int db_select_chunk_hash(Process *p, DbTable *tbl, Eterm tid, pattern, NULL, ctx.chunk_size, MAX_SELECT_CHUNK_ITERATIONS, - &ctx.hp, 0, + 0, ret); } @@ -1887,13 +1887,13 @@ static int db_select_continue_hash(Process* p, DbTable* tbl, Eterm continuation, ctx.base.tid = tid; ctx.base.prev_continuation_tptr = tptr; ctx.base.safety = *safety_p; - ctx.hp = NULL; + ctx.base.pam_flags = ERTS_PAM_COPY_RESULT; ctx.chunk_size = chunk_size; ctx.match_list = match_list; return match_traverse_continue( &ctx.base, ctx.chunk_size, - iterations_left, &ctx.hp, slot_ix, got, &mp, 0, + iterations_left, slot_ix, got, &mp, 0, ret); badparam: @@ -1963,11 +1963,12 @@ static int db_select_count_hash(Process *p, DbTable *tbl, Eterm tid, ctx.tid = tid; ctx.prev_continuation_tptr = NULL; ctx.safety = safety; + ctx.pam_flags = ERTS_PAM_TMP_RESULT; return match_traverse( &ctx, pattern, NULL, - chunk_size, iterations_left, NULL, 0, + chunk_size, iterations_left, 0, ret); } @@ -2001,11 +2002,12 @@ static int db_select_count_continue_hash(Process* p, DbTable* tbl, ctx.tid = tid; ctx.prev_continuation_tptr = tptr; ctx.safety = *safety_p; + ctx.pam_flags = ERTS_PAM_TMP_RESULT; return match_traverse_continue( &ctx, chunk_size, MAX_SELECT_COUNT_ITERATIONS, - NULL, slot_ix, got, &mp, 0, + slot_ix, got, &mp, 0, ret); } @@ -2109,6 +2111,7 @@ static int db_select_delete_hash(Process *p, DbTable *tbl, Eterm tid, ctx.base.tid = tid; ctx.base.prev_continuation_tptr = NULL; ctx.base.safety = safety; + ctx.base.pam_flags = ERTS_PAM_TMP_RESULT; ctx.fixated_by_me = ctx.base.tb->common.is_thread_safe ? 0 : 1; ctx.last_pseudo_delete = (Uint) -1; ctx.free_us = NULL; @@ -2117,7 +2120,7 @@ static int db_select_delete_hash(Process *p, DbTable *tbl, Eterm tid, &ctx.base, pattern, NULL, chunk_size, - MAX_SELECT_DELETE_ITERATIONS, NULL, 1, + MAX_SELECT_DELETE_ITERATIONS, 1, ret); } @@ -2150,6 +2153,7 @@ static int db_select_delete_continue_hash(Process* p, DbTable* tbl, ctx.base.tid = tid; ctx.base.prev_continuation_tptr = tptr; ctx.base.safety = *safety_p; + ctx.base.pam_flags = ERTS_PAM_TMP_RESULT; ctx.fixated_by_me = ONLY_WRITER(p, ctx.base.tb) ? 0 : 1; ctx.last_pseudo_delete = (Uint) -1; ctx.free_us = NULL; @@ -2157,7 +2161,7 @@ static int db_select_delete_continue_hash(Process* p, DbTable* tbl, return match_traverse_continue( &ctx.base, chunk_size, MAX_SELECT_DELETE_ITERATIONS, - NULL, slot_ix, got, &mp, 1, + slot_ix, got, &mp, 1, ret); } @@ -2251,12 +2255,13 @@ static int db_select_replace_hash(Process *p, DbTable *tbl, Eterm tid, ctx.tid = tid; ctx.prev_continuation_tptr = NULL; ctx.safety = safety; + ctx.pam_flags = ERTS_PAM_TMP_RESULT; return match_traverse( &ctx, pattern, db_match_keeps_key, chunk_size, - MAX_SELECT_REPLACE_ITERATIONS, NULL, 1, + MAX_SELECT_REPLACE_ITERATIONS, 1, ret); } @@ -2291,11 +2296,12 @@ static int db_select_replace_continue_hash(Process* p, DbTable* tbl, ctx.tid = tid; ctx.prev_continuation_tptr = tptr; ctx.safety = *safety_p; + ctx.pam_flags = ERTS_PAM_TMP_RESULT; return match_traverse_continue( &ctx, chunk_size, MAX_SELECT_REPLACE_ITERATIONS, - NULL, slot_ix, got, &mp, 1, + slot_ix, got, &mp, 1, ret); } diff --git a/erts/emulator/beam/erl_db_tree.c b/erts/emulator/beam/erl_db_tree.c index 015232e4f3..441d22805a 100644 --- a/erts/emulator/beam/erl_db_tree.c +++ b/erts/emulator/beam/erl_db_tree.c @@ -3838,7 +3838,6 @@ static int doit_select(DbTableCommon *tb, TreeDbTerm *this, { struct select_context *sc = (struct select_context *) ptr; Eterm ret; - Eterm* hp; sc->lastobj = this->dbterm.tpl; @@ -3851,8 +3850,9 @@ static int doit_select(DbTableCommon *tb, TreeDbTerm *this, GETKEY_WITH_POS(sc->keypos, this->dbterm.tpl)) > 0))) { return 0; } - ret = db_match_dbterm(tb, sc->p,sc->mp, &this->dbterm, &hp, 2); + ret = db_match_dbterm(tb, sc->p, sc->mp, &this->dbterm, ERTS_PAM_COPY_RESULT); if (is_value(ret)) { + Eterm *hp = HAlloc(sc->p, 2); sc->accum = CONS(hp, ret, sc->accum); } if (--(sc->max) <= 0) { @@ -3876,7 +3876,7 @@ static int doit_select_count(DbTableCommon *tb, TreeDbTerm *this, GETKEY_WITH_POS(sc->keypos, this->dbterm.tpl)) > 0)) { return 0; } - ret = db_match_dbterm(tb, sc->p, sc->mp, &this->dbterm, NULL, 0); + ret = db_match_dbterm(tb, sc->p, sc->mp, &this->dbterm, ERTS_PAM_TMP_RESULT); if (ret == am_true) { ++(sc->got); } @@ -3892,7 +3892,6 @@ static int doit_select_chunk(DbTableCommon *tb, TreeDbTerm *this, { struct select_context *sc = (struct select_context *) ptr; Eterm ret; - Eterm* hp; sc->lastobj = this->dbterm.tpl; @@ -3906,8 +3905,9 @@ static int doit_select_chunk(DbTableCommon *tb, TreeDbTerm *this, return 0; } - ret = db_match_dbterm(tb, sc->p, sc->mp, &this->dbterm, &hp, 2); + ret = db_match_dbterm(tb, sc->p, sc->mp, &this->dbterm, ERTS_PAM_COPY_RESULT); if (is_value(ret)) { + Eterm *hp = HAlloc(sc->p, 2); ++(sc->got); sc->accum = CONS(hp, ret, sc->accum); } @@ -3935,7 +3935,7 @@ static int doit_select_delete(DbTableCommon *tb, TreeDbTerm *this, cmp_partly_bound(sc->end_condition, GETKEY_WITH_POS(sc->keypos, this->dbterm.tpl)) > 0) return 0; - ret = db_match_dbterm(tb, sc->p, sc->mp, &this->dbterm, NULL, 0); + ret = db_match_dbterm(tb, sc->p, sc->mp, &this->dbterm, ERTS_PAM_TMP_RESULT); if (ret == am_true) { key = GETKEY(sc->tb, this->dbterm.tpl); linkout_tree(sc->tb, sc->common.root, key, sc->stack); @@ -3967,7 +3967,7 @@ static int doit_select_replace(DbTableCommon *tb, TreeDbTerm **this, obj = &(*this)->dbterm; if (tb->compress) obj = db_alloc_tmp_uncompressed(tb, obj); - ret = db_match_dbterm_uncompressed(tb, sc->p, sc->mp, obj, NULL, 0); + ret = db_match_dbterm_uncompressed(tb, sc->p, sc->mp, obj, ERTS_PAM_TMP_RESULT); if (is_value(ret)) { TreeDbTerm* new; diff --git a/erts/emulator/beam/erl_db_util.c b/erts/emulator/beam/erl_db_util.c index 7525bd8fd5..0043996601 100644 --- a/erts/emulator/beam/erl_db_util.c +++ b/erts/emulator/beam/erl_db_util.c @@ -5334,34 +5334,27 @@ void db_free_tmp_uncompressed(DbTerm* obj) } Eterm db_match_dbterm_uncompressed(DbTableCommon* tb, Process* c_p, Binary* bprog, - DbTerm* obj, Eterm** hpp, Uint extra) + DbTerm* obj, enum erts_pam_run_flags flags) { - enum erts_pam_run_flags flags; + Uint32 dummy; Eterm res; - 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, - flags, &dummy); + flags|ERTS_PAM_CONTIGUOUS_TUPLE, &dummy); - if (is_value(res) && hpp!=NULL) { - *hpp = HAlloc(c_p, extra); - } return res; } Eterm db_match_dbterm(DbTableCommon* tb, Process* c_p, Binary* bprog, - DbTerm* obj, Eterm** hpp, Uint extra) + DbTerm* obj, enum erts_pam_run_flags flags) { Eterm res; if (tb->compress) { obj = db_alloc_tmp_uncompressed(tb, obj); } - res = db_match_dbterm_uncompressed(tb, c_p, bprog, obj, hpp, extra); + res = db_match_dbterm_uncompressed(tb, c_p, bprog, obj, flags); if (tb->compress) { db_free_tmp_uncompressed(obj); } diff --git a/erts/emulator/beam/erl_db_util.h b/erts/emulator/beam/erl_db_util.h index 5e91e1511a..aee4c3b5f6 100644 --- a/erts/emulator/beam/erl_db_util.h +++ b/erts/emulator/beam/erl_db_util.h @@ -525,9 +525,9 @@ Binary *db_match_compile(Eterm *matchexpr, Eterm *guards, /* Returns newly allocated MatchProg binary with refc == 0*/ Eterm db_match_dbterm_uncompressed(DbTableCommon* tb, Process* c_p, Binary* bprog, - DbTerm* obj, Eterm** hpp, Uint extra); + DbTerm* obj, enum erts_pam_run_flags); Eterm db_match_dbterm(DbTableCommon* tb, Process* c_p, Binary* bprog, - DbTerm* obj, Eterm** hpp, Uint extra); + DbTerm *obj, enum erts_pam_run_flags); Eterm db_prog_match(Process *p, Process *self, Binary *prog, Eterm term, -- 2.26.2
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor