This is an automated email from the ASF dual-hosted git repository. nickva pushed a commit to branch quadratic-speedup-in-bulk-docs in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit 41d5efd0941895e9421fb156c1c1628495adfa38 Author: Nick Vatamaniuc <[email protected]> AuthorDate: Mon Jul 27 18:02:16 2026 -0400 Quadratic speed up in _bulk_docs in pair_write_info Previously lists:keyfind scan inside a lists:map was essentially a guadratic pentalty right in the middle of _bulk_docs hotpath. Even with individual doc updates, because couch db updater coalesces batches together this should help even individual doc updates running concurrently. --- src/couch/src/couch_db_updater.erl | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/couch/src/couch_db_updater.erl b/src/couch/src/couch_db_updater.erl index 0d89c4750..8e697039f 100644 --- a/src/couch/src/couch_db_updater.erl +++ b/src/couch/src/couch_db_updater.erl @@ -912,11 +912,21 @@ commit_data(Db) -> Db2#db{committed_update_seq = UpdateSeq}. pair_write_info(Old, New) -> + % To avoid quadratic lookups, first build a map of Id => FDI and then + % look-up Ids in the map using O(1) complexity + OldMap = lists:foldl( + fun + (#full_doc_info{id = Id} = FDI, Acc) -> Acc#{Id => FDI}; + (not_found, Acc) -> Acc + end, + #{}, + Old + ), lists:map( - fun(FDI) -> - case lists:keyfind(FDI#full_doc_info.id, #full_doc_info.id, Old) of - #full_doc_info{} = OldFDI -> {OldFDI, FDI}; - false -> {not_found, FDI} + fun(#full_doc_info{id = Id} = FDI) -> + case OldMap of + #{Id := OldFDI} -> {OldFDI, FDI}; + _ -> {not_found, FDI} end end, New
