xref: /aosp_15_r20/external/icing/icing/result/result-state-v2.h (revision 8b6cd535a057e39b3b86660c4aa06c99747c2136)
1 // Copyright (C) 2022 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef ICING_RESULT_RESULT_STATE_V2_H_
16 #define ICING_RESULT_RESULT_STATE_V2_H_
17 
18 #include <atomic>
19 #include <cstdint>
20 #include <memory>
21 #include <unordered_map>
22 #include <vector>
23 
24 #include "icing/absl_ports/mutex.h"
25 #include "icing/absl_ports/thread_annotations.h"
26 #include "icing/proto/search.pb.h"
27 #include "icing/result/result-adjustment-info.h"
28 #include "icing/scoring/scored-document-hits-ranker.h"
29 #include "icing/store/document-store.h"
30 
31 namespace icing {
32 namespace lib {
33 
34 // Used to hold information needed across multiple pagination requests of the
35 // same query. Stored in ResultStateManager.
36 class ResultStateV2 {
37  public:
38   explicit ResultStateV2(
39       std::unique_ptr<ScoredDocumentHitsRanker> scored_document_hits_ranker_in,
40       std::unique_ptr<ResultAdjustmentInfo> parent_adjustment_info,
41       std::unique_ptr<ResultAdjustmentInfo> child_adjustment_info,
42       const ResultSpecProto& result_spec, const DocumentStore& document_store);
43 
44   ~ResultStateV2();
45 
46   // Register num_total_hits_ and add current scored_document_hits_ranker.size()
47   // to it. When re-registering, it will subtract
48   // scored_document_hits_ranker.size() from the original counter.
49   void RegisterNumTotalHits(std::atomic<int>* num_total_hits)
50       ICING_EXCLUSIVE_LOCKS_REQUIRED(mutex);
51 
52   // Increment the global counter num_total_hits_ by increment_by, if
53   // num_total_hits_ has been registered (is not nullptr).
54   // Note that providing a negative value for increment_by is a valid usage,
55   // which will actually decrement num_total_hits_.
56   //
57   // It has to be called when we change scored_document_hits_ranker.
58   void IncrementNumTotalHits(int increment_by)
59       ICING_EXCLUSIVE_LOCKS_REQUIRED(mutex);
60 
61   // Returns a nullable pointer to parent adjustment info.
parent_adjustment_info()62   ResultAdjustmentInfo* parent_adjustment_info()
63       ICING_EXCLUSIVE_LOCKS_REQUIRED(mutex) {
64     return parent_adjustment_info_.get();
65   }
66 
67   // Returns a nullable pointer to parent adjustment info.
parent_adjustment_info()68   const ResultAdjustmentInfo* parent_adjustment_info() const
69       ICING_SHARED_LOCKS_REQUIRED(mutex) {
70     return parent_adjustment_info_.get();
71   }
72 
73   // Returns a nullable pointer to child adjustment info.
child_adjustment_info()74   ResultAdjustmentInfo* child_adjustment_info()
75       ICING_EXCLUSIVE_LOCKS_REQUIRED(mutex) {
76     return child_adjustment_info_.get();
77   }
78 
79   // Returns a nullable pointer to child adjustment info.
child_adjustment_info()80   const ResultAdjustmentInfo* child_adjustment_info() const
81       ICING_SHARED_LOCKS_REQUIRED(mutex) {
82     return child_adjustment_info_.get();
83   }
84 
entry_id_group_id_map()85   const std::unordered_map<int32_t, int>& entry_id_group_id_map() const
86       ICING_SHARED_LOCKS_REQUIRED(mutex) {
87     return entry_id_group_id_map_;
88   }
89 
num_per_page()90   int32_t num_per_page() const ICING_SHARED_LOCKS_REQUIRED(mutex) {
91     return num_per_page_;
92   }
93 
num_total_bytes_per_page_threshold()94   int32_t num_total_bytes_per_page_threshold() const
95       ICING_SHARED_LOCKS_REQUIRED(mutex) {
96     return num_total_bytes_per_page_threshold_;
97   }
98 
max_joined_children_per_parent_to_return()99   int32_t max_joined_children_per_parent_to_return() const
100       ICING_SHARED_LOCKS_REQUIRED(mutex) {
101     return max_joined_children_per_parent_to_return_;
102   }
103 
result_group_type()104   ResultSpecProto::ResultGroupingType result_group_type()
105       ICING_SHARED_LOCKS_REQUIRED(mutex) {
106     return result_group_type_;
107   }
108 
109   absl_ports::shared_mutex mutex;
110 
111   // When evaluating the next top K hits from scored_document_hits_ranker, some
112   // of them may be filtered out by group_result_limits and won't return to the
113   // client, so they shouldn't be counted into num_returned. Also the logic of
114   // group result limiting depends on retrieval, so it is impossible for
115   // ResultState itself to correctly modify these fields. Thus, we make them
116   // public, so users of this class can modify them directly.
117 
118   // The scored document hits ranker.
119   std::unique_ptr<ScoredDocumentHitsRanker> scored_document_hits_ranker
120       ICING_GUARDED_BY(mutex);
121 
122   // The count of remaining results to return for a group where group id is the
123   // index.
124   std::vector<int> group_result_limits ICING_GUARDED_BY(mutex);
125 
126   // Number of results that have already been returned.
127   int num_returned ICING_GUARDED_BY(mutex);
128 
129  private:
130   // Adjustment information for parent documents, including snippet and
131   // projection. Can be nullptr if there is no adjustment info for parent
132   // documents.
133   std::unique_ptr<ResultAdjustmentInfo> parent_adjustment_info_
134       ICING_GUARDED_BY(mutex);
135 
136   // Adjustment information for child documents, including snippet and
137   // projection. This is only used for join query. Can be nullptr if there is no
138   // adjustment info for child documents.
139   std::unique_ptr<ResultAdjustmentInfo> child_adjustment_info_
140       ICING_GUARDED_BY(mutex);
141 
142   // A map between result grouping entry id and the id of the group that it
143   // appears in.
144   std::unordered_map<int32_t, int> entry_id_group_id_map_
145       ICING_GUARDED_BY(mutex);
146 
147   // Number of results to return in each page.
148   int32_t num_per_page_ ICING_GUARDED_BY(mutex);
149 
150   // The threshold of total bytes of all documents to cutoff, in order to limit
151   // # of bytes in a single page.
152   // Note that it doesn't guarantee the result # of bytes will be smaller, equal
153   // to, or larger than the threshold. Instead, it is just a threshold to
154   // cutoff, and only guarantees total bytes of search results won't exceed the
155   // threshold too much.
156   int32_t num_total_bytes_per_page_threshold_ ICING_GUARDED_BY(mutex);
157 
158   // Max # of joined child documents to be attached in the result for each
159   // parent document.
160   int32_t max_joined_children_per_parent_to_return_ ICING_GUARDED_BY(mutex);
161 
162   // Pointer to a global counter to sum up the size of scored_document_hits in
163   // all ResultStates.
164   // Does not own.
165   std::atomic<int>* num_total_hits_ ICING_GUARDED_BY(mutex);
166 
167   // Value that the search results will get grouped by.
168   ResultSpecProto::ResultGroupingType result_group_type_
169       ICING_GUARDED_BY(mutex);
170 };
171 
172 }  // namespace lib
173 }  // namespace icing
174 
175 #endif  // ICING_RESULT_RESULT_STATE_V2_H_
176