You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by va...@apache.org on 2023/02/14 15:14:41 UTC

[couchdb] branch main updated (d3b0bcbf3 -> 3fa8f72ac)

This is an automated email from the ASF dual-hosted git repository.

vatamane pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/couchdb.git


    from d3b0bcbf3 Test the update_docs=true case in replicator scheduler docs test
     new 58e5825c6 mango: Remove unused imports
     new b08dc7ac7 mango: Remove unused parameter from the JSON index selection
     new 1c90b504a mango: Add type specification for the JSON index selection
     new a650b4461 mango: Cover JSON index selection with unit tests
     new 3fa8f72ac mango: Match comments with implementation for JSON index selection

The 5 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:
 src/mango/src/mango_cursor_special.erl |   4 +-
 src/mango/src/mango_cursor_view.erl    | 102 ++++++++++++++++++++++++++++++---
 2 files changed, 96 insertions(+), 10 deletions(-)


[couchdb] 02/05: mango: Remove unused parameter from the JSON index selection

Posted by va...@apache.org.
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

commit b08dc7ac77dd3ea53cf1b8b92571387478e5b143
Author: Gabor Pali <ga...@ibm.com>
AuthorDate: Mon Feb 13 22:52:26 2023 +0100

    mango: Remove unused parameter from the JSON index selection
---
 src/mango/src/mango_cursor_special.erl | 2 +-
 src/mango/src/mango_cursor_view.erl    | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/mango/src/mango_cursor_special.erl b/src/mango/src/mango_cursor_special.erl
index 59eb2baad..8ea7e914b 100644
--- a/src/mango/src/mango_cursor_special.erl
+++ b/src/mango/src/mango_cursor_special.erl
@@ -32,7 +32,7 @@ create(Db, Indexes, Selector, Opts) ->
     % catchall is the most expensive range
     FieldRanges = InitialRange ++ CatchAll,
     Composited = mango_cursor_view:composite_indexes(Indexes, FieldRanges),
-    {Index, IndexRanges} = mango_cursor_view:choose_best_index(Db, Composited),
+    {Index, IndexRanges} = mango_cursor_view:choose_best_index(Composited),
 
     Limit = couch_util:get_value(limit, Opts, mango_opts:default_limit()),
     Skip = couch_util:get_value(skip, Opts, 0),
diff --git a/src/mango/src/mango_cursor_view.erl b/src/mango/src/mango_cursor_view.erl
index 47195341c..3f67f667b 100644
--- a/src/mango/src/mango_cursor_view.erl
+++ b/src/mango/src/mango_cursor_view.erl
@@ -23,7 +23,7 @@
     handle_message/2,
     handle_all_docs_message/2,
     composite_indexes/2,
-    choose_best_index/2
+    choose_best_index/1
 ]).
 
 -include_lib("couch/include/couch_db.hrl").
@@ -51,7 +51,7 @@ viewcbargs_get(fields, Args) when is_map(Args) ->
 create(Db, Indexes, Selector, Opts) ->
     FieldRanges = mango_idx_view:field_ranges(Selector),
     Composited = composite_indexes(Indexes, FieldRanges),
-    {Index, IndexRanges} = choose_best_index(Db, Composited),
+    {Index, IndexRanges} = choose_best_index(Composited),
 
     Limit = couch_util:get_value(limit, Opts, mango_opts:default_limit()),
     Skip = couch_util:get_value(skip, Opts, 0),
@@ -230,7 +230,7 @@ composite_prefix([Col | Rest], Ranges) ->
 % In the future we can look into doing a cached parallel
 % reduce view read on each index with the ranges to find
 % the one that has the fewest number of rows or something.
-choose_best_index(_DbName, IndexRanges) ->
+choose_best_index(IndexRanges) ->
     Cmp = fun({IdxA, _PrefixA, PrefixDifferenceA}, {IdxB, _PrefixB, PrefixDifferenceB}) ->
         case PrefixDifferenceA - PrefixDifferenceB of
             N when N < 0 -> true;


[couchdb] 03/05: mango: Add type specification for the JSON index selection

Posted by va...@apache.org.
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

commit 1c90b504a9439a6c7c2a8754b03955b17780d6a8
Author: Gabor Pali <ga...@ibm.com>
AuthorDate: Mon Feb 13 22:57:25 2023 +0100

    mango: Add type specification for the JSON index selection
---
 src/mango/src/mango_cursor_view.erl | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/src/mango/src/mango_cursor_view.erl b/src/mango/src/mango_cursor_view.erl
