pgj commented on code in PR #4662:
URL: https://github.com/apache/couchdb/pull/4662#discussion_r1306557440
##########
src/mango/src/mango_cursor.erl:
##########
@@ -44,27 +44,286 @@
-define(SUPERVISOR, mango_cursor_sup).
-create(Db, Selector0, Opts) ->
+-spec create(Db, Selector, Options, Kind) -> {ok, #cursor{}} when
+ Db :: database(),
+ Selector :: selector(),
+ Options :: cursor_options(),
+ Kind :: cursor_kind().
+create(Db, Selector0, Opts, Kind) ->
Selector = mango_selector:normalize(Selector0),
- UsableIndexes = mango_idx:get_usable_indexes(Db, Selector, Opts),
- case mango_cursor:maybe_filter_indexes_by_ddoc(UsableIndexes, Opts) of
+ {UsableIndexes, Trace} = mango_idx:get_usable_indexes(Db, Selector, Opts,
Kind),
+ case maybe_filter_indexes_by_ddoc(UsableIndexes, Opts) of
[] ->
% use_index doesn't match a valid index - fall back to a valid one
- create_cursor(Db, UsableIndexes, Selector, Opts);
+ create_cursor(Db, {UsableIndexes, Trace}, Selector, Opts);
UserSpecifiedIndex ->
- create_cursor(Db, UserSpecifiedIndex, Selector, Opts)
+ create_cursor(Db, {UserSpecifiedIndex, Trace}, Selector, Opts)
end.
+-spec enhance_candidates(Candidates, [{#idx{}, properties()}]) -> Candidates
when
+ Candidates :: #{#idx{} => properties()}.
+enhance_candidates(Entries, Inputs) ->
+ Combiner =
+ fun(Key, Value1, Value2) ->
+ case Key of
+ usable -> Value1 andalso Value2;
+ reason -> lists:append(Value1, Value2);
+ ranking -> Value1 + Value2
+ end
+ end,
+ lists:foldr(
+ fun({Index, Delta}, Map) ->
+ Updater = fun(Value) -> maps:merge_with(Combiner, Value, Delta)
end,
+ maps:update_with(Index, Updater, Map)
+ end,
+ Entries,
+ Inputs
+ ).
+
+-type ranking() :: pos_integer().
+-type properties() ::
+ #{
+ usable := boolean(),
+ ranking := ranking(),
+ reason := [reason()]
+ }.
+
+-spec tag_elems(properties(), sets:set(#idx{})) -> [{#idx{}, properties()}].
+tag_elems(Properties, Set) ->
+ sets:fold(fun(Index, Acc) -> [{Index, Properties} | Acc] end, [], Set).
+
+-type reason_description() ::
+ {name, reason()}.
+-type analysis_attribute() ::
+ {usable, boolean()}
+ | {reasons, [reason_description()]}
+ | {ranking, ranking()}
+ | {covering, boolean()}.
+-type analysis() ::
+ {[analysis_attribute()]}.
+-type candidate_index_attribute() ::
+ {index, #idx{}} | {analysis, analysis()}.
+-type candidate_index() ::
+ {[candidate_index_attribute()]}.
+
+-spec extract_candidate_indexes(#cursor{}) -> [candidate_index()].
+extract_candidate_indexes(Cursor) ->
+ #cursor{trace = Trace, index = Winner, fields = Fields} = Cursor,
+ #{
+ all_indexes := AllIndexes,
+ global_indexes := GlobalIndexes,
+ partition_indexes := PartitionIndexes,
+ usable_indexes := UsableIndexes,
+ usability_map := UsabilityMap,
+ filtered_indexes := FilteredIndexes,
+ indexes_of_type := IndexesOfType
+ } = Trace,
+ % specific to view indexes
+ SortedIndexRanges = maps:get(sorted_index_ranges, Trace, []),
+ % simple difference calculations to determine the results in each stage,
+ % without looking at the implementation
+ PartialIndexes = sets:subtract(AllIndexes, GlobalIndexes),
+ OutOfScopeIndexes = sets:subtract(GlobalIndexes, PartitionIndexes),
+ NotUsableIndexes = sets:subtract(PartitionIndexes, UsableIndexes),
+ ExcludedIndexes = sets:subtract(UsableIndexes, FilteredIndexes),
+ UnfavoredIndexes = sets:subtract(FilteredIndexes, IndexesOfType),
+ % determine rankings
+ UnfavoredIndexesRank = max(1, length(SortedIndexRanges)),
+ {_, [PartialIndexesRank, OutOfScopeIndexesRank, NotUsableIndexesRank,
ExcludedIndexesRank]} =
+ lists:foldl(
Review Comment:
Yeah, it makes sense. I will change it.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]