From d9623fb6047d1fa8832710d171547020c153d355 Mon Sep 17 00:00:00 2001 From: "Paul J. Davis" Date: Mon, 8 May 2017 17:33:02 -0500 Subject: Apply the same optimization for prefix writes --- src/couch/src/couch_btree.erl | 53 +++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/src/couch/src/couch_btree.erl b/src/couch/src/couch_btree.erl index 1a4ad601c..029771a56 100644 --- a/src/couch/src/couch_btree.erl +++ b/src/couch/src/couch_btree.erl @@ -465,10 +465,17 @@ write_node(Bt, _OldNode, NodeType, [_], NewList) -> % saves us the disk space that would have been % orphaned by not reusing the old node. write_node(Bt, OldNode, NodeType, OldList, NewList) -> - case is_append_only(OldList, NewList) of - false -> - write_node(Bt, NodeType, NewList); - {true, Suffix} -> + case is_extension(OldList, NewList) of + {prefix, Prefix} -> + case old_node_full(OldList) of + true -> + {ok, Results} = write_node(Bt, NodeType, Prefix), + {OldLastKey, _} = lists:last(OldList), + {ok, Results ++ [{OldLastKey, OldNode}]}; + false -> + write_node(Bt, NodeType, NewList) + end; + {suffix, Suffix} -> case old_node_full(OldList) of true -> {ok, Results} = write_node(Bt, NodeType, Suffix), @@ -476,28 +483,26 @@ write_node(Bt, OldNode, NodeType, OldList, NewList) -> {ok, [{OldLastKey,OldNode} | Results]}; false -> write_node(Bt, NodeType, NewList) - end + end; + false -> + write_node(Bt, NodeType, NewList) end. -% This function will blow up if OldList == NewList -% on purpose as an assertion that modify_node -% doesn't provide this input. -% -% First clause finds our suff -is_append_only([], [_ | _] = Suffix) -> - {true, Suffix}; - -% We've removed keys from the node -is_append_only([_ | _], []) -> - false; - -% We've found a mismatch of keys in the node -is_append_only([KV1 | _], [KV2 | _]) when KV1 /= KV2 -> - false; - -% Current key is equal, keep going -is_append_only([KV | Rest1], [KV | Rest2]) -> - is_append_only(Rest1, Rest2). +is_extension(OldList, NewList) -> + case lists:suffix(OldList, NewList) of + true -> + PrefixLength = length(NewList) - length(OldList), + {Prefix, _} = lists:split(PrefixLength, NewList), + {prefix, Prefix}; + false -> + case lists:prefix(OldList, NewList) of + true -> + Suffix = lists:nthtail(length(OldList), NewList), + {suffix, Suffix}; + false -> + false + end + end. old_node_full(OldList) -> ChunkThreshold = get_chunk_size(), -- cgit v1.2.1