Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Even more scalable ETS ordered_set with write_concurrency #1997


None yet
1 participant
Copy link

commented Oct 23, 2018

This is a continuation on #1952 by @kjellwinblad already merged to master for OTP-22.

#1952 introduced actual scalable write_concurrency for ordered_set tables with a novel data structure called contention adapting search tree.

The implementation did however use a fallback method for functions like ets:select accessing multiple keys, where all sub-trees were first merged into one and the old implementation then called. This PR lifts that restriction and all ets functions now operate on the contention adapting search tree without collapsing it.

Here are some benchmarks showing all access patterns now perform well, including those containing "selectAll" and "partial_select1000".

sverker added some commits Oct 8, 2018

erts: Refactor ets:select* bound key lookup
Move lookup from analyze_pattern to callers.
erts: Remove tree merging for ets:slot
Brute force solution will always iterate tree from slot 0 and forward.

ToDo1: Yield.
ToDo2: Maybe optimize by caching AVL tree size in each base node.
erts: Add erts_debug feature 'ets_force_split'
to easier generate a routing tree for test
without having to spend cpu to provoke actual repeated lock conflicts.
erts: Implement ets:info(T, stats) for catrees
{RouteNodes, BaseNodes, MaxRouteTreeDepth}
erts: Optimize find_next/prev_from_pb_key
to not have to backtrack up on the stack.
erts: Do contention adaptions during (updating) iterations
Once an iteration key has been found, never fall back to first/last key in
next/prev tree as trees may split or join under our feet. I.e we must always
use previous key when searching for the next key.
erts: Fix lc_key in base nodes
to actually pass the copy to lock checker.
erts: Fix faulty assert in catree_find_nextprev_root
It's possible to first find an empty base node
and then retry and find the same base node as invalid.

It's a benign race with join which first makes the old invalid
'neighbor' accessible from 'gparent' before replacing it with
erts: Refactor away function generating macros in erl_db_catree.c
Easier to read and debug, and about the same lines of code.

@sverker sverker self-assigned this Oct 23, 2018

sverker added some commits Oct 23, 2018

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.
erts: Remove lock ordering of catree base nodes
We no longer lock more than one base node at a time.
We do however trylock a second base node at join.

sverker added some commits Oct 26, 2018

stdlib: Improve stim_cat_ord_set in ets_SUITE
to generate a routing tree with keys that fit each test case.
stdlib: Add ets_SUITE:smp_ordered_iteration
to provoke iteration over a moving ordered_set with write_concurrency
and make sure we hit all "stable" keys.

@sverker sverker merged commit fa6994f into erlang:master Oct 31, 2018

1 of 2 checks passed

continuous-integration/travis-ci/pr The Travis CI build is in progress
license/cla Contributor License Agreement is signed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.