blob: 919710eb54bb2782e8a96c037166f5c2cda5c474 [file]
// Copyright (C) 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef ICING_RESULT_RESULT_STATE_V2_H_
#define ICING_RESULT_RESULT_STATE_V2_H_
#include <atomic>
#include <cstdint>
#include <memory>
#include <unordered_map>
#include <vector>
#include "icing/absl_ports/mutex.h"
#include "icing/absl_ports/thread_annotations.h"
#include "icing/proto/search.pb.h"
#include "icing/result/result-adjustment-info.h"
#include "icing/scoring/scored-document-hits-ranker.h"
#include "icing/store/document-store.h"
namespace icing {
namespace lib {
// Used to hold information needed across multiple pagination requests of the
// same query. Stored in ResultStateManager.
class ResultStateV2 {
public:
explicit ResultStateV2(
std::unique_ptr<ScoredDocumentHitsRanker> scored_document_hits_ranker_in,
std::unique_ptr<ResultAdjustmentInfo> parent_adjustment_info,
std::unique_ptr<ResultAdjustmentInfo> child_adjustment_info,
const ResultSpecProto& result_spec, const DocumentStore& document_store);
~ResultStateV2();
// Register num_total_hits_ and add current scored_document_hits_ranker.size()
// to it. When re-registering, it will subtract
// scored_document_hits_ranker.size() from the original counter.
void RegisterNumTotalHits(std::atomic<int>* num_total_hits)
ICING_EXCLUSIVE_LOCKS_REQUIRED(mutex);
// Increment the global counter num_total_hits_ by increment_by, if
// num_total_hits_ has been registered (is not nullptr).
// Note that providing a negative value for increment_by is a valid usage,
// which will actually decrement num_total_hits_.
//
// It has to be called when we change scored_document_hits_ranker.
void IncrementNumTotalHits(int increment_by)
ICING_EXCLUSIVE_LOCKS_REQUIRED(mutex);
// Returns a nullable pointer to parent adjustment info.
ResultAdjustmentInfo* parent_adjustment_info()
ICING_EXCLUSIVE_LOCKS_REQUIRED(mutex) {
return parent_adjustment_info_.get();
}
// Returns a nullable pointer to parent adjustment info.
const ResultAdjustmentInfo* parent_adjustment_info() const
ICING_SHARED_LOCKS_REQUIRED(mutex) {
return parent_adjustment_info_.get();
}
// Returns a nullable pointer to child adjustment info.
ResultAdjustmentInfo* child_adjustment_info()
ICING_EXCLUSIVE_LOCKS_REQUIRED(mutex) {
return child_adjustment_info_.get();
}
// Returns a nullable pointer to child adjustment info.
const ResultAdjustmentInfo* child_adjustment_info() const
ICING_SHARED_LOCKS_REQUIRED(mutex) {
return child_adjustment_info_.get();
}
const std::unordered_map<int32_t, int>& entry_id_group_id_map() const
ICING_SHARED_LOCKS_REQUIRED(mutex) {
return entry_id_group_id_map_;
}
int32_t num_per_page() const ICING_SHARED_LOCKS_REQUIRED(mutex) {
return num_per_page_;
}
int32_t num_total_bytes_per_page_threshold() const
ICING_SHARED_LOCKS_REQUIRED(mutex) {
return num_total_bytes_per_page_threshold_;
}
int32_t max_joined_children_per_parent_to_return() const
ICING_SHARED_LOCKS_REQUIRED(mutex) {
return max_joined_children_per_parent_to_return_;
}
ResultSpecProto::ResultGroupingType result_group_type()
ICING_SHARED_LOCKS_REQUIRED(mutex) {
return result_group_type_;
}
absl_ports::shared_mutex mutex;
// When evaluating the next top K hits from scored_document_hits_ranker, some
// of them may be filtered out by group_result_limits and won't return to the
// client, so they shouldn't be counted into num_returned. Also the logic of
// group result limiting depends on retrieval, so it is impossible for
// ResultState itself to correctly modify these fields. Thus, we make them
// public, so users of this class can modify them directly.
// The scored document hits ranker.
std::unique_ptr<ScoredDocumentHitsRanker> scored_document_hits_ranker
ICING_GUARDED_BY(mutex);
// The count of remaining results to return for a group where group id is the
// index.
std::vector<int> group_result_limits ICING_GUARDED_BY(mutex);
// Number of results that have already been returned.
int num_returned ICING_GUARDED_BY(mutex);
private:
// Adjustment information for parent documents, including snippet and
// projection. Can be nullptr if there is no adjustment info for parent
// documents.
std::unique_ptr<ResultAdjustmentInfo> parent_adjustment_info_
ICING_GUARDED_BY(mutex);
// Adjustment information for child documents, including snippet and
// projection. This is only used for join query. Can be nullptr if there is no
// adjustment info for child documents.
std::unique_ptr<ResultAdjustmentInfo> child_adjustment_info_
ICING_GUARDED_BY(mutex);
// A map between result grouping entry id and the id of the group that it
// appears in.
std::unordered_map<int32_t, int> entry_id_group_id_map_
ICING_GUARDED_BY(mutex);
// Number of results to return in each page.
int32_t num_per_page_ ICING_GUARDED_BY(mutex);
// The threshold of total bytes of all documents to cutoff, in order to limit
// # of bytes in a single page.
// Note that it doesn't guarantee the result # of bytes will be smaller, equal
// to, or larger than the threshold. Instead, it is just a threshold to
// cutoff, and only guarantees total bytes of search results won't exceed the
// threshold too much.
int32_t num_total_bytes_per_page_threshold_ ICING_GUARDED_BY(mutex);
// Max # of joined child documents to be attached in the result for each
// parent document.
int32_t max_joined_children_per_parent_to_return_ ICING_GUARDED_BY(mutex);
// Pointer to a global counter to sum up the size of scored_document_hits in
// all ResultStates.
// Does not own.
std::atomic<int>* num_total_hits_ ICING_GUARDED_BY(mutex);
// Value that the search results will get grouped by.
ResultSpecProto::ResultGroupingType result_group_type_
ICING_GUARDED_BY(mutex);
};
} // namespace lib
} // namespace icing
#endif // ICING_RESULT_RESULT_STATE_V2_H_