index 3f67f667b..883f2e448 100644
--- a/src/mango/src/mango_cursor_view.erl
+++ b/src/mango/src/mango_cursor_view.erl
@@ -31,6 +31,7 @@
 -include_lib("fabric/include/fabric.hrl").
 
 -include("mango_cursor.hrl").
+-include("mango_idx.hrl").
 -include("mango_idx_view.hrl").
 
 -define(HEARTBEAT_INTERVAL_IN_USEC, 4000000).
@@ -230,6 +231,11 @@ composite_prefix([Col | Rest], Ranges) ->
 % In the future we can look into doing a cached parallel
 % reduce view read on each index with the ranges to find
 % the one that has the fewest number of rows or something.
+-type range() :: {binary(), any(), binary(), any()} | empty.
+
+-spec choose_best_index(IndexRanges) -> Selection when
+    IndexRanges :: nonempty_list({#idx{}, [range()], integer()}),
+    Selection :: {#idx{}, [range()]}.
 choose_best_index(IndexRanges) ->
     Cmp = fun({IdxA, _PrefixA, PrefixDifferenceA}, {IdxB, _PrefixB, PrefixDifferenceB}) ->
         case PrefixDifferenceA - PrefixDifferenceB of


[couchdb] 04/05: mango: Cover JSON index selection with unit tests

Posted by va...@apache.org.
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

commit a650b446148f7f8913a0941fa9f80d2c441554ad
Author: Gabor Pali <ga...@ibm.com>
AuthorDate: Mon Feb 13 22:59:11 2023 +0100

    mango: Cover JSON index selection with unit tests
---
 src/mango/src/mango_cursor_view.erl | 79 +++++++++++++++++++++++++++++++++++++
 1 file changed, 79 insertions(+)

diff --git a/src/mango/src/mango_cursor_view.erl b/src/mango/src/mango_cursor_view.erl
index 883f2e448..c494e3d78 100644
--- a/src/mango/src/mango_cursor_view.erl
+++ b/src/mango/src/mango_cursor_view.erl
@@ -630,4 +630,83 @@ match_and_extract_doc_nomatch_fields_test() ->
     ?assertEqual(no_match, Match),
     ?assertEqual(undefined, FinalDoc).
 
+%% Query planner tests:
+%% - there should be no comparison for a singleton list, with a trivial result
+choose_best_index_with_singleton_test() ->
+    ?assertEqual({index, ranges}, choose_best_index([{index, ranges, undefined}])).
+
+%% - choose the index with the lowest difference between its prefix and field ranges
+choose_best_index_lowest_difference_test() ->
+    IndexRanges =
+        [
+            {index1, ranges1, 3},
+            {index2, ranges2, 2},
+            {index3, ranges3, 1}
+        ],
+    ?assertEqual({index3, ranges3}, choose_best_index(IndexRanges)).
+
+%% - if that is equal, choose the index with the least number of fields in the index
+choose_best_index_least_number_of_fields_test() ->
+    Index = json_index(dbname, design_document, index_name),
+    [Index1, Index2, Index3] = [with_dummy_columns(Index, N) || N <- [6, 3, 9]],
+    IndexRanges =
+        [
+            {Index1, ranges1, 1},
+            {Index2, ranges2, 1},
+            {Index3, ranges3, 1}
+        ],
+    ?assertEqual({Index2, ranges2}, choose_best_index(IndexRanges)).
+
+%% - otherwise, choose alphabetically based on the index properties:
+choose_best_index_lowest_index_triple_test() ->
+    WithSomeColumns = fun(Idx) -> with_dummy_columns(Idx, 3) end,
+
+    % - database name
+    Index1 = WithSomeColumns(json_index(<<"db_a">>, <<"_design/c">>, <<"B">>)),
+    Index2 = WithSomeColumns(json_index(<<"db_b">>, <<"_design/b">>, <<"C">>)),
+    Index3 = WithSomeColumns(json_index(<<"db_c">>, <<"_design/a">>, <<"A">>)),
+    IndexRanges1 =
+        [
+            {Index1, ranges1, 1},
+            {Index2, ranges2, 1},
+            {Index3, ranges3, 1}
+        ],
+    ?assertEqual({Index1, ranges1}, choose_best_index(IndexRanges1)),
+
+    % - if that is equal, design document name
+    Index4 = WithSomeColumns(json_index(<<"db_a">>, <<"_design/c">>, <<"B">>)),
+    Index5 = WithSomeColumns(json_index(<<"db_a">>, <<"_design/b">>, <<"C">>)),
+    Index6 = WithSomeColumns(json_index(<<"db_a">>, <<"_design/a">>, <<"A">>)),
+    IndexRanges2 =
+        [
+            {Index4, ranges4, 1},
+            {Index5, ranges5, 1},
+            {Index6, ranges6, 1}
+        ],
+    ?assertEqual({Index6, ranges6}, choose_best_index(IndexRanges2)),
+
+    % - otherwise, index name
+    Index7 = WithSomeColumns(json_index(<<"db_a">>, <<"_design/a">>, <<"B">>)),
+    Index8 = WithSomeColumns(json_index(<<"db_a">>, <<"_design/a">>, <<"C">>)),
+    Index9 = WithSomeColumns(json_index(<<"db_a">>, <<"_design/a">>, <<"A">>)),
+    IndexRanges3 =
+        [
+            {Index7, ranges7, 1},
+            {Index8, ranges8, 1},
+            {Index9, ranges9, 1}
+        ],
+    ?assertEqual({Index9, ranges9}, choose_best_index(IndexRanges3)).
+
+json_index(DbName, DesignDoc, Name) ->
+    #idx{
+        dbname = DbName,
+        ddoc = DesignDoc,
+        name = Name,
+        type = <<"json">>
+    }.
+
+with_dummy_columns(Index, Count) ->
+    Columns =
+        {[{<<"field", (integer_to_binary(I))/binary>>, undefined} || I <- lists:seq(1, Count)]},
+    Index#idx{def = {[{<<"fields">>, Columns}]}}.
 -endif.


[couchdb] 01/05: mango: Remove unused imports

Posted by va...@apache.org.
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

commit 58e5825c64b0713596651fbd6a64c2349338f9ef
Author: Gabor Pali <ga...@ibm.com>
AuthorDate: Mon Feb 13 22:48:05 2023 +0100

    mango: Remove unused imports
---
 src/mango/src/mango_cursor_special.erl | 2 --
 1 file changed, 2 deletions(-)

diff --git a/src/mango/src/mango_cursor_special.erl b/src/mango/src/mango_cursor_special.erl
index f20edebd1..59eb2baad 100644
--- a/src/mango/src/mango_cursor_special.erl
+++ b/src/mango/src/mango_cursor_special.erl
@@ -22,8 +22,6 @@
     handle_message/2
 ]).
 
