This is an automated email from the ASF dual-hosted git repository.
nickva pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/couchdb.git
The following commit(s) were added to refs/heads/main by this push:
new 977fecb53 Quadratic speed up in _bulk_docs in pair_write_info
977fecb53 is described below
commit 977fecb535c4e50a2d1356469b670c6da0e6d7b9
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
penalty 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