This is an automated email from the ASF dual-hosted git repository.
vatamane 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 2447ad834 Simplify couch_quickjs scanner plugin
2447ad834 is described below
commit 2447ad834937ed13c88c10d4bcd78b3b185e34e2
Author: Nick Vatamaniuc <[email protected]>
AuthorDate: Fri Feb 6 13:14:12 2026 -0500
Simplify couch_quickjs scanner plugin
Since we inspect the #full_doc_info{} record to skip deleted docs anyway,
move
all the doc_id clauses to the `doc_fdi/3` callback to have one less
callback to
worry about.
There is not performance penalty as by the time we call `doc_id/3` we
already
have the full `#full_doc_info{}` record opened anyway.
---
.../src/couch_quickjs_scanner_plugin.erl | 18 ++---
.../test/couch_quickjs_scanner_plugin_tests.erl | 79 ++++++++++++----------
2 files changed, 51 insertions(+), 46 deletions(-)
diff --git a/src/couch_quickjs/src/couch_quickjs_scanner_plugin.erl
b/src/couch_quickjs/src/couch_quickjs_scanner_plugin.erl
index 52a252fc9..4c8d6b0f6 100644
--- a/src/couch_quickjs/src/couch_quickjs_scanner_plugin.erl
+++ b/src/couch_quickjs/src/couch_quickjs_scanner_plugin.erl
@@ -22,7 +22,6 @@
ddoc/3,
shards/2,
db_opened/2,
- doc_id/3,
doc_fdi/3,
doc/3,
db_closing/2
@@ -152,23 +151,20 @@ db_opened(#st{} = St, Db) ->
Step = min(MaxStep, max(1, DocTotal div MaxDocs)),
{0, [], St#st{doc_cnt = 0, docs_size = 0, doc_step = Step, docs = []}}.
-doc_id(#st{} = St, <<?DESIGN_DOC_PREFIX, _/binary>>, _Db) ->
+doc_fdi(#st{} = St, #full_doc_info{deleted = true}, _Db) ->
+ % Skip deleted; don't even open the doc body
{skip, St};
-doc_id(#st{sid = SId, doc_cnt = C, max_docs = M} = St, _DocId, Db) when C > M
->
+doc_fdi(#st{} = St, #full_doc_info{id = <<?DESIGN_DOC_PREFIX, _/binary>>},
_Db) ->
+ {skip, St};
+doc_fdi(#st{sid = SId, doc_cnt = C, max_docs = M} = St, #full_doc_info{}, Db)
when C > M ->
Meta = #{sid => SId, db => Db},
?INFO("reached max docs ~p", [M], Meta),
{stop, St};
-doc_id(#st{doc_cnt = C, doc_step = S} = St, _DocId, _Db) when C rem S /= 0 ->
+doc_fdi(#st{doc_cnt = C, doc_step = S} = St, #full_doc_info{}, _Db) when C rem
S /= 0 ->
{skip, St#st{doc_cnt = C + 1}};
-doc_id(#st{doc_cnt = C} = St, _DocId, _Db) ->
+doc_fdi(#st{doc_cnt = C} = St, #full_doc_info{}, _Db) ->
{ok, St#st{doc_cnt = C + 1}}.
-doc_fdi(#st{} = St, #full_doc_info{deleted = true}, _Db) ->
- % Skip deleted; don't even open the doc body
- {skip, St};
-doc_fdi(#st{} = St, #full_doc_info{}, _Db) ->
- {ok, St}.
-
doc(#st{} = St, Db, #doc{id = DocId} = Doc) ->
#st{sid = SId} = St,
JsonDoc = couch_query_servers:json_doc(Doc),
diff --git a/src/couch_quickjs/test/couch_quickjs_scanner_plugin_tests.erl
b/src/couch_quickjs/test/couch_quickjs_scanner_plugin_tests.erl
index 7277ab656..fe8a1a68f 100644
--- a/src/couch_quickjs/test/couch_quickjs_scanner_plugin_tests.erl
+++ b/src/couch_quickjs/test/couch_quickjs_scanner_plugin_tests.erl
@@ -92,11 +92,11 @@ t_vdu_filter_map({_, DbName}) ->
?assert(num_calls(shards, 2) >= 1),
DbOpenedCount = num_calls(db_opened, 2),
?assert(DbOpenedCount >= 2),
- ?assertEqual(1, num_calls(doc_id, ['_', ?DOC1, '_'])),
- ?assertEqual(1, num_calls(doc_id, ['_', ?DOC2, '_'])),
- ?assertEqual(1, num_calls(doc_id, ['_', ?DOC3, '_'])),
- ?assertEqual(1, num_calls(doc_id, ['_', ?DOC4, '_'])),
- ?assertEqual(1, num_calls(doc_id, ['_', ?DOC5, '_'])),
+ ?assertEqual(1, num_calls(doc_fdi, ['_', fdi_id_match(?DOC1),
'_'])),
+ ?assertEqual(1, num_calls(doc_fdi, ['_', fdi_id_match(?DOC2),
'_'])),
+ ?assertEqual(1, num_calls(doc_fdi, ['_', fdi_id_match(?DOC3),
'_'])),
+ ?assertEqual(1, num_calls(doc_fdi, ['_', fdi_id_match(?DOC4),
'_'])),
+ ?assertEqual(1, num_calls(doc_fdi, ['_', fdi_id_match(?DOC5),
'_'])),
?assert(num_calls(doc, 3) >= 5),
DbClosingCount = num_calls(db_closing, 2),
?assertEqual(DbOpenedCount, DbClosingCount),
@@ -125,11 +125,11 @@ t_filter_map({_, DbName}) ->
?assert(num_calls(shards, 2) >= 1),
DbOpenedCount = num_calls(db_opened, 2),
?assert(DbOpenedCount >= 2),
- ?assertEqual(1, num_calls(doc_id, ['_', ?DOC1, '_'])),
- ?assertEqual(1, num_calls(doc_id, ['_', ?DOC2, '_'])),
- ?assertEqual(1, num_calls(doc_id, ['_', ?DOC3, '_'])),
- ?assertEqual(1, num_calls(doc_id, ['_', ?DOC4, '_'])),
- ?assertEqual(1, num_calls(doc_id, ['_', ?DOC5, '_'])),
+ ?assertEqual(1, num_calls(doc_fdi, ['_', fdi_id_match(?DOC1),
'_'])),
+ ?assertEqual(1, num_calls(doc_fdi, ['_', fdi_id_match(?DOC2),
'_'])),
+ ?assertEqual(1, num_calls(doc_fdi, ['_', fdi_id_match(?DOC3),
'_'])),
+ ?assertEqual(1, num_calls(doc_fdi, ['_', fdi_id_match(?DOC4),
'_'])),
+ ?assertEqual(1, num_calls(doc_fdi, ['_', fdi_id_match(?DOC5),
'_'])),
?assert(num_calls(doc, 3) >= 5),
DbClosingCount = num_calls(db_closing, 2),
?assertEqual(DbOpenedCount, DbClosingCount),
@@ -158,11 +158,11 @@ t_map_only({_, DbName}) ->
?assert(num_calls(shards, 2) >= 1),
DbOpenedCount = num_calls(db_opened, 2),
?assert(DbOpenedCount >= 2),
- ?assertEqual(1, num_calls(doc_id, ['_', ?DOC1, '_'])),
- ?assertEqual(1, num_calls(doc_id, ['_', ?DOC2, '_'])),
- ?assertEqual(1, num_calls(doc_id, ['_', ?DOC3, '_'])),
- ?assertEqual(1, num_calls(doc_id, ['_', ?DOC4, '_'])),
- ?assertEqual(1, num_calls(doc_id, ['_', ?DOC5, '_'])),
+ ?assertEqual(1, num_calls(doc_fdi, ['_', fdi_id_match(?DOC1),
'_'])),
+ ?assertEqual(1, num_calls(doc_fdi, ['_', fdi_id_match(?DOC2),
'_'])),
+ ?assertEqual(1, num_calls(doc_fdi, ['_', fdi_id_match(?DOC3),
'_'])),
+ ?assertEqual(1, num_calls(doc_fdi, ['_', fdi_id_match(?DOC4),
'_'])),
+ ?assertEqual(1, num_calls(doc_fdi, ['_', fdi_id_match(?DOC5),
'_'])),
?assert(num_calls(doc, 3) >= 5),
DbClosingCount = num_calls(db_closing, 2),
?assertEqual(DbOpenedCount, DbClosingCount),
@@ -191,11 +191,11 @@ t_vdu_only({_, DbName}) ->
?assert(num_calls(shards, 2) >= 1),
DbOpenedCount = num_calls(db_opened, 2),
?assert(DbOpenedCount >= 2),
- ?assertEqual(1, num_calls(doc_id, ['_', ?DOC1, '_'])),
- ?assertEqual(1, num_calls(doc_id, ['_', ?DOC2, '_'])),
- ?assertEqual(1, num_calls(doc_id, ['_', ?DOC3, '_'])),
- ?assertEqual(1, num_calls(doc_id, ['_', ?DOC4, '_'])),
- ?assertEqual(1, num_calls(doc_id, ['_', ?DOC5, '_'])),
+ ?assertEqual(1, num_calls(doc_fdi, ['_', fdi_id_match(?DOC1),
'_'])),
+ ?assertEqual(1, num_calls(doc_fdi, ['_', fdi_id_match(?DOC2),
'_'])),
+ ?assertEqual(1, num_calls(doc_fdi, ['_', fdi_id_match(?DOC3),
'_'])),
+ ?assertEqual(1, num_calls(doc_fdi, ['_', fdi_id_match(?DOC4),
'_'])),
+ ?assertEqual(1, num_calls(doc_fdi, ['_', fdi_id_match(?DOC5),
'_'])),
?assert(num_calls(doc, 3) >= 5),
DbClosingCount = num_calls(db_closing, 2),
?assertEqual(DbOpenedCount, DbClosingCount),
@@ -224,11 +224,11 @@ t_non_deterministic_vdu({_, DbName}) ->
?assert(num_calls(shards, 2) >= 1),
DbOpenedCount = num_calls(db_opened, 2),
?assert(DbOpenedCount >= 2),
- ?assertEqual(1, num_calls(doc_id, ['_', ?DOC1, '_'])),
- ?assertEqual(1, num_calls(doc_id, ['_', ?DOC2, '_'])),
- ?assertEqual(1, num_calls(doc_id, ['_', ?DOC3, '_'])),
- ?assertEqual(1, num_calls(doc_id, ['_', ?DOC4, '_'])),
- ?assertEqual(1, num_calls(doc_id, ['_', ?DOC5, '_'])),
+ ?assertEqual(1, num_calls(doc_fdi, ['_', fdi_id_match(?DOC1),
'_'])),
+ ?assertEqual(1, num_calls(doc_fdi, ['_', fdi_id_match(?DOC2),
'_'])),
+ ?assertEqual(1, num_calls(doc_fdi, ['_', fdi_id_match(?DOC3),
'_'])),
+ ?assertEqual(1, num_calls(doc_fdi, ['_', fdi_id_match(?DOC4),
'_'])),
+ ?assertEqual(1, num_calls(doc_fdi, ['_', fdi_id_match(?DOC5),
'_'])),
?assert(num_calls(doc, 3) >= 5),
DbClosingCount = num_calls(db_closing, 2),
?assertEqual(DbOpenedCount, DbClosingCount),
@@ -257,11 +257,11 @@ t_filter_only({_, DbName}) ->
?assert(num_calls(shards, 2) >= 1),
DbOpenedCount = num_calls(db_opened, 2),
?assert(DbOpenedCount >= 2),
- ?assertEqual(1, num_calls(doc_id, ['_', ?DOC1, '_'])),
- ?assertEqual(1, num_calls(doc_id, ['_', ?DOC2, '_'])),
- ?assertEqual(1, num_calls(doc_id, ['_', ?DOC3, '_'])),
- ?assertEqual(1, num_calls(doc_id, ['_', ?DOC4, '_'])),
- ?assertEqual(1, num_calls(doc_id, ['_', ?DOC5, '_'])),
+ ?assertEqual(1, num_calls(doc_fdi, ['_', fdi_id_match(?DOC1),
'_'])),
+ ?assertEqual(1, num_calls(doc_fdi, ['_', fdi_id_match(?DOC2),
'_'])),
+ ?assertEqual(1, num_calls(doc_fdi, ['_', fdi_id_match(?DOC3),
'_'])),
+ ?assertEqual(1, num_calls(doc_fdi, ['_', fdi_id_match(?DOC4),
'_'])),
+ ?assertEqual(1, num_calls(doc_fdi, ['_', fdi_id_match(?DOC5),
'_'])),
?assert(num_calls(doc, 3) >= 5),
DbClosingCount = num_calls(db_closing, 2),
?assertEqual(DbOpenedCount, DbClosingCount),
@@ -314,11 +314,11 @@ t_empty_ddoc({_, DbName}) ->
?assertEqual(1, num_calls(ddoc, ['_', DbName, '_'])),
?assert(num_calls(shards, 2) >= 1),
?assertEqual(0, num_calls(db_opened, 2)),
- ?assertEqual(0, num_calls(doc_id, ['_', ?DOC1, '_'])),
- ?assertEqual(0, num_calls(doc_id, ['_', ?DOC2, '_'])),
- ?assertEqual(0, num_calls(doc_id, ['_', ?DOC3, '_'])),
- ?assertEqual(0, num_calls(doc_id, ['_', ?DOC4, '_'])),
- ?assertEqual(0, num_calls(doc_id, ['_', ?DOC5, '_'])),
+ ?assertEqual(0, num_calls(doc_fdi, ['_', fdi_id_match(?DOC1),
'_'])),
+ ?assertEqual(0, num_calls(doc_fdi, ['_', fdi_id_match(?DOC2),
'_'])),
+ ?assertEqual(0, num_calls(doc_fdi, ['_', fdi_id_match(?DOC3),
'_'])),
+ ?assertEqual(0, num_calls(doc_fdi, ['_', fdi_id_match(?DOC4),
'_'])),
+ ?assertEqual(0, num_calls(doc_fdi, ['_', fdi_id_match(?DOC5),
'_'])),
?assertEqual(0, num_calls(db_closing, 2)),
?assertEqual(0, couch_stats:sample([couchdb, query_server,
process_error_exits])),
?assertEqual(0, couch_stats:sample([couchdb, query_server,
process_errors])),
@@ -476,6 +476,15 @@ mkdoc(Id, #{} = Body) ->
Body1 = Body#{<<"_id">> => Id},
jiffy:decode(jiffy:encode(Body1)).
+fdi_id_match(Id) ->
+ #full_doc_info{
+ id = Id,
+ update_seq = '_',
+ deleted = '_',
+ rev_tree = '_',
+ sizes = '_'
+ }.
+
num_calls(Fun, Args) ->
meck:num_calls(?PLUGIN, Fun, Args).