You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by rn...@apache.org on 2020/08/07 09:03:24 UTC
[couchdb] branch prototype/fdb-layer-ebtree-immutable updated
(d959efb -> 5215aa3)
This is an automated email from the ASF dual-hosted git repository.
rnewson pushed a change to branch prototype/fdb-layer-ebtree-immutable
in repository https://gitbox.apache.org/repos/asf/couchdb.git.
discard d959efb add cache test
discard 81e0704 convert node ids to uuids
discard f21324e pluggable caching of inner nodes
discard be55a65 consolidate id mutation logic into one function
discard 8190602 mutate node id of non-leaf, non-root nodes on delete
discard 295e8c5 mutate node id of non-leaf, non-root nodes on insert
add ebe62b2 Only call erlfdb:set if the node changes
add f811f3f Merge pull request #3033 from apache/prototype/fdb-layer-ebtree-spurious-conflicts
add 90158ea separate out collation wrapper to avoid spurious comparisons
add 81a8db7 Merge pull request #3034 from apache/prototype/fdb-layer-collation-bugs
add 0a44446 add get_active_job_ids and get_types
add fd9557a add support for active_tasks via fabric2
add a447f07 add active_tasks for view builds using version stamps
add 0c7c77e Merge pull request #3003 from apache/add_active_tasks_fdb
add 77e1c8c Use _scheduler/jobs instead of _active_tasks in replication Elixir tests
add 5a4da50 Replace the 'true' clauses in visit with more explicit ones
add 79cb06c Allow inclusive_start/end
add 46cff24 Merge pull request #3045 from apache/prototype/fdb-layer-ebtree-enhancements
add e1b4259 Strip last_msg from logs
add 97e7a95 Add format_status/2 callback in gen_server implementations
add 52d5327 Do not log sensitive data during _cluster_setup
add 8360026 Do not log admin credentials
add e4555a4 Update config app
add 6ff2f41 Merge pull request #3031 from cloudant/clean-up-logs
add f8fdf97 Call collate for group equality
add 41d946b Merge pull request #3046 from apache/prototype/fdb-layer-ebtree-group-reduce-fix
add 8b49b0d Allow interactive requests to reopen a re-created db instance
add bd53678 Optionally add a key manager application as a dependency
add 22d857d Merge pull request #3053 from apache/aegis_key_manager_app
add 683335c Validate the result from collate_fun
add e0bcb2a Merge pull request #3055 from apache/prototype/fdb-layer-ebtree-collate-validate
add 282e858 add local_seq option to views (#3043)
add f925919 Export reduce/5
add a32bc83 Handle empty reduce batches
add 29d6498 Fix range scans over an empty tree
add 31b467c Speed up ebtree test suite without losing coverage
add bf4265e Merge pull request #3060 from apache/prototype/fdb-layer-ebtree-speedy-tests
add 042347e fixup: Build couch_js for redhat linux
add dff8bc9 Merge pull request #3057 from apache/build-fdb-couchjs-for-redhat-linux
add 51a131d Tighten expectation of members format by level
add 887e835 extra tests
add 8ddcc22 Merge pull request #3062 from apache/prototype/fdb-layer-ebtree-enhance
add a74675f Pluggable persist_fun
add 4d7149c Merge pull request #3065 from apache/prototype/fdb-layer-ebtree-persist-fun
new 9a0d67f mutate node id of non-leaf, non-root nodes on insert
new 4b9221f mutate node id of non-leaf, non-root nodes on delete
new 922c42c consolidate id mutation logic into one function
new f2a5343 pluggable caching of inner nodes
new 4bf5e30 convert node ids to uuids
new 5215aa3 add cache test
This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version. This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:
* -- * -- B -- O -- O -- O (d959efb)
\
N -- N -- N refs/heads/prototype/fdb-layer-ebtree-immutable (5215aa3)
You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.
Any revisions marked "omit" are not gone; other references still
refer to them. Any revisions marked "discard" are gone forever.
The 6 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
rebar.config.script | 4 +-
.../src/{aegis.app.src => aegis.app.src.script} | 33 +-
src/chttpd/src/chttpd_db.erl | 3 +-
src/chttpd/src/chttpd_misc.erl | 7 +-
src/chttpd/src/chttpd_node.erl | 4 +-
src/couch/include/couch_db.hrl | 3 +
src/couch/rebar.config.script | 2 +-
src/couch/src/couch_lru.erl | 5 +-
src/couch/src/couch_multidb_changes.erl | 14 +-
src/couch/src/couch_native_process.erl | 17 +-
src/couch/src/couch_proc_manager.erl | 16 +-
src/couch/src/couch_server.erl | 6 +-
src/couch/src/couch_stream.erl | 16 +-
src/couch/src/couch_work_queue.erl | 25 +-
src/couch_index/src/couch_index.erl | 19 +-
src/couch_jobs/src/couch_jobs.erl | 19 +
src/couch_jobs/src/couch_jobs_notifier.erl | 22 +-
src/couch_js/src/couch_js_native_process.erl | 18 +-
src/couch_js/src/couch_js_proc_manager.erl | 16 +-
src/couch_log/src/couch_log_config.erl | 11 +-
src/couch_log/src/couch_log_config_dyn.erl | 3 +-
src/couch_log/src/couch_log_formatter.erl | 24 +-
src/couch_log/src/couch_log_sup.erl | 2 +
src/couch_log/test/eunit/couch_log_config_test.erl | 37 +-
.../test/eunit/couch_log_formatter_test.erl | 114 +++++-
src/couch_mrview/src/couch_mrview_index.erl | 12 +
src/couch_peruser/src/couch_peruser.erl | 13 +-
.../src/couch_replicator_auth_session.erl | 2 +-
.../src/couch_replicator_httpc_pool.erl | 14 +-
src/couch_stats/src/couch_stats_aggregator.erl | 17 +-
src/couch_views/src/couch_views_indexer.erl | 60 ++-
src/couch_views/src/couch_views_server.erl | 17 +-
src/couch_views/src/couch_views_util.erl | 27 +-
.../test/couch_views_active_tasks_test.erl | 155 +++++++
src/couch_views/test/couch_views_map_test.erl | 51 ++-
src/ddoc_cache/src/ddoc_cache_entry.erl | 21 +-
src/dreyfus/src/dreyfus_index.erl | 26 +-
src/ebtree/src/ebtree.erl | 451 +++++++++++++--------
src/fabric/src/fabric2_active_tasks.erl | 51 +++
src/fabric/src/fabric2_db.erl | 8 +-
src/fabric/src/fabric2_fdb.erl | 24 +-
src/fabric/src/fabric2_server.erl | 3 +-
src/fabric/src/fabric2_txids.erl | 15 +-
src/fabric/test/fabric2_db_crud_tests.erl | 28 ++
src/fabric/test/fabric2_db_security_tests.erl | 55 ++-
src/global_changes/src/global_changes_server.erl | 11 +-
src/ken/src/ken_server.erl | 16 +-
src/setup/src/setup.erl | 2 +-
src/setup/src/setup_httpd.erl | 17 +-
test/elixir/test/map_test.exs | 27 ++
test/elixir/test/replication_test.exs | 24 +-
51 files changed, 1321 insertions(+), 266 deletions(-)
rename src/aegis/src/{aegis.app.src => aegis.app.src.script} (62%)
create mode 100644 src/couch_views/test/couch_views_active_tasks_test.erl
create mode 100644 src/fabric/src/fabric2_active_tasks.erl
[couchdb] 04/06: pluggable caching of inner nodes
Posted by rn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
rnewson pushed a commit to branch prototype/fdb-layer-ebtree-immutable
in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit f2a5343577f40777718f9064155636a57a193352
Author: Robert Newson <rn...@apache.org>
AuthorDate: Thu Jul 23 19:10:04 2020 +0100
pluggable caching of inner nodes
---
src/ebtree/src/ebtree.erl | 53 ++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 48 insertions(+), 5 deletions(-)
diff --git a/src/ebtree/src/ebtree.erl b/src/ebtree/src/ebtree.erl
index 34f42e6..7c36fa5 100644
--- a/src/ebtree/src/ebtree.erl
+++ b/src/ebtree/src/ebtree.erl
@@ -47,7 +47,8 @@
collate_fun,
reduce_fun,
encode_fun,
- persist_fun
+ persist_fun,
+ cache_fun
}).
-define(META, 0).
@@ -85,13 +86,15 @@ open(Db, Prefix, Order, Options) when is_binary(Prefix), is_integer(Order), Orde
CollateFun = proplists:get_value(collate_fun, Options, fun collate_raw/2),
EncodeFun = proplists:get_value(encode_fun, Options, fun encode_erlang/3),
PersistFun = proplists:get_value(persist_fun, Options, fun simple_persist/3),
+ CacheFun = proplists:get_value(cache_fun, Options, fun cache_noop/2),
Tree = #tree{
prefix = Prefix,
reduce_fun = ReduceFun,
collate_fun = CollateFun,
encode_fun = EncodeFun,
- persist_fun = PersistFun
+ persist_fun = PersistFun,
+ cache_fun = CacheFun
},
erlfdb:transactional(Db, fun(Tx) ->
@@ -776,9 +779,16 @@ meta_key(Prefix, MetaKey) when is_binary(Prefix) ->
%% node persistence functions
get_node(Tx, #tree{} = Tree, Id) ->
- Key = node_key(Tree#tree.prefix, Id),
- Value = persist(Tree, Tx, get, Key),
- decode_node(Tree, Id, Key, Value).
+ case cache(Tree, get, Id) of
+ undefined ->
+ Key = node_key(Tree#tree.prefix, Id),
+ Value = persist(Tree, Tx, get, Key),
+ Node = decode_node(Tree, Id, Key, Value),
+ cache(Tree, set, Node),
+ Node;
+ #node{} = Node ->
+ Node
+ end.
clear_nodes(Tx, #tree{} = Tree, Nodes) ->
@@ -789,6 +799,7 @@ clear_nodes(Tx, #tree{} = Tree, Nodes) ->
clear_node(Tx, #tree{} = Tree, #node{} = Node) ->
Key = node_key(Tree#tree.prefix, Node#node.id),
+ cache(Tree, clear, Node),
persist(Tree, Tx, clear, Key).
@@ -809,6 +820,7 @@ set_node(Tx, #tree{} = Tree, #node{} = Node) ->
validate_node(Tree, Node),
Key = node_key(Tree#tree.prefix, Node#node.id),
Value = encode_node(Tree, Key, Node),
+ cache(Tree, set, Node),
persist(Tree, Tx, set, [Key, Value]).
@@ -1026,6 +1038,37 @@ simple_persist(Tx, get, Key) ->
simple_persist(Tx, clear, Key) ->
erlfdb:clear(Tx, Key).
+%% cache functions
+
+cache_noop(set, _) ->
+ ok;
+cache_noop(clear, _) ->
+ ok;
+cache_noop(get, _) ->
+ undefined.
+
+
+cache(#tree{} = Tree, Action, #node{} = Node) when Action == set; Action == clear ->
+ #tree{cache_fun = CacheFun} = Tree,
+ NodeIsCacheable = node_is_cacheable(Node),
+ if
+ NodeIsCacheable andalso CacheFun /= undefined ->
+ CacheFun(Action, Node);
+ true ->
+ ok
+ end;
+
+cache(#tree{} = _Tree, get, ?NODE_ROOT_ID) ->
+ undefined;
+
+cache(#tree{} = Tree, get, Id) ->
+ #tree{cache_fun = CacheFun} = Tree,
+ if
+ CacheFun /= undefined ->
+ CacheFun(get, Id);
+ true ->
+ undefined
+ end.
%% private functions
[couchdb] 02/06: mutate node id of non-leaf,
non-root nodes on delete
Posted by rn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
rnewson pushed a commit to branch prototype/fdb-layer-ebtree-immutable
in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit 4b9221f37e26ee40fd343ad0cdd3f6b329fd5cd7
Author: Robert Newson <rn...@apache.org>
AuthorDate: Thu Jul 23 19:01:02 2020 +0100
mutate node id of non-leaf, non-root nodes on delete
---
src/ebtree/src/ebtree.erl | 26 ++++++++++++++++++++++----
1 file changed, 22 insertions(+), 4 deletions(-)
diff --git a/src/ebtree/src/ebtree.erl b/src/ebtree/src/ebtree.erl
index 639406e..d9bc30b 100644
--- a/src/ebtree/src/ebtree.erl
+++ b/src/ebtree/src/ebtree.erl
@@ -684,20 +684,38 @@ delete(Tx, #tree{} = Tree, #node{} = Parent0, Key) ->
end, Members2, NewNodes),
Parent1 = Parent0#node{
- %% TODO change id
members = Members3
},
+ Parent2 = if
+ Parent1#node.id == ?NODE_ROOT_ID ->
+ Parent1;
+ Parent0#node.members == Parent1#node.members ->
+ Parent1;
+ true ->
+ clear_node(Tx, Tree, Parent1),
+ Parent1#node{id = new_node_id(Tx, Tree)}
+ end,
clear_nodes(Tx, Tree, [Child0, Sibling]),
set_nodes(Tx, Tree, NewNodes),
- Parent1;
+ Parent2;
false ->
set_node(Tx, Tree, Child0, Child1),
{_OldFirstKey, _OldLastKey, ChildId0, _OldReduction} = lists:keyfind(ChildId0, 3, Parent0#node.members),
- Parent0#node{
+ Parent1 = Parent0#node{
members = lists:keyreplace(ChildId0, 3, Parent0#node.members,
{first_key(Child1), last_key(Child1), Child1#node.id, reduce_node(Tree, Child1)})
- }
+ },
+ Parent2 = if
+ Parent1#node.id == ?NODE_ROOT_ID ->
+ Parent1;
+ Parent0#node.members == Parent1#node.members ->
+ Parent1;
+ true ->
+ clear_node(Tx, Tree, Parent1),
+ Parent1#node{id = new_node_id(Tx, Tree)}
+ end,
+ Parent2
end.
[couchdb] 05/06: convert node ids to uuids
Posted by rn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
rnewson pushed a commit to branch prototype/fdb-layer-ebtree-immutable
in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit 4bf5e30a06acc74b999e6aa09c99fcf22869ecd0
Author: Robert Newson <rn...@apache.org>
AuthorDate: Thu Jul 23 19:15:33 2020 +0100
convert node ids to uuids
---
src/ebtree/src/ebtree.erl | 50 +++++++++++++++++++++++++++--------------------
1 file changed, 29 insertions(+), 21 deletions(-)
diff --git a/src/ebtree/src/ebtree.erl b/src/ebtree/src/ebtree.erl
index 7c36fa5..d058669 100644
--- a/src/ebtree/src/ebtree.erl
+++ b/src/ebtree/src/ebtree.erl
@@ -53,10 +53,9 @@
-define(META, 0).
-define(META_ORDER, 0).
--define(META_NEXT_ID, 1).
-define(NODE, 1).
--define(NODE_ROOT_ID, 0).
+-define(NODE_ROOT_ID, <<0>>).
-define(underflow(Tree, Node), Tree#tree.min > length(Node#node.members)).
-define(at_min(Tree, Node), Tree#tree.min == length(Node#node.members)).
@@ -102,7 +101,6 @@ open(Db, Prefix, Order, Options) when is_binary(Prefix), is_integer(Order), Orde
not_found ->
erlfdb:clear_range_startswith(Tx, Prefix),
set_meta(Tx, Tree, ?META_ORDER, Order),
- set_meta(Tx, Tree, ?META_NEXT_ID, 1),
set_node(Tx, Tree, #node{id = ?NODE_ROOT_ID}),
init_order(Tree, Order);
ActualOrder when is_integer(ActualOrder) ->
@@ -495,7 +493,7 @@ insert(Db, #tree{} = Tree, Key, Value) ->
Root0 = get_node(Tx, Tree, ?NODE_ROOT_ID),
case ?is_full(Tree, Root0) of
true ->
- OldRoot = Root0#node{id = new_node_id(Tx, Tree)},
+ OldRoot = Root0#node{id = new_node_id()},
FirstKey = first_key(OldRoot),
LastKey = last_key(OldRoot),
Root1 = #node{
@@ -514,8 +512,8 @@ insert(Db, #tree{} = Tree, Key, Value) ->
split_child(Tx, #tree{} = Tree, #node{} = Parent0, #node{} = Child) ->
{LeftMembers, RightMembers} = lists:split(Tree#tree.min, Child#node.members),
- LeftId = new_node_id(Tx, Tree),
- RightId = new_node_id(Tx, Tree),
+ LeftId = new_node_id(),
+ RightId = new_node_id(),
LeftChild = remove_pointers_if_not_leaf(#node{
id = LeftId,
@@ -650,12 +648,12 @@ delete(Tx, #tree{} = Tree, #node{} = Parent0, Key) ->
Sibling = get_node(Tx, Tree, SiblingId),
NewNodes = case ?at_min(Tree, Sibling) of
true ->
- Merged = merge(Tx, Tree, Child1, Sibling),
+ Merged = merge(Tree, Child1, Sibling),
update_prev_neighbour(Tx, Tree, Merged),
update_next_neighbour(Tx, Tree, Merged),
[Merged];
false ->
- {Left, Right} = rebalance(Tx, Tree, Child1, Sibling),
+ {Left, Right} = rebalance(Tree, Child1, Sibling),
update_prev_neighbour(Tx, Tree, Left),
update_next_neighbour(Tx, Tree, Right),
[Left, Right]
@@ -688,11 +686,11 @@ delete(Tx, #tree{} = Tree, #node{} = Parent0, Key) ->
end.
-merge(Tx, #tree{} = Tree, #node{level = Level} = Node1, #node{level = Level} = Node2) ->
+merge(#tree{} = Tree, #node{level = Level} = Node1, #node{level = Level} = Node2) ->
[Left, Right] = sort_nodes(Tree, [Node1, Node2]),
#node{
- id = new_node_id(Tx, Tree),
+ id = new_node_id(),
level = Level,
prev = Left#node.prev,
next = Right#node.next,
@@ -700,14 +698,14 @@ merge(Tx, #tree{} = Tree, #node{level = Level} = Node1, #node{level = Level} = N
}.
-rebalance(Tx, #tree{} = Tree, #node{level = Level} = Node1, #node{level = Level} = Node2) ->
+rebalance(#tree{} = Tree, #node{level = Level} = Node1, #node{level = Level} = Node2) ->
[Left0, Right0] = sort_nodes(Tree, [Node1, Node2]),
Members = lists:append(Left0#node.members, Right0#node.members),
{LeftMembers, RightMembers} = lists:split(length(Members) div 2, Members),
- Left1Id = new_node_id(Tx, Tree),
- Right1Id = new_node_id(Tx, Tree),
+ Left1Id = new_node_id(),
+ Right1Id = new_node_id(),
Left1 = remove_pointers_if_not_leaf(Left0#node{
id = Left1Id,
@@ -824,7 +822,7 @@ set_node(Tx, #tree{} = Tree, #node{} = Node) ->
persist(Tree, Tx, set, [Key, Value]).
-node_key(Prefix, Id) when is_binary(Prefix), is_integer(Id) ->
+node_key(Prefix, Id) when is_binary(Prefix), is_binary(Id) ->
erlfdb_tuple:pack({?NODE, Id}, Prefix).
@@ -1105,7 +1103,7 @@ new_node_id_if_cacheable(Tx, #tree{} = Tree, #node{} = Old, #node{} = New) ->
if
MembersChanged andalso NodeIsCacheable ->
clear_node(Tx, Tree, New),
- New#node{id = new_node_id(Tx, Tree)};
+ New#node{id = new_node_id()};
true ->
New
end.
@@ -1121,10 +1119,8 @@ node_is_cacheable(#node{}) ->
true.
-new_node_id(Tx, Tree) ->
- NextId = get_meta(Tx, Tree, ?META_NEXT_ID),
- set_meta(Tx, Tree, ?META_NEXT_ID, NextId + 1),
- NextId.
+new_node_id() ->
+ crypto:strong_rand_bytes(16).
%% remove prev/next pointers for nonleaf nodes
@@ -1135,10 +1131,22 @@ remove_pointers_if_not_leaf(#node{} = Node) ->
Node#node{prev = undefined, next = undefined}.
+print_node(#node{level = 0} = Node) ->
+ io:format("#node{id = ~s, level = ~w, prev = ~s, next = ~s, members = ~w}~n~n",
+ [b64(Node#node.id), Node#node.level, b64(Node#node.prev), b64(Node#node.next),
+ Node#node.members]);
+
print_node(#node{} = Node) ->
- io:format("#node{id = ~w, level = ~w, prev = ~w, next = ~w, members = ~w}~n~n",
- [Node#node.id, Node#node.level, Node#node.prev, Node#node.next, Node#node.members]).
+ io:format("#node{id = ~s, level = ~w, prev = ~s, next = ~s, members = ~s}~n~n",
+ [base64:encode(Node#node.id), Node#node.level, b64(Node#node.prev), b64(Node#node.next),
+ [io_lib:format("{~w, ~w, ~s, ~w}, ", [F, L, b64(P), R]) || {F, L, P, R} <- Node#node.members]]).
+
+
+b64(undefined) ->
+ undefined;
+b64(Bin) ->
+ base64:encode(Bin).
%% tests
[couchdb] 01/06: mutate node id of non-leaf,
non-root nodes on insert
Posted by rn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
rnewson pushed a commit to branch prototype/fdb-layer-ebtree-immutable
in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit 9a0d67fb9ac79370b1a8616990eddd6d7ba30144
Author: Robert Newson <rn...@apache.org>
AuthorDate: Thu Jul 23 19:00:48 2020 +0100
mutate node id of non-leaf, non-root nodes on insert
---
src/ebtree/src/ebtree.erl | 32 +++++++++++++++++++++++++-------
1 file changed, 25 insertions(+), 7 deletions(-)
diff --git a/src/ebtree/src/ebtree.erl b/src/ebtree/src/ebtree.erl
index 536d3b1..639406e 100644
--- a/src/ebtree/src/ebtree.erl
+++ b/src/ebtree/src/ebtree.erl
@@ -549,9 +549,18 @@ split_child(Tx, #tree{} = Tree, #node{} = Parent0, #node{} = Child) ->
umerge_members(Tree, Parent0#node.level, [{FirstRightKey, LastRightKey, RightId, RightReduction}],
lists:keydelete(Child#node.id, 3, Parent0#node.members)))
},
+ Parent2 =
+ if Parent1#node.id == ?NODE_ROOT_ID ->
+ Parent1;
+ Parent0#node.members == Parent1#node.members ->
+ Parent1;
+ true ->
+ clear_node(Tx, Tree, Parent1),
+ Parent1#node{id = new_node_id(Tx, Tree)}
+ end,
clear_node(Tx, Tree, Child),
- set_nodes(Tx, Tree, [LeftChild, RightChild, Parent1]),
- {Parent1, LeftChild, RightChild}.
+ set_nodes(Tx, Tree, [LeftChild, RightChild, Parent2]),
+ {Parent2, LeftChild, RightChild}.
update_prev_neighbour(_Tx, #tree{} = _Tree, #node{prev = undefined} = _Node) ->
@@ -575,7 +584,7 @@ insert_nonfull(Tx, #tree{} = Tree, #node{level = 0} = Node0, Key, Value) ->
members = umerge_members(Tree, 0, [{Key, Value}], Node0#node.members)
},
set_node(Tx, Tree, Node0, Node1),
- reduce_node(Tree, Node1);
+ {Node1#node.id, reduce_node(Tree, Node1)};
insert_nonfull(Tx, #tree{} = Tree, #node{} = Node0, Key, Value) ->
ChildId0 = find_child_id(Tree, Node0, Key),
@@ -595,16 +604,25 @@ insert_nonfull(Tx, #tree{} = Tree, #node{} = Node0, Key, Value) ->
{Node0, Child0}
end,
ChildId1 = Child1#node.id,
- NewReduction = insert_nonfull(Tx, Tree, Child1, Key, Value),
+ {ChildId2, NewReduction} = insert_nonfull(Tx, Tree, Child1, Key, Value),
{CurrentFirstKey, CurrentLastKey, ChildId1, _OldReduction} = lists:keyfind(ChildId1, 3, Node1#node.members),
[NewFirstKey, _] = sort_keys(Tree, [Key, CurrentFirstKey]),
[_, NewLastKey] = sort_keys(Tree, [Key, CurrentLastKey]),
Node2 = Node1#node{
members = lists:keyreplace(ChildId1, 3, Node1#node.members,
- {NewFirstKey, NewLastKey, ChildId1, NewReduction})
+ {NewFirstKey, NewLastKey, ChildId2, NewReduction})
},
- set_node(Tx, Tree, Node0, Node2),
- reduce_node(Tree, Node2).
+ Node3 = if
+ Node2#node.id == ?NODE_ROOT_ID ->
+ Node2;
+ Node0#node.members == Node2#node.members ->
+ Node2;
+ true ->
+ clear_node(Tx, Tree, Node2),
+ Node2#node{id = new_node_id(Tx, Tree)}
+ end,
+ set_node(Tx, Tree, Node0, Node3),
+ {Node3#node.id, reduce_node(Tree, Node3)}.
%% @doc Deletes an entry from the ebtree
[couchdb] 03/06: consolidate id mutation logic into one function
Posted by rn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
rnewson pushed a commit to branch prototype/fdb-layer-ebtree-immutable
in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit 922c42ced8ce8998d1a993221a4c6847e08f473d
Author: Robert Newson <rn...@apache.org>
AuthorDate: Thu Jul 23 19:02:24 2020 +0100
consolidate id mutation logic into one function
---
src/ebtree/src/ebtree.erl | 64 +++++++++++++++++++----------------------------
1 file changed, 26 insertions(+), 38 deletions(-)
diff --git a/src/ebtree/src/ebtree.erl b/src/ebtree/src/ebtree.erl
index d9bc30b..34f42e6 100644
--- a/src/ebtree/src/ebtree.erl
+++ b/src/ebtree/src/ebtree.erl
@@ -549,15 +549,7 @@ split_child(Tx, #tree{} = Tree, #node{} = Parent0, #node{} = Child) ->
umerge_members(Tree, Parent0#node.level, [{FirstRightKey, LastRightKey, RightId, RightReduction}],
lists:keydelete(Child#node.id, 3, Parent0#node.members)))
},
- Parent2 =
- if Parent1#node.id == ?NODE_ROOT_ID ->
- Parent1;
- Parent0#node.members == Parent1#node.members ->
- Parent1;
- true ->
- clear_node(Tx, Tree, Parent1),
- Parent1#node{id = new_node_id(Tx, Tree)}
- end,
+ Parent2 = new_node_id_if_cacheable(Tx, Tree, Parent0, Parent1),
clear_node(Tx, Tree, Child),
set_nodes(Tx, Tree, [LeftChild, RightChild, Parent2]),
{Parent2, LeftChild, RightChild}.
@@ -612,15 +604,7 @@ insert_nonfull(Tx, #tree{} = Tree, #node{} = Node0, Key, Value) ->
members = lists:keyreplace(ChildId1, 3, Node1#node.members,
{NewFirstKey, NewLastKey, ChildId2, NewReduction})
},
- Node3 = if
- Node2#node.id == ?NODE_ROOT_ID ->
- Node2;
- Node0#node.members == Node2#node.members ->
- Node2;
- true ->
- clear_node(Tx, Tree, Node2),
- Node2#node{id = new_node_id(Tx, Tree)}
- end,
+ Node3 = new_node_id_if_cacheable(Tx, Tree, Node0, Node2),
set_node(Tx, Tree, Node0, Node3),
{Node3#node.id, reduce_node(Tree, Node3)}.
@@ -686,16 +670,7 @@ delete(Tx, #tree{} = Tree, #node{} = Parent0, Key) ->
Parent1 = Parent0#node{
members = Members3
},
- Parent2 = if
- Parent1#node.id == ?NODE_ROOT_ID ->
- Parent1;
- Parent0#node.members == Parent1#node.members ->
- Parent1;
- true ->
- clear_node(Tx, Tree, Parent1),
- Parent1#node{id = new_node_id(Tx, Tree)}
- end,
-
+ Parent2 = new_node_id_if_cacheable(Tx, Tree, Parent0, Parent1),
clear_nodes(Tx, Tree, [Child0, Sibling]),
set_nodes(Tx, Tree, NewNodes),
Parent2;
@@ -706,16 +681,7 @@ delete(Tx, #tree{} = Tree, #node{} = Parent0, Key) ->
members = lists:keyreplace(ChildId0, 3, Parent0#node.members,
{first_key(Child1), last_key(Child1), Child1#node.id, reduce_node(Tree, Child1)})
},
- Parent2 = if
- Parent1#node.id == ?NODE_ROOT_ID ->
- Parent1;
- Parent0#node.members == Parent1#node.members ->
- Parent1;
- true ->
- clear_node(Tx, Tree, Parent1),
- Parent1#node{id = new_node_id(Tx, Tree)}
- end,
- Parent2
+ new_node_id_if_cacheable(Tx, Tree, Parent0, Parent1)
end.
@@ -1090,6 +1056,28 @@ last_key(Members) when is_list(Members) ->
end.
+new_node_id_if_cacheable(Tx, #tree{} = Tree, #node{} = Old, #node{} = New) ->
+ MembersChanged = Old#node.members /= New#node.members,
+ NodeIsCacheable = node_is_cacheable(New),
+ if
+ MembersChanged andalso NodeIsCacheable ->
+ clear_node(Tx, Tree, New),
+ New#node{id = new_node_id(Tx, Tree)};
+ true ->
+ New
+ end.
+
+
+node_is_cacheable(#node{id = ?NODE_ROOT_ID}) ->
+ false;
+
+node_is_cacheable(#node{level = 0}) ->
+ false;
+
+node_is_cacheable(#node{}) ->
+ true.
+
+
new_node_id(Tx, Tree) ->
NextId = get_meta(Tx, Tree, ?META_NEXT_ID),
set_meta(Tx, Tree, ?META_NEXT_ID, NextId + 1),
[couchdb] 06/06: add cache test
Posted by rn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
rnewson pushed a commit to branch prototype/fdb-layer-ebtree-immutable
in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit 5215aa3ec007d7c83159ba01b943867a2419bc1c
Author: Robert Newson <rn...@apache.org>
AuthorDate: Thu Jul 23 19:16:25 2020 +0100
add cache test
---
src/ebtree/src/ebtree.erl | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/src/ebtree/src/ebtree.erl b/src/ebtree/src/ebtree.erl
index d058669..5409966 100644
--- a/src/ebtree/src/ebtree.erl
+++ b/src/ebtree/src/ebtree.erl
@@ -1529,4 +1529,23 @@ validate_node_test_() ->
].
+cache_test_() ->
+ {spawn, [fun() ->
+ Db = erlfdb_util:get_test_db([empty]),
+ CacheFun = fun
+ (set, Node) ->
+ erlang:put(Node#node.id, Node);
+ (clear, Node) ->
+ erlang:erase(Node#node.id);
+ (get, Id) ->
+ erlang:get(Id)
+ end,
+ Tree = open(Db, <<1,2,3>>, 4, [{cache_fun, CacheFun}]),
+ [ebtree:insert(Db, Tree, I, I) || I <- lists:seq(1, 16)],
+ ?assertEqual({1, 1}, ebtree:lookup(Db, Tree, 1)),
+ NodeCache = [V || {_K, V} <- erlang:get(), is_record(V, node)],
+ ?assertEqual(3, length(NodeCache))
+ end]}.
+
+
-endif.