--include_lib("couch/include/couch_db.hrl").
--include_lib("couch_mrview/include/couch_mrview.hrl").
 -include("mango_cursor.hrl").
 
 create(Db, Indexes, Selector, Opts) ->


[couchdb] 05/05: mango: Match comments with implementation for JSON index selection

Posted by va...@apache.org.
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

commit 3fa8f72ac113dff073c9a764ba9189abb29ecba7
Author: Gabor Pali <ga...@ibm.com>
AuthorDate: Tue Feb 14 12:46:28 2023 +0100

    mango: Match comments with implementation for JSON index selection
---
 src/mango/src/mango_cursor_view.erl | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/src/mango/src/mango_cursor_view.erl b/src/mango/src/mango_cursor_view.erl
index c494e3d78..a784cf6b0 100644
--- a/src/mango/src/mango_cursor_view.erl
+++ b/src/mango/src/mango_cursor_view.erl
@@ -225,7 +225,7 @@ composite_prefix([Col | Rest], Ranges) ->
 % Prefix and the FieldRanges. If that is equal, then
 % choose the index with the least number of
 % fields in the index. If we still cannot break the tie,
-% then choose alphabetically based on ddocId.
+% then choose alphabetically based on (dbname, ddocid, view_name).
 % Return the first element's Index and IndexRanges.
 %
 % In the future we can look into doing a cached parallel
@@ -247,9 +247,12 @@ choose_best_index(IndexRanges) ->
                     M when M < 0 ->
                         true;
                     M when M == 0 ->
-                        % We have no other way to choose, so at this point
-                        % select the index based on (dbname, ddocid, view_name) triple
-                        IdxA =< IdxB;
+                        % Restrict the comparison to the (dbname, ddocid, view_name)
+                        % triple -- in case of their equivalence, the original order
+                        % will be maintained.
+                        #idx{dbname = DbNameA, ddoc = DDocA, name = NameA} = IdxA,
+                        #idx{dbname = DbNameB, ddoc = DDocB, name = NameB} = IdxB,
+                        {DbNameA, DDocA, NameA} =< {DbNameB, DDocB, NameB};
                     _ ->
                         false
                 end;