diff options
author | Sverker Eriksson <[email protected]> | 2018-10-25 13:35:12 +0200 |
---|---|---|
committer | Sverker Eriksson <[email protected]> | 2018-10-26 11:57:54 +0200 |
commit | 13214aae3697d27d27d5c628997fd4a92b497f89 (patch) | |
tree | 539966cbda52ad0f8dc9b14be769bb80679843a4 | |
parent | c6af9cd30c151baaa0afb929ce6a0292607db86c (diff) | |
download | otp-13214aae3697d27d27d5c628997fd4a92b497f89.tar.gz otp-13214aae3697d27d27d5c628997fd4a92b497f89.tar.bz2 otp-13214aae3697d27d27d5c628997fd4a92b497f89.zip |
erts: Join empty base nodes in catree
The original implementation did not do this due to fear of bad
performance. But we think the negative effect of "leaking" empty
base nodes is more important to fix.
To get the bad performance a special kind of access patterns is
needed where base nodes are frequently emptied and then repopulated
soon again. ets_SUITE:throughput_benchmark for example did not show
any negative effect from this commit at all.
-rw-r--r-- | erts/emulator/beam/erl_db_catree.c | 18 | ||||
-rw-r--r-- | lib/stdlib/test/ets_SUITE.erl | 9 |
2 files changed, 15 insertions, 12 deletions
diff --git a/erts/emulator/beam/erl_db_catree.c b/erts/emulator/beam/erl_db_catree.c index 5d88c61144..1cd01e7e33 100644 --- a/erts/emulator/beam/erl_db_catree.c +++ b/erts/emulator/beam/erl_db_catree.c @@ -703,20 +703,22 @@ void wunlock_base_node(DbTableCATreeNode *base_node) static ERTS_INLINE void wunlock_adapt_base_node(DbTableCATree* tb, - DbTableCATreeNode* base_node, + DbTableCATreeNode* node, DbTableCATreeNode* parent, int current_level) { - dbg_maybe_force_splitjoin(base_node); - if (base_node->u.base.lock_statistics > ERL_DB_CATREE_HIGH_CONTENTION_LIMIT - && current_level < ERL_DB_CATREE_MAX_ROUTE_NODE_LAYER_HEIGHT) { - split_catree(tb, base_node, parent); + dbg_maybe_force_splitjoin(node); + if ((!node->u.base.root && parent && !(tb->common.status + & DB_CATREE_FORCE_SPLIT)) + || node->u.base.lock_statistics < ERL_DB_CATREE_LOW_CONTENTION_LIMIT) { + join_catree(tb, node, parent); } - else if (base_node->u.base.lock_statistics < ERL_DB_CATREE_LOW_CONTENTION_LIMIT) { - join_catree(tb, base_node, parent); + else if (node->u.base.lock_statistics > ERL_DB_CATREE_HIGH_CONTENTION_LIMIT + && current_level < ERL_DB_CATREE_MAX_ROUTE_NODE_LAYER_HEIGHT) { + split_catree(tb, node, parent); } else { - wunlock_base_node(base_node); + wunlock_base_node(node); } } diff --git a/lib/stdlib/test/ets_SUITE.erl b/lib/stdlib/test/ets_SUITE.erl index 367c7533b4..74a4f47fa9 100644 --- a/lib/stdlib/test/ets_SUITE.erl +++ b/lib/stdlib/test/ets_SUITE.erl @@ -7393,13 +7393,14 @@ stimulate_contention(Tid) -> RState = unique_rand_start(KeyRange, Seed), stim_inserter_loop(T, RState, Num), Num = ets:info(T, size), - erts_debug:set_internal_state(ets_force_split, {T, false}), ets:match_delete(T, {'$1','$1','$1'}), + 0 = ets:info(T, size), + erts_debug:set_internal_state(ets_force_split, {T, false}), case ets:info(T,stats) of {0, _, _} -> - io:format("Houston, we got a testability problem.\n" - "Someone seems to have implemented join-on-delete\n", []), - ct:fail("Join on delete?"); + io:format("No routing nodes in table?\n" + "Debug feature 'ets_force_split' does not seem to work.\n", []), + ct:fail("No ets_force_split?"); Stats -> io:format("stimulated ordered_set: ~p\n", [Stats]) end. |