diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-06-03 21:05:38 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-06-03 21:05:38 +0000 |
commit | 5731afd2647d6ee0b8bcfa1f3afe97e22c7d7140 (patch) | |
tree | abdc5e8d95a65551a3ae923942417330a5e9241b | |
parent | fc00d0ee283c95b003010d38f32845292b22fd66 (diff) | |
parent | 44b77e1c87fcd576022edc03a87c309c7fc7e04e (diff) | |
download | icing-android14-d1-s4-release.tar.gz |
Snap for 10255852 from 44b77e1c87fcd576022edc03a87c309c7fc7e04e to udc-d1-releaseandroid-14.0.0_r9android-14.0.0_r8android-14.0.0_r7android-14.0.0_r6android-14.0.0_r5android-14.0.0_r4android-14.0.0_r3android-14.0.0_r12android-14.0.0_r11android-14.0.0_r10android14-d1-s7-releaseandroid14-d1-s6-releaseandroid14-d1-s5-releaseandroid14-d1-s4-releaseandroid14-d1-s3-releaseandroid14-d1-s2-releaseandroid14-d1-s1-releaseandroid14-d1-release
Change-Id: I515411e6f97ad22a01493420f56809d63ea8cf7d
66 files changed, 1696 insertions, 1131 deletions
diff --git a/icing/file/filesystem.cc b/icing/file/filesystem.cc index c83a351..cd905e7 100644 --- a/icing/file/filesystem.cc +++ b/icing/file/filesystem.cc @@ -72,7 +72,7 @@ void LogOpenFileDescriptors() { << ") too large."; fd_lim = kMaxFileDescriptorsToStat; } - ICING_LOG(ERROR) << "Listing up to " << fd_lim << " file descriptors."; + ICING_LOG(INFO) << "Listing up to " << fd_lim << " file descriptors."; // Verify that /proc/self/fd is a directory. If not, procfs is not mounted or // inaccessible for some other reason. In that case, there's no point trying @@ -94,12 +94,12 @@ void LogOpenFileDescriptors() { if (len >= 0) { // Zero-terminate the buffer, because readlink() won't. target[len < target_size ? len : target_size - 1] = '\0'; - ICING_LOG(ERROR) << "fd " << fd << " -> \"" << target << "\""; + ICING_LOG(INFO) << "fd " << fd << " -> \"" << target << "\""; } else if (errno != ENOENT) { ICING_LOG(ERROR) << "fd " << fd << " -> ? (errno=" << errno << ")"; } } - ICING_LOG(ERROR) << "File descriptor list complete."; + ICING_LOG(INFO) << "File descriptor list complete."; } // Logs an error formatted as: desc1 + file_name + desc2 + strerror(errnum). @@ -108,7 +108,11 @@ void LogOpenFileDescriptors() { // file descriptors (see LogOpenFileDescriptors() above). void LogOpenError(const char* desc1, const char* file_name, const char* desc2, int errnum) { - ICING_LOG(ERROR) << desc1 << file_name << desc2 << strerror(errnum); + if (errnum == ENOENT) { + ICING_VLOG(1) << desc1 << file_name << desc2 << strerror(errnum); + } else { + ICING_LOG(ERROR) << desc1 << file_name << desc2 << strerror(errnum); + } if (errnum == EMFILE) { LogOpenFileDescriptors(); } @@ -361,7 +365,11 @@ int Filesystem::OpenForRead(const char* file_name) const { int64_t Filesystem::GetFileSize(int fd) const { struct stat st; if (fstat(fd, &st) < 0) { - ICING_LOG(ERROR) << "Unable to stat file: " << strerror(errno); + if (errno == ENOENT) { + ICING_VLOG(1) << "Unable to stat file: " << strerror(errno); + } else { + ICING_LOG(WARNING) << "Unable to stat file: " << strerror(errno); + } return kBadFileSize; } return st.st_size; diff --git a/icing/icing-search-engine.cc b/icing/icing-search-engine.cc index d6e25a2..2cdf930 100644 --- a/icing/icing-search-engine.cc +++ b/icing/icing-search-engine.cc @@ -728,8 +728,7 @@ libtextclassifier3::Status IcingSearchEngine::InitializeMembers( } result_state_manager_ = std::make_unique<ResultStateManager>( - performance_configuration_.max_num_total_hits, *document_store_, - clock_.get()); + performance_configuration_.max_num_total_hits, *document_store_); return status; } @@ -1156,8 +1155,9 @@ PutResultProto IcingSearchEngine::Put(DocumentProto&& document) { if (!index_status.ok()) { // If we encountered a failure or cannot resolve an internal error while // indexing this document, then mark it as deleted. + int64_t current_time_ms = clock_->GetSystemTimeMilliseconds(); libtextclassifier3::Status delete_status = - document_store_->Delete(document_id); + document_store_->Delete(document_id, current_time_ms); if (!delete_status.ok()) { // This is pretty dire (and, hopefully, unlikely). We can't roll back the // document that we just added. Wipeout the whole index. @@ -1276,7 +1276,9 @@ DeleteResultProto IcingSearchEngine::Delete(const std::string_view name_space, std::unique_ptr<Timer> delete_timer = clock_->GetNewTimer(); // TODO(b/216487496): Implement a more robust version of TC_RETURN_IF_ERROR // that can support error logging. - libtextclassifier3::Status status = document_store_->Delete(name_space, uri); + int64_t current_time_ms = clock_->GetSystemTimeMilliseconds(); + libtextclassifier3::Status status = + document_store_->Delete(name_space, uri, current_time_ms); if (!status.ok()) { LogSeverity::Code severity = ERROR; if (absl_ports::IsNotFound(status)) { @@ -1410,8 +1412,9 @@ DeleteByQueryResultProto IcingSearchEngine::DeleteByQuery( std::unique_ptr<QueryProcessor> query_processor = std::move(query_processor_or).ValueOrDie(); + int64_t current_time_ms = clock_->GetSystemTimeMilliseconds(); auto query_results_or = query_processor->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::NONE); + search_spec, ScoringSpecProto::RankingStrategy::NONE, current_time_ms); if (!query_results_or.ok()) { TransformStatus(query_results_or.status(), result_status); delete_stats->set_parse_query_latency_ms( @@ -1448,7 +1451,8 @@ DeleteByQueryResultProto IcingSearchEngine::DeleteByQuery( } } status = document_store_->Delete( - query_results.root_iterator->doc_hit_info().document_id()); + query_results.root_iterator->doc_hit_info().document_id(), + current_time_ms); if (!status.ok()) { TransformStatus(status, result_status); delete_stats->set_document_removal_latency_ms( @@ -1897,14 +1901,15 @@ SearchResultProto IcingSearchEngine::InternalSearch( const JoinSpecProto& join_spec = search_spec.join_spec(); std::unique_ptr<JoinChildrenFetcher> join_children_fetcher; std::unique_ptr<ResultAdjustmentInfo> child_result_adjustment_info; + int64_t current_time_ms = clock_->GetSystemTimeMilliseconds(); if (!join_spec.parent_property_expression().empty() && !join_spec.child_property_expression().empty()) { // Process child query - QueryScoringResults nested_query_scoring_results = - ProcessQueryAndScore(join_spec.nested_spec().search_spec(), - join_spec.nested_spec().scoring_spec(), - join_spec.nested_spec().result_spec(), - /*join_children_fetcher=*/nullptr); + QueryScoringResults nested_query_scoring_results = ProcessQueryAndScore( + join_spec.nested_spec().search_spec(), + join_spec.nested_spec().scoring_spec(), + join_spec.nested_spec().result_spec(), + /*join_children_fetcher=*/nullptr, current_time_ms); // TOOD(b/256022027): set different kinds of latency for 2nd query. if (!nested_query_scoring_results.status.ok()) { TransformStatus(nested_query_scoring_results.status, result_status); @@ -1912,7 +1917,8 @@ SearchResultProto IcingSearchEngine::InternalSearch( } JoinProcessor join_processor(document_store_.get(), schema_store_.get(), - qualified_id_join_index_.get()); + qualified_id_join_index_.get(), + current_time_ms); // Building a JoinChildrenFetcher where child documents are grouped by // their joinable values. libtextclassifier3::StatusOr<JoinChildrenFetcher> join_children_fetcher_or = @@ -1935,8 +1941,9 @@ SearchResultProto IcingSearchEngine::InternalSearch( } // Process parent query - QueryScoringResults query_scoring_results = ProcessQueryAndScore( - search_spec, scoring_spec, result_spec, join_children_fetcher.get()); + QueryScoringResults query_scoring_results = + ProcessQueryAndScore(search_spec, scoring_spec, result_spec, + join_children_fetcher.get(), current_time_ms); int term_count = 0; for (const auto& section_and_terms : query_scoring_results.query_terms) { term_count += section_and_terms.second.size(); @@ -1968,7 +1975,8 @@ SearchResultProto IcingSearchEngine::InternalSearch( std::unique_ptr<Timer> join_timer = clock_->GetNewTimer(); // Join 2 scored document hits JoinProcessor join_processor(document_store_.get(), schema_store_.get(), - qualified_id_join_index_.get()); + qualified_id_join_index_.get(), + current_time_ms); libtextclassifier3::StatusOr<std::vector<JoinedScoredDocumentHit>> joined_result_document_hits_or = join_processor.Join( join_spec, std::move(query_scoring_results.scored_document_hits), @@ -2023,7 +2031,7 @@ SearchResultProto IcingSearchEngine::InternalSearch( page_result_info_or = result_state_manager_->CacheAndRetrieveFirstPage( std::move(ranker), std::move(parent_result_adjustment_info), std::move(child_result_adjustment_info), result_spec, - *document_store_, *result_retriever); + *document_store_, *result_retriever, current_time_ms); if (!page_result_info_or.ok()) { TransformStatus(page_result_info_or.status(), result_status); query_stats->set_document_retrieval_latency_ms( @@ -2064,7 +2072,7 @@ SearchResultProto IcingSearchEngine::InternalSearch( IcingSearchEngine::QueryScoringResults IcingSearchEngine::ProcessQueryAndScore( const SearchSpecProto& search_spec, const ScoringSpecProto& scoring_spec, const ResultSpecProto& result_spec, - const JoinChildrenFetcher* join_children_fetcher) { + const JoinChildrenFetcher* join_children_fetcher, int64_t current_time_ms) { std::unique_ptr<Timer> component_timer = clock_->GetNewTimer(); // Gets unordered results from query processor @@ -2085,7 +2093,7 @@ IcingSearchEngine::QueryScoringResults IcingSearchEngine::ProcessQueryAndScore( libtextclassifier3::StatusOr<QueryResults> query_results_or; if (ranking_strategy_or.ok()) { query_results_or = query_processor->ParseSearch( - search_spec, ranking_strategy_or.ValueOrDie()); + search_spec, ranking_strategy_or.ValueOrDie(), current_time_ms); } else { query_results_or = ranking_strategy_or.status(); } @@ -2102,9 +2110,9 @@ IcingSearchEngine::QueryScoringResults IcingSearchEngine::ProcessQueryAndScore( component_timer = clock_->GetNewTimer(); // Scores but does not rank the results. libtextclassifier3::StatusOr<std::unique_ptr<ScoringProcessor>> - scoring_processor_or = - ScoringProcessor::Create(scoring_spec, document_store_.get(), - schema_store_.get(), join_children_fetcher); + scoring_processor_or = ScoringProcessor::Create( + scoring_spec, document_store_.get(), schema_store_.get(), + current_time_ms, join_children_fetcher); if (!scoring_processor_or.ok()) { return QueryScoringResults(std::move(scoring_processor_or).status(), std::move(query_results.query_terms), @@ -2154,9 +2162,10 @@ SearchResultProto IcingSearchEngine::GetNextPage(uint64_t next_page_token) { std::unique_ptr<ResultRetrieverV2> result_retriever = std::move(result_retriever_or).ValueOrDie(); + int64_t current_time_ms = clock_->GetSystemTimeMilliseconds(); libtextclassifier3::StatusOr<std::pair<uint64_t, PageResult>> page_result_info_or = result_state_manager_->GetNextPage( - next_page_token, *result_retriever); + next_page_token, *result_retriever, current_time_ms); if (!page_result_info_or.ok()) { if (absl_ports::IsNotFound(page_result_info_or.status())) { // NOT_FOUND means an empty result. @@ -2285,8 +2294,7 @@ IcingSearchEngine::OptimizeDocumentStore(OptimizeStatsProto* optimize_stats) { } document_store_ = std::move(create_result_or.ValueOrDie().document_store); result_state_manager_ = std::make_unique<ResultStateManager>( - performance_configuration_.max_num_total_hits, *document_store_, - clock_.get()); + performance_configuration_.max_num_total_hits, *document_store_); // Potential data loss // TODO(b/147373249): Find a way to detect true data loss error @@ -2310,8 +2318,7 @@ IcingSearchEngine::OptimizeDocumentStore(OptimizeStatsProto* optimize_stats) { } document_store_ = std::move(create_result_or.ValueOrDie().document_store); result_state_manager_ = std::make_unique<ResultStateManager>( - performance_configuration_.max_num_total_hits, *document_store_, - clock_.get()); + performance_configuration_.max_num_total_hits, *document_store_); // Deletes tmp directory if (!filesystem_->DeleteDirectoryRecursively( @@ -2689,8 +2696,9 @@ SuggestionResponse IcingSearchEngine::SearchSuggestions( std::move(suggestion_processor_or).ValueOrDie(); // Run suggestion based on given SuggestionSpec. + int64_t current_time_ms = clock_->GetSystemTimeMilliseconds(); libtextclassifier3::StatusOr<std::vector<TermMetadata>> terms_or = - suggestion_processor->QuerySuggestions(suggestion_spec); + suggestion_processor->QuerySuggestions(suggestion_spec, current_time_ms); if (!terms_or.ok()) { TransformStatus(terms_or.status(), response_status); return response; diff --git a/icing/icing-search-engine.h b/icing/icing-search-engine.h index 1a5d130..15da142 100644 --- a/icing/icing-search-engine.h +++ b/icing/icing-search-engine.h @@ -620,7 +620,7 @@ class IcingSearchEngine { QueryScoringResults ProcessQueryAndScore( const SearchSpecProto& search_spec, const ScoringSpecProto& scoring_spec, const ResultSpecProto& result_spec, - const JoinChildrenFetcher* join_children_fetcher) + const JoinChildrenFetcher* join_children_fetcher, int64_t current_time_ms) ICING_SHARED_LOCKS_REQUIRED(mutex_); // Many of the internal components rely on other components' derived data. diff --git a/icing/index/index-processor_test.cc b/icing/index/index-processor_test.cc index 581645a..0a0108d 100644 --- a/icing/index/index-processor_test.cc +++ b/icing/index/index-processor_test.cc @@ -1552,10 +1552,11 @@ TEST_F(IndexProcessorTest, IndexableIntegerProperty) { EXPECT_THAT(index_processor_->IndexDocument(tokenized_document, kDocumentId0), IsOk()); - ICING_ASSERT_OK_AND_ASSIGN(std::unique_ptr<DocHitInfoIterator> itr, - integer_index_->GetIterator( - kIndexableIntegerProperty, /*key_lower=*/1, - /*key_upper=*/5, *doc_store_, *schema_store_)); + ICING_ASSERT_OK_AND_ASSIGN( + std::unique_ptr<DocHitInfoIterator> itr, + integer_index_->GetIterator(kIndexableIntegerProperty, /*key_lower=*/1, + /*key_upper=*/5, *doc_store_, *schema_store_, + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT( GetHits(std::move(itr)), @@ -1581,10 +1582,11 @@ TEST_F(IndexProcessorTest, IndexableIntegerPropertyNoMatch) { EXPECT_THAT(index_processor_->IndexDocument(tokenized_document, kDocumentId0), IsOk()); - ICING_ASSERT_OK_AND_ASSIGN(std::unique_ptr<DocHitInfoIterator> itr, - integer_index_->GetIterator( - kIndexableIntegerProperty, /*key_lower=*/-1, - /*key_upper=*/0, *doc_store_, *schema_store_)); + ICING_ASSERT_OK_AND_ASSIGN( + std::unique_ptr<DocHitInfoIterator> itr, + integer_index_->GetIterator(kIndexableIntegerProperty, /*key_lower=*/-1, + /*key_upper=*/0, *doc_store_, *schema_store_, + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(GetHits(std::move(itr)), IsEmpty()); } diff --git a/icing/index/integer-section-indexing-handler_test.cc b/icing/index/integer-section-indexing-handler_test.cc index 389caef..96e21ca 100644 --- a/icing/index/integer-section-indexing-handler_test.cc +++ b/icing/index/integer-section-indexing-handler_test.cc @@ -250,7 +250,7 @@ TEST_F(IntegerSectionIndexingHandlerTest, HandleIntegerSection) { integer_index_->GetIterator( kPropertyTimestamp, /*key_lower=*/std::numeric_limits<int64_t>::min(), /*key_upper=*/std::numeric_limits<int64_t>::max(), *document_store_, - *schema_store_)); + *schema_store_, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(GetHits(std::move(itr)), ElementsAre(EqualsDocHitInfo( document_id, std::vector<SectionId>{kSectionIdTimestamp}))); @@ -299,7 +299,7 @@ TEST_F(IntegerSectionIndexingHandlerTest, HandleNestedIntegerSection) { integer_index_->GetIterator( "nested.timestamp", /*key_lower=*/std::numeric_limits<int64_t>::min(), /*key_upper=*/std::numeric_limits<int64_t>::max(), *document_store_, - *schema_store_)); + *schema_store_, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT( GetHits(std::move(itr)), ElementsAre(EqualsDocHitInfo( @@ -311,7 +311,7 @@ TEST_F(IntegerSectionIndexingHandlerTest, HandleNestedIntegerSection) { integer_index_->GetIterator( kPropertyPrice, /*key_lower=*/std::numeric_limits<int64_t>::min(), /*key_upper=*/std::numeric_limits<int64_t>::max(), *document_store_, - *schema_store_)); + *schema_store_, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(GetHits(std::move(itr)), ElementsAre(EqualsDocHitInfo( document_id, std::vector<SectionId>{kSectionIdPrice}))); @@ -322,7 +322,7 @@ TEST_F(IntegerSectionIndexingHandlerTest, HandleNestedIntegerSection) { integer_index_->GetIterator( kPropertyTimestamp, /*key_lower=*/std::numeric_limits<int64_t>::min(), /*key_upper=*/std::numeric_limits<int64_t>::max(), *document_store_, - *schema_store_)); + *schema_store_, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(GetHits(std::move(itr)), IsEmpty()); } @@ -362,7 +362,7 @@ TEST_F(IntegerSectionIndexingHandlerTest, HandleShouldSkipEmptyIntegerSection) { integer_index_->GetIterator( kPropertyTimestamp, /*key_lower=*/std::numeric_limits<int64_t>::min(), /*key_upper=*/std::numeric_limits<int64_t>::max(), *document_store_, - *schema_store_)); + *schema_store_, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(GetHits(std::move(itr)), IsEmpty()); } @@ -405,7 +405,7 @@ TEST_F(IntegerSectionIndexingHandlerTest, integer_index_->GetIterator( kPropertyTimestamp, /*key_lower=*/std::numeric_limits<int64_t>::min(), /*key_upper=*/std::numeric_limits<int64_t>::max(), *document_store_, - *schema_store_)); + *schema_store_, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(GetHits(std::move(itr)), IsEmpty()); // Recovery mode should get the same result. @@ -421,7 +421,7 @@ TEST_F(IntegerSectionIndexingHandlerTest, integer_index_->GetIterator( kPropertyTimestamp, /*key_lower=*/std::numeric_limits<int64_t>::min(), /*key_upper=*/std::numeric_limits<int64_t>::max(), *document_store_, - *schema_store_)); + *schema_store_, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(GetHits(std::move(itr)), IsEmpty()); } @@ -465,7 +465,7 @@ TEST_F(IntegerSectionIndexingHandlerTest, integer_index_->GetIterator( kPropertyTimestamp, /*key_lower=*/std::numeric_limits<int64_t>::min(), /*key_upper=*/std::numeric_limits<int64_t>::max(), *document_store_, - *schema_store_)); + *schema_store_, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(GetHits(std::move(itr)), IsEmpty()); // Handling document with document_id < last_added_document_id should cause a @@ -485,7 +485,7 @@ TEST_F(IntegerSectionIndexingHandlerTest, integer_index_->GetIterator( kPropertyTimestamp, /*key_lower=*/std::numeric_limits<int64_t>::min(), /*key_upper=*/std::numeric_limits<int64_t>::max(), *document_store_, - *schema_store_)); + *schema_store_, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(GetHits(std::move(itr)), IsEmpty()); } @@ -541,7 +541,7 @@ TEST_F(IntegerSectionIndexingHandlerTest, integer_index_->GetIterator( kPropertyTimestamp, /*key_lower=*/std::numeric_limits<int64_t>::min(), /*key_upper=*/std::numeric_limits<int64_t>::max(), *document_store_, - *schema_store_)); + *schema_store_, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(GetHits(std::move(itr)), ElementsAre(EqualsDocHitInfo( document_id1, std::vector<SectionId>{kSectionIdTimestamp}))); @@ -564,7 +564,7 @@ TEST_F(IntegerSectionIndexingHandlerTest, integer_index_->GetIterator( kPropertyTimestamp, /*key_lower=*/std::numeric_limits<int64_t>::min(), /*key_upper=*/std::numeric_limits<int64_t>::max(), *document_store_, - *schema_store_)); + *schema_store_, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(GetHits(std::move(itr)), ElementsAre(EqualsDocHitInfo( document_id1, std::vector<SectionId>{kSectionIdTimestamp}))); @@ -586,7 +586,7 @@ TEST_F(IntegerSectionIndexingHandlerTest, integer_index_->GetIterator( kPropertyTimestamp, /*key_lower=*/std::numeric_limits<int64_t>::min(), /*key_upper=*/std::numeric_limits<int64_t>::max(), *document_store_, - *schema_store_)); + *schema_store_, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(GetHits(std::move(itr)), ElementsAre(EqualsDocHitInfo( document_id1, std::vector<SectionId>{kSectionIdTimestamp}))); diff --git a/icing/index/iterator/doc-hit-info-iterator-filter.cc b/icing/index/iterator/doc-hit-info-iterator-filter.cc index 2c0c2c2..a82e556 100644 --- a/icing/index/iterator/doc-hit-info-iterator-filter.cc +++ b/icing/index/iterator/doc-hit-info-iterator-filter.cc @@ -38,11 +38,12 @@ namespace lib { DocHitInfoIteratorFilter::DocHitInfoIteratorFilter( std::unique_ptr<DocHitInfoIterator> delegate, const DocumentStore* document_store, const SchemaStore* schema_store, - const Options& options) + const Options& options, int64_t current_time_ms) : delegate_(std::move(delegate)), document_store_(*document_store), schema_store_(*schema_store), - options_(options) { + options_(options), + current_time_ms_(current_time_ms) { // Precompute all the NamespaceIds for (std::string_view name_space : options_.namespaces) { auto namespace_id_or = document_store_.GetNamespaceId(name_space); @@ -74,7 +75,7 @@ libtextclassifier3::Status DocHitInfoIteratorFilter::Advance() { // Try to get the DocumentFilterData auto document_filter_data_optional = document_store_.GetAliveDocumentFilterData( - delegate_->doc_hit_info().document_id()); + delegate_->doc_hit_info().document_id(), current_time_ms_); if (!document_filter_data_optional) { // Didn't find the DocumentFilterData in the filter cache. This could be // because the Document doesn't exist or the DocumentId isn't valid or the @@ -117,7 +118,7 @@ DocHitInfoIteratorFilter::TrimRightMostNode() && { if (trimmed_delegate.iterator_ != nullptr) { trimmed_delegate.iterator_ = std::make_unique<DocHitInfoIteratorFilter>( std::move(trimmed_delegate.iterator_), &document_store_, &schema_store_, - options_); + options_, current_time_ms_); } return trimmed_delegate; } diff --git a/icing/index/iterator/doc-hit-info-iterator-filter.h b/icing/index/iterator/doc-hit-info-iterator-filter.h index ab13ae5..be5e1e8 100644 --- a/icing/index/iterator/doc-hit-info-iterator-filter.h +++ b/icing/index/iterator/doc-hit-info-iterator-filter.h @@ -56,7 +56,7 @@ class DocHitInfoIteratorFilter : public DocHitInfoIterator { explicit DocHitInfoIteratorFilter( std::unique_ptr<DocHitInfoIterator> delegate, const DocumentStore* document_store, const SchemaStore* schema_store, - const Options& options); + const Options& options, int64_t current_time_ms); libtextclassifier3::Status Advance() override; @@ -82,6 +82,7 @@ class DocHitInfoIteratorFilter : public DocHitInfoIterator { const Options options_; std::unordered_set<NamespaceId> target_namespace_ids_; std::unordered_set<SchemaTypeId> target_schema_type_ids_; + int64_t current_time_ms_; }; } // namespace lib diff --git a/icing/index/iterator/doc-hit-info-iterator-filter_test.cc b/icing/index/iterator/doc-hit-info-iterator-filter_test.cc index 4b86cae..d8839dc 100644 --- a/icing/index/iterator/doc-hit-info-iterator-filter_test.cc +++ b/icing/index/iterator/doc-hit-info-iterator-filter_test.cc @@ -117,9 +117,9 @@ TEST_F(DocHitInfoIteratorDeletedFilterTest, EmptyOriginalIterator) { std::unique_ptr<DocHitInfoIterator> original_iterator_empty = std::make_unique<DocHitInfoIteratorDummy>(); - DocHitInfoIteratorFilter filtered_iterator(std::move(original_iterator_empty), - document_store_.get(), - schema_store_.get(), options_); + DocHitInfoIteratorFilter filtered_iterator( + std::move(original_iterator_empty), document_store_.get(), + schema_store_.get(), options_, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(GetDocumentIds(&filtered_iterator), IsEmpty()); } @@ -132,8 +132,9 @@ TEST_F(DocHitInfoIteratorDeletedFilterTest, DeletedDocumentsAreFiltered) { ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id3, document_store_->Put(test_document3_)); // Deletes test document 2 - ICING_ASSERT_OK(document_store_->Delete(test_document2_.namespace_(), - test_document2_.uri())); + ICING_ASSERT_OK(document_store_->Delete( + test_document2_.namespace_(), test_document2_.uri(), + fake_clock_.GetSystemTimeMilliseconds())); std::vector<DocHitInfo> doc_hit_infos = {DocHitInfo(document_id1), DocHitInfo(document_id2), @@ -141,9 +142,9 @@ TEST_F(DocHitInfoIteratorDeletedFilterTest, DeletedDocumentsAreFiltered) { std::unique_ptr<DocHitInfoIterator> original_iterator = std::make_unique<DocHitInfoIteratorDummy>(doc_hit_infos); - DocHitInfoIteratorFilter filtered_iterator(std::move(original_iterator), - document_store_.get(), - schema_store_.get(), options_); + DocHitInfoIteratorFilter filtered_iterator( + std::move(original_iterator), document_store_.get(), schema_store_.get(), + options_, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(GetDocumentIds(&filtered_iterator), ElementsAre(document_id1, document_id3)); @@ -167,9 +168,9 @@ TEST_F(DocHitInfoIteratorDeletedFilterTest, NonExistingDocumentsAreFiltered) { std::unique_ptr<DocHitInfoIterator> original_iterator = std::make_unique<DocHitInfoIteratorDummy>(doc_hit_infos); - DocHitInfoIteratorFilter filtered_iterator(std::move(original_iterator), - document_store_.get(), - schema_store_.get(), options_); + DocHitInfoIteratorFilter filtered_iterator( + std::move(original_iterator), document_store_.get(), schema_store_.get(), + options_, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(GetDocumentIds(&filtered_iterator), ElementsAre(document_id1, document_id2, document_id3)); @@ -180,9 +181,9 @@ TEST_F(DocHitInfoIteratorDeletedFilterTest, NegativeDocumentIdIsIgnored) { std::unique_ptr<DocHitInfoIterator> original_iterator = std::make_unique<DocHitInfoIteratorDummy>(doc_hit_infos); - DocHitInfoIteratorFilter filtered_iterator(std::move(original_iterator), - document_store_.get(), - schema_store_.get(), options_); + DocHitInfoIteratorFilter filtered_iterator( + std::move(original_iterator), document_store_.get(), schema_store_.get(), + options_, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(filtered_iterator.Advance(), StatusIs(libtextclassifier3::StatusCode::RESOURCE_EXHAUSTED)); @@ -194,9 +195,9 @@ TEST_F(DocHitInfoIteratorDeletedFilterTest, InvalidDocumentIdIsIgnored) { std::unique_ptr<DocHitInfoIterator> original_iterator = std::make_unique<DocHitInfoIteratorDummy>(doc_hit_infos); - DocHitInfoIteratorFilter filtered_iterator(std::move(original_iterator), - document_store_.get(), - schema_store_.get(), options_); + DocHitInfoIteratorFilter filtered_iterator( + std::move(original_iterator), document_store_.get(), schema_store_.get(), + options_, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(filtered_iterator.Advance(), StatusIs(libtextclassifier3::StatusCode::RESOURCE_EXHAUSTED)); @@ -211,9 +212,9 @@ TEST_F(DocHitInfoIteratorDeletedFilterTest, GreaterThanMaxDocumentIdIsIgnored) { std::unique_ptr<DocHitInfoIterator> original_iterator = std::make_unique<DocHitInfoIteratorDummy>(doc_hit_infos); - DocHitInfoIteratorFilter filtered_iterator(std::move(original_iterator), - document_store_.get(), - schema_store_.get(), options_); + DocHitInfoIteratorFilter filtered_iterator( + std::move(original_iterator), document_store_.get(), schema_store_.get(), + options_, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(filtered_iterator.Advance(), StatusIs(libtextclassifier3::StatusCode::RESOURCE_EXHAUSTED)); @@ -289,9 +290,9 @@ TEST_F(DocHitInfoIteratorNamespaceFilterTest, EmptyOriginalIterator) { std::make_unique<DocHitInfoIteratorDummy>(); options_.namespaces = std::vector<std::string_view>{}; - DocHitInfoIteratorFilter filtered_iterator(std::move(original_iterator_empty), - document_store_.get(), - schema_store_.get(), options_); + DocHitInfoIteratorFilter filtered_iterator( + std::move(original_iterator_empty), document_store_.get(), + schema_store_.get(), options_, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(GetDocumentIds(&filtered_iterator), IsEmpty()); } @@ -307,9 +308,9 @@ TEST_F(DocHitInfoIteratorNamespaceFilterTest, std::make_unique<DocHitInfoIteratorDummy>(doc_hit_infos); options_.namespaces = std::vector<std::string_view>{"nonexistent_namespace"}; - DocHitInfoIteratorFilter filtered_iterator(std::move(original_iterator), - document_store_.get(), - schema_store_.get(), options_); + DocHitInfoIteratorFilter filtered_iterator( + std::move(original_iterator), document_store_.get(), schema_store_.get(), + options_, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(GetDocumentIds(&filtered_iterator), IsEmpty()); } @@ -324,9 +325,9 @@ TEST_F(DocHitInfoIteratorNamespaceFilterTest, NoNamespacesReturnsAll) { std::make_unique<DocHitInfoIteratorDummy>(doc_hit_infos); options_.namespaces = std::vector<std::string_view>{}; - DocHitInfoIteratorFilter filtered_iterator(std::move(original_iterator), - document_store_.get(), - schema_store_.get(), options_); + DocHitInfoIteratorFilter filtered_iterator( + std::move(original_iterator), document_store_.get(), schema_store_.get(), + options_, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(GetDocumentIds(&filtered_iterator), ElementsAre(document_id1)); } @@ -348,9 +349,9 @@ TEST_F(DocHitInfoIteratorNamespaceFilterTest, std::make_unique<DocHitInfoIteratorDummy>(doc_hit_infos); options_.namespaces = std::vector<std::string_view>{namespace1_}; - DocHitInfoIteratorFilter filtered_iterator(std::move(original_iterator), - document_store_.get(), - schema_store_.get(), options_); + DocHitInfoIteratorFilter filtered_iterator( + std::move(original_iterator), document_store_.get(), schema_store_.get(), + options_, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(GetDocumentIds(&filtered_iterator), ElementsAre(document_id1, document_id2)); @@ -374,9 +375,9 @@ TEST_F(DocHitInfoIteratorNamespaceFilterTest, FilterForMultipleNamespacesOk) { std::make_unique<DocHitInfoIteratorDummy>(doc_hit_infos); options_.namespaces = std::vector<std::string_view>{namespace1_, namespace3_}; - DocHitInfoIteratorFilter filtered_iterator(std::move(original_iterator), - document_store_.get(), - schema_store_.get(), options_); + DocHitInfoIteratorFilter filtered_iterator( + std::move(original_iterator), document_store_.get(), schema_store_.get(), + options_, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(GetDocumentIds(&filtered_iterator), ElementsAre(document_id1, document_id2, document_id4)); @@ -463,9 +464,9 @@ TEST_F(DocHitInfoIteratorSchemaTypeFilterTest, EmptyOriginalIterator) { std::make_unique<DocHitInfoIteratorDummy>(); options_.schema_types = std::vector<std::string_view>{}; - DocHitInfoIteratorFilter filtered_iterator(std::move(original_iterator_empty), - document_store_.get(), - schema_store_.get(), options_); + DocHitInfoIteratorFilter filtered_iterator( + std::move(original_iterator_empty), document_store_.get(), + schema_store_.get(), options_, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(GetDocumentIds(&filtered_iterator), IsEmpty()); } @@ -482,9 +483,9 @@ TEST_F(DocHitInfoIteratorSchemaTypeFilterTest, options_.schema_types = std::vector<std::string_view>{"nonexistent_schema_type"}; - DocHitInfoIteratorFilter filtered_iterator(std::move(original_iterator), - document_store_.get(), - schema_store_.get(), options_); + DocHitInfoIteratorFilter filtered_iterator( + std::move(original_iterator), document_store_.get(), schema_store_.get(), + options_, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(GetDocumentIds(&filtered_iterator), IsEmpty()); } @@ -499,9 +500,9 @@ TEST_F(DocHitInfoIteratorSchemaTypeFilterTest, NoSchemaTypesReturnsAll) { std::make_unique<DocHitInfoIteratorDummy>(doc_hit_infos); options_.schema_types = std::vector<std::string_view>{}; - DocHitInfoIteratorFilter filtered_iterator(std::move(original_iterator), - document_store_.get(), - schema_store_.get(), options_); + DocHitInfoIteratorFilter filtered_iterator( + std::move(original_iterator), document_store_.get(), schema_store_.get(), + options_, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(GetDocumentIds(&filtered_iterator), ElementsAre(document_id1)); } @@ -520,9 +521,9 @@ TEST_F(DocHitInfoIteratorSchemaTypeFilterTest, std::make_unique<DocHitInfoIteratorDummy>(doc_hit_infos); options_.schema_types = std::vector<std::string_view>{kSchema1}; - DocHitInfoIteratorFilter filtered_iterator(std::move(original_iterator), - document_store_.get(), - schema_store_.get(), options_); + DocHitInfoIteratorFilter filtered_iterator( + std::move(original_iterator), document_store_.get(), schema_store_.get(), + options_, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(GetDocumentIds(&filtered_iterator), ElementsAre(document_id1)); } @@ -543,9 +544,9 @@ TEST_F(DocHitInfoIteratorSchemaTypeFilterTest, FilterForMultipleSchemaTypesOk) { std::make_unique<DocHitInfoIteratorDummy>(doc_hit_infos); options_.schema_types = std::vector<std::string_view>{kSchema2, kSchema3}; - DocHitInfoIteratorFilter filtered_iterator(std::move(original_iterator), - document_store_.get(), - schema_store_.get(), options_); + DocHitInfoIteratorFilter filtered_iterator( + std::move(original_iterator), document_store_.get(), schema_store_.get(), + options_, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(GetDocumentIds(&filtered_iterator), ElementsAre(document_id2, document_id3)); @@ -582,18 +583,18 @@ TEST_F(DocHitInfoIteratorSchemaTypeFilterTest, std::unique_ptr<DocHitInfoIterator> original_iterator = std::make_unique<DocHitInfoIteratorDummy>(doc_hit_infos); options_.schema_types = {"person"}; - DocHitInfoIteratorFilter filtered_iterator_1(std::move(original_iterator), - document_store_.get(), - schema_store_.get(), options_); + DocHitInfoIteratorFilter filtered_iterator_1( + std::move(original_iterator), document_store_.get(), schema_store_.get(), + options_, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(GetDocumentIds(&filtered_iterator_1), ElementsAre(person_document_id, artist_document_id)); // Filters for the "artist" type should not include the "person" type. original_iterator = std::make_unique<DocHitInfoIteratorDummy>(doc_hit_infos); options_.schema_types = {"artist"}; - DocHitInfoIteratorFilter filtered_iterator_2(std::move(original_iterator), - document_store_.get(), - schema_store_.get(), options_); + DocHitInfoIteratorFilter filtered_iterator_2( + std::move(original_iterator), document_store_.get(), schema_store_.get(), + options_, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(GetDocumentIds(&filtered_iterator_2), ElementsAre(artist_document_id)); } @@ -631,27 +632,27 @@ TEST_F(DocHitInfoIteratorSchemaTypeFilterTest, std::unique_ptr<DocHitInfoIterator> original_iterator = std::make_unique<DocHitInfoIteratorDummy>(doc_hit_infos); options_.schema_types = std::vector<std::string_view>{"email"}; - DocHitInfoIteratorFilter filtered_iterator_1(std::move(original_iterator), - document_store_.get(), - schema_store_.get(), options_); + DocHitInfoIteratorFilter filtered_iterator_1( + std::move(original_iterator), document_store_.get(), schema_store_.get(), + options_, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(GetDocumentIds(&filtered_iterator_1), ElementsAre(email_document_id, email_message_document_id)); // Filters for the "message" type should also include the "emailMessage" type. original_iterator = std::make_unique<DocHitInfoIteratorDummy>(doc_hit_infos); options_.schema_types = std::vector<std::string_view>{"message"}; - DocHitInfoIteratorFilter filtered_iterator_2(std::move(original_iterator), - document_store_.get(), - schema_store_.get(), options_); + DocHitInfoIteratorFilter filtered_iterator_2( + std::move(original_iterator), document_store_.get(), schema_store_.get(), + options_, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(GetDocumentIds(&filtered_iterator_2), ElementsAre(message_document_id, email_message_document_id)); // Filters for a irrelevant type should return nothing. original_iterator = std::make_unique<DocHitInfoIteratorDummy>(doc_hit_infos); options_.schema_types = std::vector<std::string_view>{"person"}; - DocHitInfoIteratorFilter filtered_iterator_3(std::move(original_iterator), - document_store_.get(), - schema_store_.get(), options_); + DocHitInfoIteratorFilter filtered_iterator_3( + std::move(original_iterator), document_store_.get(), schema_store_.get(), + options_, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(GetDocumentIds(&filtered_iterator_3), IsEmpty()); } @@ -723,9 +724,9 @@ TEST_F(DocHitInfoIteratorExpirationFilterTest, TtlZeroIsntFilteredOut) { std::unique_ptr<DocHitInfoIterator> original_iterator = std::make_unique<DocHitInfoIteratorDummy>(doc_hit_infos); - DocHitInfoIteratorFilter filtered_iterator(std::move(original_iterator), - document_store.get(), - schema_store_.get(), options_); + DocHitInfoIteratorFilter filtered_iterator( + std::move(original_iterator), document_store.get(), schema_store_.get(), + options_, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(GetDocumentIds(&filtered_iterator), ElementsAre(document_id1)); } @@ -755,9 +756,9 @@ TEST_F(DocHitInfoIteratorExpirationFilterTest, BeforeTtlNotFilteredOut) { std::unique_ptr<DocHitInfoIterator> original_iterator = std::make_unique<DocHitInfoIteratorDummy>(doc_hit_infos); - DocHitInfoIteratorFilter filtered_iterator(std::move(original_iterator), - document_store.get(), - schema_store_.get(), options_); + DocHitInfoIteratorFilter filtered_iterator( + std::move(original_iterator), document_store.get(), schema_store_.get(), + options_, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(GetDocumentIds(&filtered_iterator), ElementsAre(document_id1)); } @@ -787,9 +788,9 @@ TEST_F(DocHitInfoIteratorExpirationFilterTest, EqualTtlFilteredOut) { std::unique_ptr<DocHitInfoIterator> original_iterator = std::make_unique<DocHitInfoIteratorDummy>(doc_hit_infos); - DocHitInfoIteratorFilter filtered_iterator(std::move(original_iterator), - document_store.get(), - schema_store_.get(), options_); + DocHitInfoIteratorFilter filtered_iterator( + std::move(original_iterator), document_store.get(), schema_store_.get(), + options_, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(GetDocumentIds(&filtered_iterator), IsEmpty()); } @@ -820,9 +821,9 @@ TEST_F(DocHitInfoIteratorExpirationFilterTest, PastTtlFilteredOut) { std::unique_ptr<DocHitInfoIterator> original_iterator = std::make_unique<DocHitInfoIteratorDummy>(doc_hit_infos); - DocHitInfoIteratorFilter filtered_iterator(std::move(original_iterator), - document_store.get(), - schema_store_.get(), options_); + DocHitInfoIteratorFilter filtered_iterator( + std::move(original_iterator), document_store.get(), schema_store_.get(), + options_, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(GetDocumentIds(&filtered_iterator), IsEmpty()); } @@ -937,7 +938,8 @@ TEST_F(DocHitInfoIteratorFilterTest, CombineAllFiltersOk) { // Deletes document2, causing it to be filtered out ICING_ASSERT_OK( document_store->Delete(document2_namespace1_schema1_.namespace_(), - document2_namespace1_schema1_.uri())); + document2_namespace1_schema1_.uri(), + fake_clock_.GetSystemTimeMilliseconds())); std::vector<DocHitInfo> doc_hit_infos = { DocHitInfo(document_id1), DocHitInfo(document_id2), @@ -955,9 +957,9 @@ TEST_F(DocHitInfoIteratorFilterTest, CombineAllFiltersOk) { // Filters out document4 by schema type options.schema_types = std::vector<std::string_view>{schema1_}; - DocHitInfoIteratorFilter filtered_iterator(std::move(original_iterator), - document_store.get(), - schema_store_.get(), options); + DocHitInfoIteratorFilter filtered_iterator( + std::move(original_iterator), document_store.get(), schema_store_.get(), + options, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(GetDocumentIds(&filtered_iterator), ElementsAre(document_id1)); } @@ -988,9 +990,9 @@ TEST_F(DocHitInfoIteratorFilterTest, SectionIdMasksArePopulatedCorrectly) { std::make_unique<DocHitInfoIteratorDummy>(doc_hit_infos); DocHitInfoIteratorFilter::Options options; - DocHitInfoIteratorFilter filtered_iterator(std::move(original_iterator), - document_store_.get(), - schema_store_.get(), options); + DocHitInfoIteratorFilter filtered_iterator( + std::move(original_iterator), document_store_.get(), schema_store_.get(), + options, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(GetDocHitInfos(&filtered_iterator), ElementsAre(EqualsDocHitInfo(document_id1, section_ids1), @@ -1003,9 +1005,9 @@ TEST_F(DocHitInfoIteratorFilterTest, GetNumBlocksInspected) { original_iterator->SetNumBlocksInspected(5); DocHitInfoIteratorFilter::Options options; - DocHitInfoIteratorFilter filtered_iterator(std::move(original_iterator), - document_store_.get(), - schema_store_.get(), options); + DocHitInfoIteratorFilter filtered_iterator( + std::move(original_iterator), document_store_.get(), schema_store_.get(), + options, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(filtered_iterator.GetNumBlocksInspected(), Eq(5)); } @@ -1015,9 +1017,9 @@ TEST_F(DocHitInfoIteratorFilterTest, GetNumLeafAdvanceCalls) { original_iterator->SetNumLeafAdvanceCalls(6); DocHitInfoIteratorFilter::Options options; - DocHitInfoIteratorFilter filtered_iterator(std::move(original_iterator), - document_store_.get(), - schema_store_.get(), options); + DocHitInfoIteratorFilter filtered_iterator( + std::move(original_iterator), document_store_.get(), schema_store_.get(), + options, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(filtered_iterator.GetNumLeafAdvanceCalls(), Eq(6)); } @@ -1055,9 +1057,9 @@ TEST_F(DocHitInfoIteratorFilterTest, TrimFilterIterator) { DocHitInfoIteratorFilter::Options options; // Filters out document3 by namespace options.namespaces = std::vector<std::string_view>{namespace1_}; - DocHitInfoIteratorFilter filtered_iterator(std::move(original_iterator), - document_store_.get(), - schema_store_.get(), options); + DocHitInfoIteratorFilter filtered_iterator( + std::move(original_iterator), document_store_.get(), schema_store_.get(), + options, fake_clock_.GetSystemTimeMilliseconds()); // The trimmed tree. // Filter diff --git a/icing/index/iterator/doc-hit-info-iterator-property-in-schema.cc b/icing/index/iterator/doc-hit-info-iterator-property-in-schema.cc index 5f260a8..05778b0 100644 --- a/icing/index/iterator/doc-hit-info-iterator-property-in-schema.cc +++ b/icing/index/iterator/doc-hit-info-iterator-property-in-schema.cc @@ -36,11 +36,12 @@ namespace lib { DocHitInfoIteratorPropertyInSchema::DocHitInfoIteratorPropertyInSchema( std::unique_ptr<DocHitInfoIterator> delegate, const DocumentStore* document_store, const SchemaStore* schema_store, - std::set<std::string> target_sections) + std::set<std::string> target_sections, int64_t current_time_ms) : delegate_(std::move(delegate)), document_store_(*document_store), schema_store_(*schema_store), - target_properties_(std::move(target_sections)) {} + target_properties_(std::move(target_sections)), + current_time_ms_(current_time_ms) {} libtextclassifier3::Status DocHitInfoIteratorPropertyInSchema::Advance() { doc_hit_info_ = DocHitInfo(kInvalidDocumentId); @@ -51,8 +52,8 @@ libtextclassifier3::Status DocHitInfoIteratorPropertyInSchema::Advance() { std::unordered_map<SchemaTypeId, bool> property_defined_types; while (delegate_->Advance().ok()) { DocumentId document_id = delegate_->doc_hit_info().document_id(); - auto data_optional = - document_store_.GetAliveDocumentFilterData(document_id); + auto data_optional = document_store_.GetAliveDocumentFilterData( + document_id, current_time_ms_); if (!data_optional) { // Ran into some error retrieving information on this hit, skip continue; diff --git a/icing/index/iterator/doc-hit-info-iterator-property-in-schema.h b/icing/index/iterator/doc-hit-info-iterator-property-in-schema.h index 35b87e1..730c497 100644 --- a/icing/index/iterator/doc-hit-info-iterator-property-in-schema.h +++ b/icing/index/iterator/doc-hit-info-iterator-property-in-schema.h @@ -39,7 +39,7 @@ class DocHitInfoIteratorPropertyInSchema : public DocHitInfoIterator { explicit DocHitInfoIteratorPropertyInSchema( std::unique_ptr<DocHitInfoIterator> delegate, const DocumentStore* document_store, const SchemaStore* schema_store, - std::set<std::string> target_sections); + std::set<std::string> target_sections, int64_t current_time_ms); libtextclassifier3::Status Advance() override; @@ -68,6 +68,7 @@ class DocHitInfoIteratorPropertyInSchema : public DocHitInfoIterator { const SchemaStore& schema_store_; std::set<std::string> target_properties_; + int64_t current_time_ms_; }; } // namespace lib diff --git a/icing/index/iterator/doc-hit-info-iterator-property-in-schema_test.cc b/icing/index/iterator/doc-hit-info-iterator-property-in-schema_test.cc index 9bffeeb..df5ddf5 100644 --- a/icing/index/iterator/doc-hit-info-iterator-property-in-schema_test.cc +++ b/icing/index/iterator/doc-hit-info-iterator-property-in-schema_test.cc @@ -137,7 +137,8 @@ TEST_F(DocHitInfoIteratorPropertyInSchemaTest, DocHitInfoIteratorPropertyInSchema property_defined_iterator( std::move(original_iterator), document_store_.get(), schema_store_.get(), - /*target_target_sections=*/{indexed_section_0}); + /*target_target_sections=*/{indexed_section_0}, + fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(GetDocumentIds(&property_defined_iterator), ElementsAre(document_id)); @@ -156,7 +157,8 @@ TEST_F(DocHitInfoIteratorPropertyInSchemaTest, DocHitInfoIteratorPropertyInSchema property_defined_iterator( std::move(original_iterator), document_store_.get(), schema_store_.get(), - /*target_target_sections=*/{unindexed_section_1}); + /*target_target_sections=*/{unindexed_section_1}, + fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(GetDocumentIds(&property_defined_iterator), ElementsAre(document_id)); @@ -172,7 +174,8 @@ TEST_F(DocHitInfoIteratorPropertyInSchemaTest, NoMatchWithUndefinedProperty) { DocHitInfoIteratorPropertyInSchema property_defined_iterator( std::move(original_iterator), document_store_.get(), schema_store_.get(), - /*target_target_sections=*/{not_defined_section_2}); + /*target_target_sections=*/{not_defined_section_2}, + fake_clock_.GetSystemTimeMilliseconds()); EXPECT_FALSE(property_defined_iterator.Advance().ok()); } @@ -200,7 +203,8 @@ TEST_F(DocHitInfoIteratorPropertyInSchemaTest, DocHitInfoIteratorPropertyInSchema property_defined_iterator( std::move(original_iterator), document_store_.get(), schema_store_.get(), - /*target_target_sections=*/{indexed_section_0}); + /*target_target_sections=*/{indexed_section_0}, + fake_clock_.GetSystemTimeMilliseconds()); std::vector<TermMatchInfo> matched_terms_stats; property_defined_iterator.PopulateMatchedTermsStats(&matched_terms_stats); @@ -232,7 +236,8 @@ TEST_F(DocHitInfoIteratorPropertyInSchemaTest, DocHitInfoIteratorPropertyInSchema property_defined_iterator( std::move(original_iterator), document_store_.get(), schema_store_.get(), - /*target_target_sections=*/{indexed_section_0}); + /*target_target_sections=*/{indexed_section_0}, + fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(std::move(property_defined_iterator).TrimRightMostNode(), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); @@ -249,7 +254,8 @@ TEST_F(DocHitInfoIteratorPropertyInSchemaTest, DocHitInfoIteratorPropertyInSchema property_defined_iterator( std::move(original_iterator), document_store_.get(), schema_store_.get(), - /*target_target_sections=*/{unindexed_section_1}); + /*target_target_sections=*/{unindexed_section_1}, + fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(GetDocumentIds(&property_defined_iterator), ElementsAre(document_id2, document_id1)); diff --git a/icing/index/iterator/doc-hit-info-iterator-section-restrict.cc b/icing/index/iterator/doc-hit-info-iterator-section-restrict.cc index d60e68e..227a185 100644 --- a/icing/index/iterator/doc-hit-info-iterator-section-restrict.cc +++ b/icing/index/iterator/doc-hit-info-iterator-section-restrict.cc @@ -38,11 +38,12 @@ namespace lib { DocHitInfoIteratorSectionRestrict::DocHitInfoIteratorSectionRestrict( std::unique_ptr<DocHitInfoIterator> delegate, const DocumentStore* document_store, const SchemaStore* schema_store, - std::set<std::string> target_sections) + std::set<std::string> target_sections, int64_t current_time_ms) : delegate_(std::move(delegate)), document_store_(*document_store), schema_store_(*schema_store), - target_sections_(std::move(target_sections)) {} + target_sections_(std::move(target_sections)), + current_time_ms_(current_time_ms) {} libtextclassifier3::Status DocHitInfoIteratorSectionRestrict::Advance() { doc_hit_info_ = DocHitInfo(kInvalidDocumentId); @@ -53,8 +54,8 @@ libtextclassifier3::Status DocHitInfoIteratorSectionRestrict::Advance() { SectionIdMask section_id_mask = delegate_->doc_hit_info().hit_section_ids_mask(); - auto data_optional = - document_store_.GetAliveDocumentFilterData(document_id); + auto data_optional = document_store_.GetAliveDocumentFilterData( + document_id, current_time_ms_); if (!data_optional) { // Ran into some error retrieving information on this hit, skip continue; @@ -112,7 +113,7 @@ DocHitInfoIteratorSectionRestrict::TrimRightMostNode() && { trimmed_delegate.iterator_ = std::make_unique<DocHitInfoIteratorSectionRestrict>( std::move(trimmed_delegate.iterator_), &document_store_, - &schema_store_, std::move(target_sections_)); + &schema_store_, std::move(target_sections_), current_time_ms_); return std::move(trimmed_delegate); } diff --git a/icing/index/iterator/doc-hit-info-iterator-section-restrict.h b/icing/index/iterator/doc-hit-info-iterator-section-restrict.h index 92971a6..58dd120 100644 --- a/icing/index/iterator/doc-hit-info-iterator-section-restrict.h +++ b/icing/index/iterator/doc-hit-info-iterator-section-restrict.h @@ -42,7 +42,7 @@ class DocHitInfoIteratorSectionRestrict : public DocHitInfoIterator { explicit DocHitInfoIteratorSectionRestrict( std::unique_ptr<DocHitInfoIterator> delegate, const DocumentStore* document_store, const SchemaStore* schema_store, - std::set<std::string> target_sections); + std::set<std::string> target_sections, int64_t current_time_ms); libtextclassifier3::Status Advance() override; @@ -77,6 +77,7 @@ class DocHitInfoIteratorSectionRestrict : public DocHitInfoIterator { const SchemaStore& schema_store_; std::set<std::string> target_sections_; + int64_t current_time_ms_; }; } // namespace lib diff --git a/icing/index/iterator/doc-hit-info-iterator-section-restrict_test.cc b/icing/index/iterator/doc-hit-info-iterator-section-restrict_test.cc index 78f4d34..c765e6d 100644 --- a/icing/index/iterator/doc-hit-info-iterator-section-restrict_test.cc +++ b/icing/index/iterator/doc-hit-info-iterator-section-restrict_test.cc @@ -156,7 +156,8 @@ TEST_F(DocHitInfoIteratorSectionRestrictTest, // get a result. DocHitInfoIteratorSectionRestrict section_restrict_iterator( std::move(original_iterator), document_store_.get(), schema_store_.get(), - /*target_sections=*/{indexed_section_0}); + /*target_sections=*/{indexed_section_0}, + fake_clock_.GetSystemTimeMilliseconds()); std::vector<TermMatchInfo> matched_terms_stats; section_restrict_iterator.PopulateMatchedTermsStats(&matched_terms_stats); @@ -184,7 +185,8 @@ TEST_F(DocHitInfoIteratorSectionRestrictTest, EmptyOriginalIterator) { DocHitInfoIteratorSectionRestrict filtered_iterator( std::move(original_iterator_empty), document_store_.get(), - schema_store_.get(), /*target_sections=*/{}); + schema_store_.get(), /*target_sections=*/{}, + fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(GetDocumentIds(&filtered_iterator), IsEmpty()); std::vector<TermMatchInfo> matched_terms_stats; @@ -209,7 +211,8 @@ TEST_F(DocHitInfoIteratorSectionRestrictTest, IncludesHitWithMatchingSection) { // Filtering for the indexed section name should get a result DocHitInfoIteratorSectionRestrict section_restrict_iterator( std::move(original_iterator), document_store_.get(), schema_store_.get(), - /*target_sections=*/{indexed_section_0}); + /*target_sections=*/{indexed_section_0}, + fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(GetDocumentIds(§ion_restrict_iterator), ElementsAre(document_id)); @@ -234,7 +237,8 @@ TEST_F(DocHitInfoIteratorSectionRestrictTest, // Filter for both target_sections DocHitInfoIteratorSectionRestrict section_restrict_iterator( std::move(original_iterator), document_store_.get(), schema_store_.get(), - /*target_sections=*/{indexed_section_0, indexed_section_1}); + /*target_sections=*/{indexed_section_0, indexed_section_1}, + fake_clock_.GetSystemTimeMilliseconds()); ICING_ASSERT_OK(section_restrict_iterator.Advance()); std::vector<SectionId> expected_section_ids = {kIndexedSectionId0, @@ -264,7 +268,8 @@ TEST_F(DocHitInfoIteratorSectionRestrictTest, // Filter for both target_sections DocHitInfoIteratorSectionRestrict section_restrict_iterator( std::move(original_iterator), document_store_.get(), schema_store_.get(), - /*target_sections=*/{indexed_section_1}); + /*target_sections=*/{indexed_section_1}, + fake_clock_.GetSystemTimeMilliseconds()); ICING_ASSERT_OK(section_restrict_iterator.Advance()); std::vector<SectionId> expected_section_ids = {kIndexedSectionId1}; @@ -292,7 +297,8 @@ TEST_F(DocHitInfoIteratorSectionRestrictTest, // Filter for both target_sections DocHitInfoIteratorSectionRestrict section_restrict_iterator( std::move(original_iterator), document_store_.get(), schema_store_.get(), - /*target_sections=*/{indexed_section_0, indexed_section_1}); + /*target_sections=*/{indexed_section_0, indexed_section_1}, + fake_clock_.GetSystemTimeMilliseconds()); ICING_ASSERT_OK(section_restrict_iterator.Advance()); std::vector<SectionId> expected_section_ids = {kIndexedSectionId1}; @@ -312,7 +318,7 @@ TEST_F(DocHitInfoIteratorSectionRestrictTest, NoMatchingDocumentFilterData) { // Filtering for the indexed section name should get a result DocHitInfoIteratorSectionRestrict section_restrict_iterator( std::move(original_iterator), document_store_.get(), schema_store_.get(), - /*target_sections=*/{""}); + /*target_sections=*/{""}, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(GetDocumentIds(§ion_restrict_iterator), IsEmpty()); std::vector<TermMatchInfo> matched_terms_stats; @@ -338,7 +344,8 @@ TEST_F(DocHitInfoIteratorSectionRestrictTest, // Filtering for the indexed section name should get a result DocHitInfoIteratorSectionRestrict section_restrict_iterator( std::move(original_iterator), document_store_.get(), schema_store_.get(), - /*target_sections=*/{"some_section_name"}); + /*target_sections=*/{"some_section_name"}, + fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(GetDocumentIds(§ion_restrict_iterator), IsEmpty()); std::vector<TermMatchInfo> matched_terms_stats; @@ -362,7 +369,8 @@ TEST_F(DocHitInfoIteratorSectionRestrictTest, DocHitInfoIteratorSectionRestrict section_restrict_iterator( std::move(original_iterator), document_store_.get(), schema_store_.get(), - /*target_sections=*/{indexed_section_0}); + /*target_sections=*/{indexed_section_0}, + fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(GetDocumentIds(§ion_restrict_iterator), IsEmpty()); std::vector<TermMatchInfo> matched_terms_stats; @@ -389,7 +397,8 @@ TEST_F(DocHitInfoIteratorSectionRestrictTest, DocHitInfoIteratorSectionRestrict section_restrict_iterator( std::move(original_iterator), document_store_.get(), schema_store_.get(), - /*target_sections=*/{indexed_section_0}); + /*target_sections=*/{indexed_section_0}, + fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(GetDocumentIds(§ion_restrict_iterator), IsEmpty()); std::vector<TermMatchInfo> matched_terms_stats; @@ -403,7 +412,7 @@ TEST_F(DocHitInfoIteratorSectionRestrictTest, GetNumBlocksInspected) { DocHitInfoIteratorSectionRestrict section_restrict_iterator( std::move(original_iterator), document_store_.get(), schema_store_.get(), - /*target_sections=*/{""}); + /*target_sections=*/{""}, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(section_restrict_iterator.GetNumBlocksInspected(), Eq(5)); } @@ -414,7 +423,7 @@ TEST_F(DocHitInfoIteratorSectionRestrictTest, GetNumLeafAdvanceCalls) { DocHitInfoIteratorSectionRestrict section_restrict_iterator( std::move(original_iterator), document_store_.get(), schema_store_.get(), - /*target_sections=*/{""}); + /*target_sections=*/{""}, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(section_restrict_iterator.GetNumLeafAdvanceCalls(), Eq(6)); } @@ -457,7 +466,7 @@ TEST_F(DocHitInfoIteratorSectionRestrictTest, DocHitInfoIteratorSectionRestrict section_restrict_iterator( std::move(original_iterator), document_store_.get(), schema_store_.get(), - {indexed_section_0}); + {indexed_section_0}, fake_clock_.GetSystemTimeMilliseconds()); // The trimmed tree. // Restrict @@ -497,7 +506,7 @@ TEST_F(DocHitInfoIteratorSectionRestrictTest, TrimSectionRestrictIterator) { DocHitInfoIteratorSectionRestrict section_restrict_iterator( std::move(original_iterator), document_store_.get(), schema_store_.get(), - {indexed_section_0}); + {indexed_section_0}, fake_clock_.GetSystemTimeMilliseconds()); // The trimmed tree has null iterator but has target section. ICING_ASSERT_OK_AND_ASSIGN( diff --git a/icing/index/numeric/dummy-numeric-index.h b/icing/index/numeric/dummy-numeric-index.h index 7cfb102..2c077a2 100644 --- a/icing/index/numeric/dummy-numeric-index.h +++ b/icing/index/numeric/dummy-numeric-index.h @@ -71,7 +71,7 @@ class DummyNumericIndex : public NumericIndex<T> { libtextclassifier3::StatusOr<std::unique_ptr<DocHitInfoIterator>> GetIterator( std::string_view property_path, T key_lower, T key_upper, - const DocumentStore&, const SchemaStore&) const override; + const DocumentStore&, const SchemaStore&, int64_t) const override; libtextclassifier3::Status Optimize( const std::vector<DocumentId>& document_id_old_to_new, @@ -268,7 +268,7 @@ template <typename T> libtextclassifier3::StatusOr<std::unique_ptr<DocHitInfoIterator>> DummyNumericIndex<T>::GetIterator(std::string_view property_path, T key_lower, T key_upper, const DocumentStore&, - const SchemaStore&) const { + const SchemaStore&, int64_t) const { if (key_lower > key_upper) { return absl_ports::InvalidArgumentError( "key_lower should not be greater than key_upper"); diff --git a/icing/index/numeric/integer-index.cc b/icing/index/numeric/integer-index.cc index de00b85..5fa82a5 100644 --- a/icing/index/numeric/integer-index.cc +++ b/icing/index/numeric/integer-index.cc @@ -213,7 +213,8 @@ libtextclassifier3::StatusOr<std::unique_ptr<DocHitInfoIterator>> IntegerIndex::GetIterator(std::string_view property_path, int64_t key_lower, int64_t key_upper, const DocumentStore& document_store, - const SchemaStore& schema_store) const { + const SchemaStore& schema_store, + int64_t current_time_ms) const { std::string property_path_str(property_path); auto iter = property_to_storage_map_.find(property_path_str); if (iter != property_to_storage_map_.end()) { @@ -228,7 +229,7 @@ IntegerIndex::GetIterator(std::string_view property_path, int64_t key_lower, std::set<std::string> property_paths = {std::move(property_path_str)}; return std::make_unique<DocHitInfoIteratorSectionRestrict>( std::move(delegate), &document_store, &schema_store, - std::move(property_paths)); + std::move(property_paths), current_time_ms); } // Return an empty iterator. diff --git a/icing/index/numeric/integer-index.h b/icing/index/numeric/integer-index.h index 23b463f..30f9852 100644 --- a/icing/index/numeric/integer-index.h +++ b/icing/index/numeric/integer-index.h @@ -139,8 +139,8 @@ class IntegerIndex : public NumericIndex<int64_t> { // - Any IntegerIndexStorage errors libtextclassifier3::StatusOr<std::unique_ptr<DocHitInfoIterator>> GetIterator( std::string_view property_path, int64_t key_lower, int64_t key_upper, - const DocumentStore& document_store, - const SchemaStore& schema_store) const override; + const DocumentStore& document_store, const SchemaStore& schema_store, + int64_t current_time_ms) const override; // Reduces internal file sizes by reclaiming space and ids of deleted // documents. Integer index will convert all data (hits) to the new document diff --git a/icing/index/numeric/integer-index_test.cc b/icing/index/numeric/integer-index_test.cc index d3901cc..8a7acb9 100644 --- a/icing/index/numeric/integer-index_test.cc +++ b/icing/index/numeric/integer-index_test.cc @@ -170,7 +170,8 @@ class NumericIndexIntegerTest : public ::testing::Test { ICING_ASSIGN_OR_RETURN( std::unique_ptr<DocHitInfoIterator> iter, integer_index->GetIterator(property_path, key_lower, key_upper, - *doc_store_, *schema_store_)); + *doc_store_, *schema_store_, + clock_.GetSystemTimeMilliseconds())); std::vector<DocHitInfo> result; while (iter->Advance().ok()) { @@ -2028,8 +2029,10 @@ TEST_P(IntegerIndexTest, WildcardStorageWorksAfterOptimize) { Index(integer_index.get(), desired_property, /*document_id=*/20, typeb_desired_prop_id, /*keys=*/{2}); - ICING_ASSERT_OK(doc_store_->Delete(/*document_id=*/3)); - ICING_ASSERT_OK(doc_store_->Delete(/*document_id=*/5)); + ICING_ASSERT_OK(doc_store_->Delete(/*document_id=*/3, + clock_.GetSystemTimeMilliseconds())); + ICING_ASSERT_OK(doc_store_->Delete(/*document_id=*/5, + clock_.GetSystemTimeMilliseconds())); // Delete doc id = 3, 5, compress and keep the rest. ICING_ASSERT_OK_AND_ASSIGN(std::vector<DocumentId> document_id_old_to_new, CompactDocStore()); @@ -2272,12 +2275,18 @@ TEST_P(IntegerIndexTest, WildcardStorageAvailableIndicesAfterOptimize) { // Delete all the docs that had hits in otherProperty* and // undesiredProperty. - ICING_ASSERT_OK(doc_store_->Delete(/*document_id=*/0)); - ICING_ASSERT_OK(doc_store_->Delete(/*document_id=*/6)); - ICING_ASSERT_OK(doc_store_->Delete(/*document_id=*/7)); - ICING_ASSERT_OK(doc_store_->Delete(/*document_id=*/8)); - ICING_ASSERT_OK(doc_store_->Delete(/*document_id=*/9)); - ICING_ASSERT_OK(doc_store_->Delete(/*document_id=*/10)); + ICING_ASSERT_OK(doc_store_->Delete(/*document_id=*/0, + clock_.GetSystemTimeMilliseconds())); + ICING_ASSERT_OK(doc_store_->Delete(/*document_id=*/6, + clock_.GetSystemTimeMilliseconds())); + ICING_ASSERT_OK(doc_store_->Delete(/*document_id=*/7, + clock_.GetSystemTimeMilliseconds())); + ICING_ASSERT_OK(doc_store_->Delete(/*document_id=*/8, + clock_.GetSystemTimeMilliseconds())); + ICING_ASSERT_OK(doc_store_->Delete(/*document_id=*/9, + clock_.GetSystemTimeMilliseconds())); + ICING_ASSERT_OK(doc_store_->Delete(/*document_id=*/10, + clock_.GetSystemTimeMilliseconds())); // Delete doc id = 0, 6, 7, 8, 9, 10. Compress and keep the rest. ICING_ASSERT_OK_AND_ASSIGN(std::vector<DocumentId> document_id_old_to_new, CompactDocStore()); diff --git a/icing/index/numeric/numeric-index.h b/icing/index/numeric/numeric-index.h index 28640ca..24b81e7 100644 --- a/icing/index/numeric/numeric-index.h +++ b/icing/index/numeric/numeric-index.h @@ -130,7 +130,8 @@ class NumericIndex : public PersistentStorage { virtual libtextclassifier3::StatusOr<std::unique_ptr<DocHitInfoIterator>> GetIterator(std::string_view property_path, T key_lower, T key_upper, const DocumentStore& document_store, - const SchemaStore& schema_store) const = 0; + const SchemaStore& schema_store, + int64_t current_time_ms) const = 0; // Reduces internal file sizes by reclaiming space and ids of deleted // documents. Numeric index will convert all data (hits) to the new document diff --git a/icing/join/join-processor.cc b/icing/join/join-processor.cc index d68ec98..e27b1ea 100644 --- a/icing/join/join-processor.cc +++ b/icing/join/join-processor.cc @@ -119,7 +119,7 @@ libtextclassifier3::StatusOr<DocumentId> JoinProcessor::FetchReferencedQualifiedId( const DocumentId& document_id, const std::string& property_path) const { std::optional<DocumentFilterData> filter_data = - doc_store_->GetAliveDocumentFilterData(document_id); + doc_store_->GetAliveDocumentFilterData(document_id, current_time_ms_); if (!filter_data) { return kInvalidDocumentId; } diff --git a/icing/join/join-processor.h b/icing/join/join-processor.h index 497787f..347ce85 100644 --- a/icing/join/join-processor.h +++ b/icing/join/join-processor.h @@ -15,6 +15,7 @@ #ifndef ICING_JOIN_JOIN_PROCESSOR_H_ #define ICING_JOIN_JOIN_PROCESSOR_H_ +#include <cstdint> #include <string> #include <string_view> #include <vector> @@ -36,10 +37,12 @@ class JoinProcessor { explicit JoinProcessor( const DocumentStore* doc_store, const SchemaStore* schema_store, - const QualifiedIdTypeJoinableIndex* qualified_id_join_index) + const QualifiedIdTypeJoinableIndex* qualified_id_join_index, + int64_t current_time_ms) : doc_store_(doc_store), schema_store_(schema_store), - qualified_id_join_index_(qualified_id_join_index) {} + qualified_id_join_index_(qualified_id_join_index), + current_time_ms_(current_time_ms) {} // Get a JoinChildrenFetcher used to fetch all children documents by a parent // document id. @@ -77,6 +80,7 @@ class JoinProcessor { const SchemaStore* schema_store_; // Does not own. const QualifiedIdTypeJoinableIndex* qualified_id_join_index_; // Does not own. + int64_t current_time_ms_; }; } // namespace lib diff --git a/icing/join/join-processor_test.cc b/icing/join/join-processor_test.cc index 0d3e57c..95d1392 100644 --- a/icing/join/join-processor_test.cc +++ b/icing/join/join-processor_test.cc @@ -164,8 +164,9 @@ class JoinProcessorTest : public ::testing::Test { const JoinSpecProto& join_spec, std::vector<ScoredDocumentHit>&& parent_scored_document_hits, std::vector<ScoredDocumentHit>&& child_scored_document_hits) { - JoinProcessor join_processor(doc_store_.get(), schema_store_.get(), - qualified_id_join_index_.get()); + JoinProcessor join_processor( + doc_store_.get(), schema_store_.get(), qualified_id_join_index_.get(), + /*current_time_ms=*/fake_clock_.GetSystemTimeMilliseconds()); ICING_ASSIGN_OR_RETURN( JoinChildrenFetcher join_children_fetcher, join_processor.GetChildrenFetcher( diff --git a/icing/query/advanced_query_parser/query-visitor.cc b/icing/query/advanced_query_parser/query-visitor.cc index 664b072..d75a550 100644 --- a/icing/query/advanced_query_parser/query-visitor.cc +++ b/icing/query/advanced_query_parser/query-visitor.cc @@ -183,7 +183,7 @@ QueryVisitor::CreateTermIterator(const QueryTerm& query_term) { query_term_iterators_[query_term.term] = std::make_unique<DocHitInfoIteratorFilter>( std::move(term_iterator), &document_store_, &schema_store_, - filter_options_); + filter_options_, current_time_ms_); } } @@ -265,11 +265,11 @@ libtextclassifier3::StatusOr<PendingValue> QueryVisitor::SearchFunction( iterator = std::make_unique<DocHitInfoIteratorAllDocumentId>( document_store_.last_added_document_id()); } else { - QueryVisitor query_visitor(&index_, &numeric_index_, &document_store_, - &schema_store_, &normalizer_, &tokenizer_, - query->raw_term, filter_options_, match_type_, - needs_term_frequency_info_, - pending_property_restricts_, processing_not_); + QueryVisitor query_visitor( + &index_, &numeric_index_, &document_store_, &schema_store_, + &normalizer_, &tokenizer_, query->raw_term, filter_options_, + match_type_, needs_term_frequency_info_, pending_property_restricts_, + processing_not_, current_time_ms_); tree_root->Accept(&query_visitor); ICING_ASSIGN_OR_RETURN(query_result, std::move(query_visitor).ConsumeResults()); @@ -281,7 +281,8 @@ libtextclassifier3::StatusOr<PendingValue> QueryVisitor::SearchFunction( pending_property_restricts_.has_active_property_restricts()) { iterator = std::make_unique<DocHitInfoIteratorSectionRestrict>( std::move(iterator), &document_store_, &schema_store_, - pending_property_restricts_.active_property_restricts()); + pending_property_restricts_.active_property_restricts(), + current_time_ms_); pending_property_restricts_.PopRestricts(); } if (!processing_not_) { @@ -314,7 +315,7 @@ QueryVisitor::PropertyDefinedFunction(std::vector<PendingValue>&& args) { std::unique_ptr<DocHitInfoIterator> property_in_schema_iterator = std::make_unique<DocHitInfoIteratorPropertyInSchema>( std::move(all_docs_iterator), &document_store_, &schema_store_, - std::move(target_sections)); + std::move(target_sections), current_time_ms_); features_.insert(kListFilterQueryLanguageFeature); @@ -490,10 +491,10 @@ libtextclassifier3::Status QueryVisitor::ProcessNumericComparator( // 5. Create the iterator and push it onto pending_values_. ICING_ASSIGN_OR_RETURN(Int64Range range, GetInt64Range(node->operator_text(), int_value)); - ICING_ASSIGN_OR_RETURN( - std::unique_ptr<DocHitInfoIterator> iterator, - numeric_index_.GetIterator(text_value.term, range.low, range.high, - document_store_, schema_store_)); + ICING_ASSIGN_OR_RETURN(std::unique_ptr<DocHitInfoIterator> iterator, + numeric_index_.GetIterator( + text_value.term, range.low, range.high, + document_store_, schema_store_, current_time_ms_)); features_.insert(kNumericSearchFeature); pending_values_.push(PendingValue(std::move(iterator))); @@ -648,7 +649,7 @@ libtextclassifier3::Status QueryVisitor::ProcessHasOperator( pending_values_.push( PendingValue(std::make_unique<DocHitInfoIteratorSectionRestrict>( std::move(delegate), &document_store_, &schema_store_, - std::move(property_restricts)))); + std::move(property_restricts), current_time_ms_))); return libtextclassifier3::Status::OK; } diff --git a/icing/query/advanced_query_parser/query-visitor.h b/icing/query/advanced_query_parser/query-visitor.h index c5598dd..38864f8 100644 --- a/icing/query/advanced_query_parser/query-visitor.h +++ b/icing/query/advanced_query_parser/query-visitor.h @@ -45,18 +45,21 @@ namespace lib { // the parser. class QueryVisitor : public AbstractSyntaxTreeVisitor { public: - explicit QueryVisitor( - Index* index, const NumericIndex<int64_t>* numeric_index, - const DocumentStore* document_store, const SchemaStore* schema_store, - const Normalizer* normalizer, const Tokenizer* tokenizer, - std::string_view raw_query_text, - DocHitInfoIteratorFilter::Options filter_options, - TermMatchType::Code match_type, bool needs_term_frequency_info) + explicit QueryVisitor(Index* index, + const NumericIndex<int64_t>* numeric_index, + const DocumentStore* document_store, + const SchemaStore* schema_store, + const Normalizer* normalizer, + const Tokenizer* tokenizer, + std::string_view raw_query_text, + DocHitInfoIteratorFilter::Options filter_options, + TermMatchType::Code match_type, + bool needs_term_frequency_info, int64_t current_time_ms) : QueryVisitor(index, numeric_index, document_store, schema_store, normalizer, tokenizer, raw_query_text, filter_options, match_type, needs_term_frequency_info, PendingPropertyRestricts(), - /*processing_not=*/false) {} + /*processing_not=*/false, current_time_ms) {} void VisitFunctionName(const FunctionNameNode* node) override; void VisitString(const StringNode* node) override; @@ -108,7 +111,8 @@ class QueryVisitor : public AbstractSyntaxTreeVisitor { std::string_view raw_query_text, DocHitInfoIteratorFilter::Options filter_options, TermMatchType::Code match_type, bool needs_term_frequency_info, - PendingPropertyRestricts pending_property_restricts, bool processing_not) + PendingPropertyRestricts pending_property_restricts, bool processing_not, + int64_t current_time_ms) : index_(*index), numeric_index_(*numeric_index), document_store_(*document_store), @@ -121,7 +125,8 @@ class QueryVisitor : public AbstractSyntaxTreeVisitor { needs_term_frequency_info_(needs_term_frequency_info), pending_property_restricts_(std::move(pending_property_restricts)), processing_not_(processing_not), - expecting_numeric_arg_(false) { + expecting_numeric_arg_(false), + current_time_ms_(current_time_ms) { RegisterFunctions(); } @@ -302,6 +307,8 @@ class QueryVisitor : public AbstractSyntaxTreeVisitor { // Whether we are in the midst of processing a subtree that is expected to // resolve to a numeric argument. bool expecting_numeric_arg_; + + int64_t current_time_ms_; }; } // namespace lib diff --git a/icing/query/advanced_query_parser/query-visitor_test.cc b/icing/query/advanced_query_parser/query-visitor_test.cc index 92eb3e7..0d7ba6d 100644 --- a/icing/query/advanced_query_parser/query-visitor_test.cc +++ b/icing/query/advanced_query_parser/query-visitor_test.cc @@ -233,7 +233,7 @@ TEST_P(QueryVisitorTest, SimpleLessThan) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -276,7 +276,7 @@ TEST_P(QueryVisitorTest, SimpleLessThanEq) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -319,7 +319,7 @@ TEST_P(QueryVisitorTest, SimpleEqual) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -362,7 +362,7 @@ TEST_P(QueryVisitorTest, SimpleGreaterThanEq) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -405,7 +405,7 @@ TEST_P(QueryVisitorTest, SimpleGreaterThan) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -449,7 +449,7 @@ TEST_P(QueryVisitorTest, IntMinLessThanEqual) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -493,7 +493,7 @@ TEST_P(QueryVisitorTest, IntMaxGreaterThanEqual) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -538,7 +538,7 @@ TEST_P(QueryVisitorTest, NestedPropertyLessThan) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -566,7 +566,7 @@ TEST_P(QueryVisitorTest, IntParsingError) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); EXPECT_THAT(std::move(query_visitor).ConsumeResults(), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); @@ -580,7 +580,7 @@ TEST_P(QueryVisitorTest, NotEqualsUnsupported) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); EXPECT_THAT(std::move(query_visitor).ConsumeResults(), StatusIs(libtextclassifier3::StatusCode::UNIMPLEMENTED)); @@ -628,7 +628,7 @@ TEST_P(QueryVisitorTest, LessThanTooManyOperandsInvalid) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); EXPECT_THAT(std::move(query_visitor).ConsumeResults(), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); @@ -655,7 +655,7 @@ TEST_P(QueryVisitorTest, LessThanTooFewOperandsInvalid) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); EXPECT_THAT(std::move(query_visitor).ConsumeResults(), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); @@ -686,7 +686,7 @@ TEST_P(QueryVisitorTest, LessThanNonExistentPropertyNotFound) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -708,7 +708,7 @@ TEST_P(QueryVisitorTest, NeverVisitedReturnsInvalid) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), "", DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(std::move(query_visitor).ConsumeResults(), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); } @@ -737,7 +737,7 @@ TEST_P(QueryVisitorTest, IntMinLessThanInvalid) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); EXPECT_THAT(std::move(query_visitor).ConsumeResults(), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); @@ -767,7 +767,7 @@ TEST_P(QueryVisitorTest, IntMaxGreaterThanInvalid) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); EXPECT_THAT(std::move(query_visitor).ConsumeResults(), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); @@ -782,7 +782,7 @@ TEST_P(QueryVisitorTest, NumericComparisonPropertyStringIsInvalid) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); EXPECT_THAT(std::move(query_visitor).ConsumeResults(), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); @@ -846,7 +846,7 @@ TEST_P(QueryVisitorTest, NumericComparatorDoesntAffectLaterTerms) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -889,7 +889,7 @@ TEST_P(QueryVisitorTest, SingleTermTermFrequencyEnabled) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -941,7 +941,7 @@ TEST_P(QueryVisitorTest, SingleTermTermFrequencyDisabled) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/false); + /*needs_term_frequency_info_=*/false, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -993,7 +993,7 @@ TEST_P(QueryVisitorTest, SingleTermPrefix) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_EXACT, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -1009,7 +1009,7 @@ TEST_P(QueryVisitorTest, SingleTermPrefix) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_EXACT, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor_two); ICING_ASSERT_OK_AND_ASSIGN(query_results, std::move(query_visitor_two).ConsumeResults()); @@ -1029,7 +1029,7 @@ TEST_P(QueryVisitorTest, PrefixOperatorAfterPropertyReturnsInvalid) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); EXPECT_THAT(std::move(query_visitor).ConsumeResults(), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); @@ -1043,7 +1043,7 @@ TEST_P(QueryVisitorTest, PrefixOperatorAfterNumericValueReturnsInvalid) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); EXPECT_THAT(std::move(query_visitor).ConsumeResults(), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); @@ -1057,7 +1057,7 @@ TEST_P(QueryVisitorTest, PrefixOperatorAfterPropertyRestrictReturnsInvalid) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); EXPECT_THAT(std::move(query_visitor).ConsumeResults(), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); @@ -1095,7 +1095,7 @@ TEST_P(QueryVisitorTest, SegmentationWithPrefix) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_EXACT, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -1118,7 +1118,7 @@ TEST_P(QueryVisitorTest, SegmentationWithPrefix) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_EXACT, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor_two); ICING_ASSERT_OK_AND_ASSIGN(query_results, std::move(query_visitor_two).ConsumeResults()); @@ -1155,7 +1155,7 @@ TEST_P(QueryVisitorTest, SingleVerbatimTerm) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -1202,7 +1202,7 @@ TEST_P(QueryVisitorTest, SingleVerbatimTermPrefix) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_EXACT, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -1255,7 +1255,7 @@ TEST_P(QueryVisitorTest, VerbatimTermEscapingQuote) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -1307,7 +1307,7 @@ TEST_P(QueryVisitorTest, VerbatimTermEscapingEscape) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -1361,7 +1361,7 @@ TEST_P(QueryVisitorTest, VerbatimTermEscapingNonSpecialChar) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -1388,7 +1388,7 @@ TEST_P(QueryVisitorTest, VerbatimTermEscapingNonSpecialChar) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor_two); ICING_ASSERT_OK_AND_ASSIGN(query_results, std::move(query_visitor_two).ConsumeResults()); @@ -1443,7 +1443,7 @@ TEST_P(QueryVisitorTest, VerbatimTermNewLine) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -1469,7 +1469,7 @@ TEST_P(QueryVisitorTest, VerbatimTermNewLine) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor_two); ICING_ASSERT_OK_AND_ASSIGN(query_results, std::move(query_visitor_two).ConsumeResults()); @@ -1518,7 +1518,7 @@ TEST_P(QueryVisitorTest, VerbatimTermEscapingComplex) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -1577,7 +1577,7 @@ TEST_P(QueryVisitorTest, SingleMinusTerm) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -1631,7 +1631,7 @@ TEST_P(QueryVisitorTest, SingleNotTerm) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -1686,7 +1686,7 @@ TEST_P(QueryVisitorTest, NestedNotTerms) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -1755,7 +1755,7 @@ TEST_P(QueryVisitorTest, DeeplyNestedNotTerms) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -1794,7 +1794,7 @@ TEST_P(QueryVisitorTest, ImplicitAndTerms) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -1837,7 +1837,7 @@ TEST_P(QueryVisitorTest, ExplicitAndTerms) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -1880,7 +1880,7 @@ TEST_P(QueryVisitorTest, OrTerms) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -1925,7 +1925,7 @@ TEST_P(QueryVisitorTest, AndOrTermPrecedence) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -1950,7 +1950,7 @@ TEST_P(QueryVisitorTest, AndOrTermPrecedence) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor_two); ICING_ASSERT_OK_AND_ASSIGN(query_results, std::move(query_visitor_two).ConsumeResults()); @@ -1974,7 +1974,7 @@ TEST_P(QueryVisitorTest, AndOrTermPrecedence) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor_three); ICING_ASSERT_OK_AND_ASSIGN(query_results, std::move(query_visitor_three).ConsumeResults()); @@ -2036,7 +2036,7 @@ TEST_P(QueryVisitorTest, AndOrNotPrecedence) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -2056,7 +2056,7 @@ TEST_P(QueryVisitorTest, AndOrNotPrecedence) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor_two); ICING_ASSERT_OK_AND_ASSIGN(query_results, std::move(query_visitor_two).ConsumeResults()); @@ -2121,7 +2121,7 @@ TEST_P(QueryVisitorTest, PropertyFilter) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -2197,7 +2197,7 @@ TEST_F(QueryVisitorTest, MultiPropertyFilter) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -2240,7 +2240,7 @@ TEST_P(QueryVisitorTest, PropertyFilterStringIsInvalid) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); EXPECT_THAT(std::move(query_visitor).ConsumeResults(), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); @@ -2296,7 +2296,7 @@ TEST_P(QueryVisitorTest, PropertyFilterNonNormalized) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -2367,7 +2367,7 @@ TEST_P(QueryVisitorTest, PropertyFilterWithGrouping) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -2434,7 +2434,7 @@ TEST_P(QueryVisitorTest, ValidNestedPropertyFilter) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -2455,7 +2455,7 @@ TEST_P(QueryVisitorTest, ValidNestedPropertyFilter) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor_two); ICING_ASSERT_OK_AND_ASSIGN(query_results, std::move(query_visitor_two).ConsumeResults()); @@ -2521,7 +2521,7 @@ TEST_P(QueryVisitorTest, InvalidNestedPropertyFilter) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -2542,7 +2542,7 @@ TEST_P(QueryVisitorTest, InvalidNestedPropertyFilter) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor_two); ICING_ASSERT_OK_AND_ASSIGN(query_results, std::move(query_visitor_two).ConsumeResults()); @@ -2608,7 +2608,7 @@ TEST_P(QueryVisitorTest, NotWithPropertyFilter) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -2629,7 +2629,7 @@ TEST_P(QueryVisitorTest, NotWithPropertyFilter) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor_two); ICING_ASSERT_OK_AND_ASSIGN(query_results, std::move(query_visitor_two).ConsumeResults()); @@ -2696,7 +2696,7 @@ TEST_P(QueryVisitorTest, PropertyFilterWithNot) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -2720,7 +2720,7 @@ TEST_P(QueryVisitorTest, PropertyFilterWithNot) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor_two); ICING_ASSERT_OK_AND_ASSIGN(query_results, std::move(query_visitor_two).ConsumeResults()); @@ -2802,7 +2802,7 @@ TEST_P(QueryVisitorTest, SegmentationTest) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -2922,7 +2922,7 @@ TEST_P(QueryVisitorTest, PropertyRestrictsPopCorrectly) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -3039,7 +3039,7 @@ TEST_P(QueryVisitorTest, UnsatisfiablePropertyRestrictsPopCorrectly) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -3063,7 +3063,7 @@ TEST_F(QueryVisitorTest, UnsupportedFunctionReturnsInvalidArgument) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); EXPECT_THAT(std::move(query_visitor).ConsumeResults(), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); @@ -3077,7 +3077,7 @@ TEST_F(QueryVisitorTest, SearchFunctionTooFewArgumentsReturnsInvalidArgument) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); EXPECT_THAT(std::move(query_visitor).ConsumeResults(), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); @@ -3091,7 +3091,7 @@ TEST_F(QueryVisitorTest, SearchFunctionTooManyArgumentsReturnsInvalidArgument) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); EXPECT_THAT(std::move(query_visitor).ConsumeResults(), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); @@ -3107,7 +3107,7 @@ TEST_F(QueryVisitorTest, index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); EXPECT_THAT(std::move(query_visitor).ConsumeResults(), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); @@ -3119,7 +3119,7 @@ TEST_F(QueryVisitorTest, index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor_two); EXPECT_THAT(std::move(query_visitor_two).ConsumeResults(), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); @@ -3135,7 +3135,7 @@ TEST_F(QueryVisitorTest, index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); EXPECT_THAT(std::move(query_visitor).ConsumeResults(), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); @@ -3147,7 +3147,7 @@ TEST_F(QueryVisitorTest, index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor_two); EXPECT_THAT(std::move(query_visitor_two).ConsumeResults(), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); @@ -3162,7 +3162,7 @@ TEST_F(QueryVisitorTest, index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); EXPECT_THAT(std::move(query_visitor).ConsumeResults(), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); @@ -3225,7 +3225,7 @@ TEST_F(QueryVisitorTest, SearchFunctionNestedFunctionCalls) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), level_two_query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -3249,7 +3249,7 @@ TEST_F(QueryVisitorTest, SearchFunctionNestedFunctionCalls) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), level_three_query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor_two); ICING_ASSERT_OK_AND_ASSIGN(query_results, std::move(query_visitor_two).ConsumeResults()); @@ -3273,7 +3273,7 @@ TEST_F(QueryVisitorTest, SearchFunctionNestedFunctionCalls) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), level_four_query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor_three); ICING_ASSERT_OK_AND_ASSIGN(query_results, std::move(query_visitor_three).ConsumeResults()); @@ -3395,7 +3395,7 @@ TEST_F(QueryVisitorTest, SearchFunctionNestedPropertyRestrictsNarrowing) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), level_one_query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -3427,7 +3427,7 @@ TEST_F(QueryVisitorTest, SearchFunctionNestedPropertyRestrictsNarrowing) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), level_two_query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor_two); ICING_ASSERT_OK_AND_ASSIGN(query_results, std::move(query_visitor_two).ConsumeResults()); @@ -3453,7 +3453,7 @@ TEST_F(QueryVisitorTest, SearchFunctionNestedPropertyRestrictsNarrowing) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), level_three_query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor_three); ICING_ASSERT_OK_AND_ASSIGN(query_results, std::move(query_visitor_three).ConsumeResults()); @@ -3575,7 +3575,7 @@ TEST_F(QueryVisitorTest, SearchFunctionNestedPropertyRestrictsExpanding) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), level_one_query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -3599,7 +3599,7 @@ TEST_F(QueryVisitorTest, SearchFunctionNestedPropertyRestrictsExpanding) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), level_two_query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor_two); ICING_ASSERT_OK_AND_ASSIGN(query_results, std::move(query_visitor_two).ConsumeResults()); @@ -3624,7 +3624,7 @@ TEST_F(QueryVisitorTest, SearchFunctionNestedPropertyRestrictsExpanding) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), level_three_query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor_three); ICING_ASSERT_OK_AND_ASSIGN(query_results, std::move(query_visitor_three).ConsumeResults()); @@ -3650,7 +3650,7 @@ TEST_F(QueryVisitorTest, index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); EXPECT_THAT(std::move(query_visitor).ConsumeResults(), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); @@ -3666,7 +3666,7 @@ TEST_F( index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); EXPECT_THAT(std::move(query_visitor).ConsumeResults(), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); @@ -3682,7 +3682,7 @@ TEST_F(QueryVisitorTest, index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); EXPECT_THAT(std::move(query_visitor).ConsumeResults(), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); @@ -3697,7 +3697,7 @@ TEST_F(QueryVisitorTest, index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); EXPECT_THAT(std::move(query_visitor).ConsumeResults(), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); @@ -3751,7 +3751,7 @@ TEST_P(QueryVisitorTest, PropertyDefinedFunctionReturnsMatchingDocuments) { index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -3804,7 +3804,7 @@ TEST_P(QueryVisitorTest, index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); @@ -3855,7 +3855,7 @@ TEST_P(QueryVisitorTest, index_.get(), numeric_index_.get(), document_store_.get(), schema_store_.get(), normalizer_.get(), tokenizer_.get(), query, DocHitInfoIteratorFilter::Options(), TERM_MATCH_PREFIX, - /*needs_term_frequency_info_=*/true); + /*needs_term_frequency_info_=*/true, clock_.GetSystemTimeMilliseconds()); root_node->Accept(&query_visitor); ICING_ASSERT_OK_AND_ASSIGN(QueryResults query_results, std::move(query_visitor).ConsumeResults()); diff --git a/icing/query/query-processor.cc b/icing/query/query-processor.cc index c9704fe..5e0b696 100644 --- a/icing/query/query-processor.cc +++ b/icing/query/query-processor.cc @@ -140,7 +140,8 @@ QueryProcessor::QueryProcessor(Index* index, libtextclassifier3::StatusOr<QueryResults> QueryProcessor::ParseSearch( const SearchSpecProto& search_spec, - ScoringSpecProto::RankingStrategy::Code ranking_strategy) { + ScoringSpecProto::RankingStrategy::Code ranking_strategy, + int64_t current_time_ms) { if (search_spec.search_type() == SearchSpecProto::SearchType::UNDEFINED) { return absl_ports::InvalidArgumentError(absl_ports::StrCat( "Search type ", @@ -151,11 +152,12 @@ libtextclassifier3::StatusOr<QueryResults> QueryProcessor::ParseSearch( if (search_spec.search_type() == SearchSpecProto::SearchType::EXPERIMENTAL_ICING_ADVANCED_QUERY) { ICING_VLOG(1) << "Using EXPERIMENTAL_ICING_ADVANCED_QUERY parser!"; - ICING_ASSIGN_OR_RETURN(results, - ParseAdvancedQuery(search_spec, ranking_strategy)); + ICING_ASSIGN_OR_RETURN( + results, + ParseAdvancedQuery(search_spec, ranking_strategy, current_time_ms)); } else { - ICING_ASSIGN_OR_RETURN(results, - ParseRawQuery(search_spec, ranking_strategy)); + ICING_ASSIGN_OR_RETURN( + results, ParseRawQuery(search_spec, ranking_strategy, current_time_ms)); } // Check that all new features used in the search have been enabled in the @@ -173,13 +175,14 @@ libtextclassifier3::StatusOr<QueryResults> QueryProcessor::ParseSearch( DocHitInfoIteratorFilter::Options options = GetFilterOptions(search_spec); results.root_iterator = std::make_unique<DocHitInfoIteratorFilter>( std::move(results.root_iterator), &document_store_, &schema_store_, - options); + options, current_time_ms); return results; } libtextclassifier3::StatusOr<QueryResults> QueryProcessor::ParseAdvancedQuery( const SearchSpecProto& search_spec, - ScoringSpecProto::RankingStrategy::Code ranking_strategy) const { + ScoringSpecProto::RankingStrategy::Code ranking_strategy, + int64_t current_time_ms) const { QueryResults results; Lexer lexer(search_spec.query(), Lexer::Language::QUERY); ICING_ASSIGN_OR_RETURN(std::vector<Lexer::LexerToken> lexer_tokens, @@ -201,10 +204,11 @@ libtextclassifier3::StatusOr<QueryResults> QueryProcessor::ParseAdvancedQuery( DocHitInfoIteratorFilter::Options options = GetFilterOptions(search_spec); bool needs_term_frequency_info = ranking_strategy == ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE; - QueryVisitor query_visitor( - &index_, &numeric_index_, &document_store_, &schema_store_, &normalizer_, - plain_tokenizer.get(), search_spec.query(), std::move(options), - search_spec.term_match_type(), needs_term_frequency_info); + QueryVisitor query_visitor(&index_, &numeric_index_, &document_store_, + &schema_store_, &normalizer_, + plain_tokenizer.get(), search_spec.query(), + std::move(options), search_spec.term_match_type(), + needs_term_frequency_info, current_time_ms); tree_root->Accept(&query_visitor); return std::move(query_visitor).ConsumeResults(); } @@ -212,7 +216,8 @@ libtextclassifier3::StatusOr<QueryResults> QueryProcessor::ParseAdvancedQuery( // TODO(cassiewang): Collect query stats to populate the SearchResultsProto libtextclassifier3::StatusOr<QueryResults> QueryProcessor::ParseRawQuery( const SearchSpecProto& search_spec, - ScoringSpecProto::RankingStrategy::Code ranking_strategy) { + ScoringSpecProto::RankingStrategy::Code ranking_strategy, + int64_t current_time_ms) { DocHitInfoIteratorFilter::Options options = GetFilterOptions(search_spec); // Tokenize the incoming raw query @@ -338,7 +343,7 @@ libtextclassifier3::StatusOr<QueryResults> QueryProcessor::ParseRawQuery( results.query_term_iterators[normalized_text] = std::make_unique<DocHitInfoIteratorFilter>( std::move(term_iterator), &document_store_, &schema_store_, - options); + options, current_time_ms); } results.query_terms[frames.top().section_restrict].insert( std::move(normalized_text)); @@ -396,7 +401,7 @@ libtextclassifier3::StatusOr<QueryResults> QueryProcessor::ParseRawQuery( section_restricts.insert(std::move(frames.top().section_restrict)); result_iterator = std::make_unique<DocHitInfoIteratorSectionRestrict>( std::move(result_iterator), &document_store_, &schema_store_, - std::move(section_restricts)); + std::move(section_restricts), current_time_ms); frames.top().section_restrict = ""; } diff --git a/icing/query/query-processor.h b/icing/query/query-processor.h index 26c5984..d4c22dd 100644 --- a/icing/query/query-processor.h +++ b/icing/query/query-processor.h @@ -67,7 +67,8 @@ class QueryProcessor { // INTERNAL_ERROR on all other errors libtextclassifier3::StatusOr<QueryResults> ParseSearch( const SearchSpecProto& search_spec, - ScoringSpecProto::RankingStrategy::Code ranking_strategy); + ScoringSpecProto::RankingStrategy::Code ranking_strategy, + int64_t current_time_ms); private: explicit QueryProcessor(Index* index, @@ -86,7 +87,8 @@ class QueryProcessor { // INVALID_ARGUMENT if query syntax is incorrect and cannot be tokenized libtextclassifier3::StatusOr<QueryResults> ParseAdvancedQuery( const SearchSpecProto& search_spec, - ScoringSpecProto::RankingStrategy::Code ranking_strategy) const; + ScoringSpecProto::RankingStrategy::Code ranking_strategy, + int64_t current_time_ms) const; // Parse the query into a one DocHitInfoIterator that represents the root of a // query tree. @@ -99,7 +101,8 @@ class QueryProcessor { // INTERNAL_ERROR on all other errors libtextclassifier3::StatusOr<QueryResults> ParseRawQuery( const SearchSpecProto& search_spec, - ScoringSpecProto::RankingStrategy::Code ranking_strategy); + ScoringSpecProto::RankingStrategy::Code ranking_strategy, + int64_t current_time_ms); // Not const because we could modify/sort the hit buffer in the lite index at // query time. diff --git a/icing/query/query-processor_benchmark.cc b/icing/query/query-processor_benchmark.cc index 3596082..89f3b54 100644 --- a/icing/query/query-processor_benchmark.cc +++ b/icing/query/query-processor_benchmark.cc @@ -180,7 +180,8 @@ void BM_QueryOneTerm(benchmark::State& state) { QueryResults results = query_processor ->ParseSearch(search_spec, - ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE) + ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + clock.GetSystemTimeMilliseconds()) .ValueOrDie(); while (results.root_iterator->Advance().ok()) { results.root_iterator->doc_hit_info(); @@ -326,7 +327,8 @@ void BM_QueryFiveTerms(benchmark::State& state) { QueryResults results = query_processor ->ParseSearch(search_spec, - ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE) + ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + clock.GetSystemTimeMilliseconds()) .ValueOrDie(); while (results.root_iterator->Advance().ok()) { results.root_iterator->doc_hit_info(); @@ -457,7 +459,8 @@ void BM_QueryDiacriticTerm(benchmark::State& state) { QueryResults results = query_processor ->ParseSearch(search_spec, - ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE) + ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + clock.GetSystemTimeMilliseconds()) .ValueOrDie(); while (results.root_iterator->Advance().ok()) { results.root_iterator->doc_hit_info(); @@ -588,7 +591,8 @@ void BM_QueryHiragana(benchmark::State& state) { QueryResults results = query_processor ->ParseSearch(search_spec, - ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE) + ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + clock.GetSystemTimeMilliseconds()) .ValueOrDie(); while (results.root_iterator->Advance().ok()) { results.root_iterator->doc_hit_info(); diff --git a/icing/query/query-processor_test.cc b/icing/query/query-processor_test.cc index be20b04..3d3cf48 100644 --- a/icing/query/query-processor_test.cc +++ b/icing/query/query-processor_test.cc @@ -246,7 +246,8 @@ TEST_P(QueryProcessorTest, EmptyGroupMatchAllDocuments) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch(search_spec, - ScoringSpecProto::RankingStrategy::NONE)); + ScoringSpecProto::RankingStrategy::NONE, + fake_clock_.GetSystemTimeMilliseconds())); // Descending order of valid DocumentIds EXPECT_THAT(GetDocumentIds(results.root_iterator.get()), @@ -257,7 +258,8 @@ TEST_P(QueryProcessorTest, EmptyGroupMatchAllDocuments) { // TODO(b/208654892): Resolve the difference between RAW_QUERY and ADVANCED // regarding empty composite expressions. EXPECT_THAT(query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::NONE), + search_spec, ScoringSpecProto::RankingStrategy::NONE, + fake_clock_.GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); } } @@ -292,7 +294,8 @@ TEST_P(QueryProcessorTest, EmptyQueryMatchAllDocuments) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch(search_spec, - ScoringSpecProto::RankingStrategy::NONE)); + ScoringSpecProto::RankingStrategy::NONE, + fake_clock_.GetSystemTimeMilliseconds())); // Descending order of valid DocumentIds EXPECT_THAT(GetDocumentIds(results.root_iterator.get()), @@ -340,7 +343,8 @@ TEST_P(QueryProcessorTest, QueryTermNormalized) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE)); + search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + fake_clock_.GetSystemTimeMilliseconds())); ASSERT_THAT(results.root_iterator->Advance(), IsOk()); EXPECT_EQ(results.root_iterator->doc_hit_info().document_id(), document_id); @@ -397,7 +401,8 @@ TEST_P(QueryProcessorTest, OneTermPrefixMatch) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE)); + search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + fake_clock_.GetSystemTimeMilliseconds())); ASSERT_THAT(results.root_iterator->Advance(), IsOk()); EXPECT_EQ(results.root_iterator->doc_hit_info().document_id(), document_id); @@ -454,7 +459,8 @@ TEST_P(QueryProcessorTest, OneTermPrefixMatchWithMaxSectionID) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE)); + search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + fake_clock_.GetSystemTimeMilliseconds())); ASSERT_THAT(results.root_iterator->Advance(), IsOk()); EXPECT_EQ(results.root_iterator->doc_hit_info().document_id(), document_id); @@ -509,7 +515,8 @@ TEST_P(QueryProcessorTest, OneTermExactMatch) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE)); + search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + fake_clock_.GetSystemTimeMilliseconds())); ASSERT_THAT(results.root_iterator->Advance(), IsOk()); EXPECT_EQ(results.root_iterator->doc_hit_info().document_id(), document_id); @@ -564,7 +571,8 @@ TEST_P(QueryProcessorTest, AndSameTermExactMatch) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE)); + search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + fake_clock_.GetSystemTimeMilliseconds())); ASSERT_THAT(results.root_iterator->Advance(), IsOk()); EXPECT_EQ(results.root_iterator->doc_hit_info().document_id(), document_id); @@ -624,7 +632,8 @@ TEST_P(QueryProcessorTest, AndTwoTermExactMatch) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE)); + search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + fake_clock_.GetSystemTimeMilliseconds())); ASSERT_THAT(results.root_iterator->Advance(), IsOk()); EXPECT_EQ(results.root_iterator->doc_hit_info().document_id(), document_id); @@ -681,7 +690,8 @@ TEST_P(QueryProcessorTest, AndSameTermPrefixMatch) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE)); + search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + fake_clock_.GetSystemTimeMilliseconds())); ASSERT_THAT(results.root_iterator->Advance(), IsOk()); EXPECT_EQ(results.root_iterator->doc_hit_info().document_id(), document_id); @@ -741,7 +751,8 @@ TEST_P(QueryProcessorTest, AndTwoTermPrefixMatch) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE)); + search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + fake_clock_.GetSystemTimeMilliseconds())); // Descending order of valid DocumentIds ASSERT_THAT(results.root_iterator->Advance(), IsOk()); @@ -802,7 +813,8 @@ TEST_P(QueryProcessorTest, AndTwoTermPrefixAndExactMatch) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE)); + search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + fake_clock_.GetSystemTimeMilliseconds())); // Descending order of valid DocumentIds ASSERT_THAT(results.root_iterator->Advance(), IsOk()); @@ -868,7 +880,8 @@ TEST_P(QueryProcessorTest, OrTwoTermExactMatch) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE)); + search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + fake_clock_.GetSystemTimeMilliseconds())); // Descending order of valid DocumentIds ASSERT_THAT(results.root_iterator->Advance(), IsOk()); @@ -942,7 +955,8 @@ TEST_P(QueryProcessorTest, OrTwoTermPrefixMatch) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE)); + search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + fake_clock_.GetSystemTimeMilliseconds())); // Descending order of valid DocumentIds ASSERT_THAT(results.root_iterator->Advance(), IsOk()); @@ -1015,7 +1029,8 @@ TEST_P(QueryProcessorTest, OrTwoTermPrefixAndExactMatch) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE)); + search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + fake_clock_.GetSystemTimeMilliseconds())); // Descending order of valid DocumentIds ASSERT_THAT(results.root_iterator->Advance(), IsOk()); @@ -1104,7 +1119,8 @@ TEST_P(QueryProcessorTest, CombinedAndOrTerms) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE)); + search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + fake_clock_.GetSystemTimeMilliseconds())); // Only Document 1 matches since it has puppy AND dog ASSERT_THAT(results.root_iterator->Advance(), IsOk()); @@ -1139,7 +1155,8 @@ TEST_P(QueryProcessorTest, CombinedAndOrTerms) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE)); + search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + fake_clock_.GetSystemTimeMilliseconds())); // Both Document 1 and 2 match since Document 1 has animal AND puppy, and // Document 2 has animal AND kitten @@ -1190,7 +1207,8 @@ TEST_P(QueryProcessorTest, CombinedAndOrTerms) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE)); + search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + fake_clock_.GetSystemTimeMilliseconds())); // Only Document 2 matches since it has both kitten and cat ASSERT_THAT(results.root_iterator->Advance(), IsOk()); @@ -1267,7 +1285,8 @@ TEST_P(QueryProcessorTest, OneGroup) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE)); + search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + fake_clock_.GetSystemTimeMilliseconds())); // Descending order of valid DocumentIds DocHitInfo expectedDocHitInfo(document_id1); @@ -1334,7 +1353,8 @@ TEST_P(QueryProcessorTest, TwoGroups) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE)); + search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + fake_clock_.GetSystemTimeMilliseconds())); // Descending order of valid DocumentIds DocHitInfo expectedDocHitInfo1(document_id1); @@ -1402,7 +1422,8 @@ TEST_P(QueryProcessorTest, ManyLevelNestedGrouping) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE)); + search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + fake_clock_.GetSystemTimeMilliseconds())); // Descending order of valid DocumentIds DocHitInfo expectedDocHitInfo(document_id1); @@ -1468,7 +1489,8 @@ TEST_P(QueryProcessorTest, OneLevelNestedGrouping) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE)); + search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + fake_clock_.GetSystemTimeMilliseconds())); // Descending order of valid DocumentIds DocHitInfo expectedDocHitInfo1(document_id1); @@ -1527,7 +1549,8 @@ TEST_P(QueryProcessorTest, ExcludeTerm) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch(search_spec, - ScoringSpecProto::RankingStrategy::NONE)); + ScoringSpecProto::RankingStrategy::NONE, + fake_clock_.GetSystemTimeMilliseconds())); // We don't know have the section mask to indicate what section "world" // came. It doesn't matter which section it was in since the query doesn't @@ -1580,7 +1603,8 @@ TEST_P(QueryProcessorTest, ExcludeNonexistentTerm) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch(search_spec, - ScoringSpecProto::RankingStrategy::NONE)); + ScoringSpecProto::RankingStrategy::NONE, + fake_clock_.GetSystemTimeMilliseconds())); // Descending order of valid DocumentIds EXPECT_THAT(GetDocHitInfos(results.root_iterator.get()), @@ -1641,7 +1665,8 @@ TEST_P(QueryProcessorTest, ExcludeAnd) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE)); + search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + fake_clock_.GetSystemTimeMilliseconds())); // The query is interpreted as "exclude all documents that have animal, // and exclude all documents that have cat". Since both documents contain @@ -1661,7 +1686,8 @@ TEST_P(QueryProcessorTest, ExcludeAnd) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE)); + search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + fake_clock_.GetSystemTimeMilliseconds())); // The query is interpreted as "exclude all documents that have animal, // and include all documents that have cat". Since both documents contain @@ -1725,7 +1751,8 @@ TEST_P(QueryProcessorTest, ExcludeOr) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE)); + search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + fake_clock_.GetSystemTimeMilliseconds())); // We don't have a section mask indicating which sections in this document // matched the query since it's not based on section-term matching. It's @@ -1746,7 +1773,8 @@ TEST_P(QueryProcessorTest, ExcludeOr) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE)); + search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + fake_clock_.GetSystemTimeMilliseconds())); // Descending order of valid DocumentIds DocHitInfo expectedDocHitInfo1(document_id1); @@ -1823,7 +1851,8 @@ TEST_P(QueryProcessorTest, WithoutTermFrequency) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch(search_spec, - ScoringSpecProto::RankingStrategy::NONE)); + ScoringSpecProto::RankingStrategy::NONE, + fake_clock_.GetSystemTimeMilliseconds())); // Descending order of valid DocumentIds // The first Document to match (Document 2) matches on 'animal' AND 'kitten' @@ -1883,7 +1912,9 @@ TEST_P(QueryProcessorTest, DeletedFilter) { .SetKey("namespace", "2") .SetSchema("email") .Build())); - EXPECT_THAT(document_store_->Delete("namespace", "1"), IsOk()); + EXPECT_THAT(document_store_->Delete("namespace", "1", + fake_clock_.GetSystemTimeMilliseconds()), + IsOk()); // Populate the index SectionId section_id = 0; @@ -1911,7 +1942,8 @@ TEST_P(QueryProcessorTest, DeletedFilter) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE)); + search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + fake_clock_.GetSystemTimeMilliseconds())); // Descending order of valid DocumentIds DocHitInfo expectedDocHitInfo(document_id2); @@ -1975,7 +2007,8 @@ TEST_P(QueryProcessorTest, NamespaceFilter) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE)); + search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + fake_clock_.GetSystemTimeMilliseconds())); // Descending order of valid DocumentIds DocHitInfo expectedDocHitInfo(document_id1); @@ -2037,7 +2070,8 @@ TEST_P(QueryProcessorTest, SchemaTypeFilter) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE)); + search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + fake_clock_.GetSystemTimeMilliseconds())); // Descending order of valid DocumentIds DocHitInfo expectedDocHitInfo(document_id1); @@ -2093,7 +2127,8 @@ TEST_P(QueryProcessorTest, PropertyFilterForOneDocument) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE)); + search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + fake_clock_.GetSystemTimeMilliseconds())); // Descending order of valid DocumentIds DocHitInfo expectedDocHitInfo(document_id); @@ -2175,7 +2210,8 @@ TEST_P(QueryProcessorTest, PropertyFilterAcrossSchemaTypes) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE)); + search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + fake_clock_.GetSystemTimeMilliseconds())); // Ordered by descending DocumentId, so message comes first since it was // inserted last @@ -2250,7 +2286,8 @@ TEST_P(QueryProcessorTest, PropertyFilterWithinSchemaType) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE)); + search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + fake_clock_.GetSystemTimeMilliseconds())); // Shouldn't include the message document since we're only looking at email // types @@ -2330,7 +2367,8 @@ TEST_P(QueryProcessorTest, NestedPropertyFilter) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE)); + search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + fake_clock_.GetSystemTimeMilliseconds())); // Even though the section id is the same, we should be able to tell that it // doesn't match to the name of the section filter @@ -2406,7 +2444,8 @@ TEST_P(QueryProcessorTest, PropertyFilterRespectsDifferentSectionIds) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE)); + search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + fake_clock_.GetSystemTimeMilliseconds())); // Even though the section id is the same, we should be able to tell that it // doesn't match to the name of the section filter @@ -2457,7 +2496,8 @@ TEST_P(QueryProcessorTest, NonexistentPropertyFilterReturnsEmptyResults) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE)); + search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + fake_clock_.GetSystemTimeMilliseconds())); // Even though the section id is the same, we should be able to tell that it // doesn't match to the name of the section filter @@ -2514,7 +2554,8 @@ TEST_P(QueryProcessorTest, UnindexedPropertyFilterReturnsEmptyResults) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE)); + search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + fake_clock_.GetSystemTimeMilliseconds())); // Even though the section id is the same, we should be able to tell that it // doesn't match to the name of the section filter @@ -2586,7 +2627,8 @@ TEST_P(QueryProcessorTest, PropertyFilterTermAndUnrestrictedTerm) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE)); + search_spec, ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, + fake_clock_.GetSystemTimeMilliseconds())); // Ordered by descending DocumentId, so message comes first since it was // inserted last @@ -2656,7 +2698,8 @@ TEST_P(QueryProcessorTest, DocumentBeforeTtlNotFilteredOut) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, local_query_processor->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::NONE)); + search_spec, ScoringSpecProto::RankingStrategy::NONE, + fake_clock_.GetSystemTimeMilliseconds())); DocHitInfo expectedDocHitInfo(document_id); expectedDocHitInfo.UpdateSection(/*section_id=*/0); @@ -2676,12 +2719,12 @@ TEST_P(QueryProcessorTest, DocumentPastTtlFilteredOut) { // Arbitrary value, just has to be greater than the document's creation // timestamp + ttl - FakeClock fake_clock; - fake_clock.SetSystemTimeMilliseconds(200); + FakeClock fake_clock_local; + fake_clock_local.SetSystemTimeMilliseconds(200); ICING_ASSERT_OK_AND_ASSIGN( DocumentStore::CreateResult create_result, - CreateDocumentStore(&filesystem_, store_dir_, &fake_clock, + CreateDocumentStore(&filesystem_, store_dir_, &fake_clock_local, schema_store_.get())); document_store_ = std::move(create_result.document_store); @@ -2717,7 +2760,8 @@ TEST_P(QueryProcessorTest, DocumentPastTtlFilteredOut) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, local_query_processor->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::NONE)); + search_spec, ScoringSpecProto::RankingStrategy::NONE, + fake_clock_local.GetSystemTimeMilliseconds())); EXPECT_THAT(GetDocHitInfos(results.root_iterator.get()), IsEmpty()); } @@ -2787,7 +2831,8 @@ TEST_P(QueryProcessorTest, NumericFilter) { ICING_ASSERT_OK_AND_ASSIGN( QueryResults results, query_processor_->ParseSearch(search_spec, - ScoringSpecProto::RankingStrategy::NONE)); + ScoringSpecProto::RankingStrategy::NONE, + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(GetDocHitInfos(results.root_iterator.get()), ElementsAre(EqualsDocHitInfo( document_one_id, std::vector<SectionId>{price_section_id}))); @@ -2795,7 +2840,8 @@ TEST_P(QueryProcessorTest, NumericFilter) { search_spec.set_query("price == 25"); ICING_ASSERT_OK_AND_ASSIGN( results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::NONE)); + search_spec, ScoringSpecProto::RankingStrategy::NONE, + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(GetDocHitInfos(results.root_iterator.get()), ElementsAre(EqualsDocHitInfo( document_two_id, std::vector<SectionId>{price_section_id}))); @@ -2803,13 +2849,15 @@ TEST_P(QueryProcessorTest, NumericFilter) { search_spec.set_query("cost > 2"); ICING_ASSERT_OK_AND_ASSIGN( results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::NONE)); + search_spec, ScoringSpecProto::RankingStrategy::NONE, + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(GetDocHitInfos(results.root_iterator.get()), IsEmpty()); search_spec.set_query("cost >= 2"); ICING_ASSERT_OK_AND_ASSIGN( results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::NONE)); + search_spec, ScoringSpecProto::RankingStrategy::NONE, + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(GetDocHitInfos(results.root_iterator.get()), ElementsAre(EqualsDocHitInfo( document_three_id, std::vector<SectionId>{cost_section_id}))); @@ -2817,7 +2865,8 @@ TEST_P(QueryProcessorTest, NumericFilter) { search_spec.set_query("price <= 25"); ICING_ASSERT_OK_AND_ASSIGN( results, query_processor_->ParseSearch( - search_spec, ScoringSpecProto::RankingStrategy::NONE)); + search_spec, ScoringSpecProto::RankingStrategy::NONE, + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT( GetDocHitInfos(results.root_iterator.get()), ElementsAre(EqualsDocHitInfo(document_two_id, @@ -2864,7 +2913,8 @@ TEST_P(QueryProcessorTest, NumericFilterWithoutEnablingFeatureFails) { libtextclassifier3::StatusOr<QueryResults> result_or = query_processor_->ParseSearch(search_spec, - ScoringSpecProto::RankingStrategy::NONE); + ScoringSpecProto::RankingStrategy::NONE, + fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(result_or, StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); } diff --git a/icing/query/suggestion-processor.cc b/icing/query/suggestion-processor.cc index 3626ae3..eb86e3b 100644 --- a/icing/query/suggestion-processor.cc +++ b/icing/query/suggestion-processor.cc @@ -161,7 +161,8 @@ PopulatePropertyFilters( libtextclassifier3::StatusOr<std::vector<TermMetadata>> SuggestionProcessor::QuerySuggestions( - const icing::lib::SuggestionSpecProto& suggestion_spec) { + const icing::lib::SuggestionSpecProto& suggestion_spec, + int64_t current_time_ms) { // We use query tokenizer to tokenize the give prefix, and we only use the // last token to be the suggestion prefix. @@ -233,7 +234,8 @@ SuggestionProcessor::QuerySuggestions( ICING_ASSIGN_OR_RETURN( QueryResults query_results, query_processor->ParseSearch(search_spec, - ScoringSpecProto::RankingStrategy::NONE)); + ScoringSpecProto::RankingStrategy::NONE, + current_time_ms)); ICING_ASSIGN_OR_RETURN( DocHitInfoIterator::TrimmedNode trimmed_node, @@ -273,7 +275,7 @@ SuggestionProcessor::QuerySuggestions( &document_store_, &schema_store_, std::move(namespace_ids), std::move(document_id_filter_map), std::move(schema_type_ids), std::move(property_filter_map), std::move(trimmed_node.target_section_), - std::move(search_base)); + std::move(search_base), current_time_ms); // TODO(b/228240987) support generate suggestion and append suffix for advance // query and function call. std::string query_prefix = diff --git a/icing/query/suggestion-processor.h b/icing/query/suggestion-processor.h index 01ea9b9..e100031 100644 --- a/icing/query/suggestion-processor.h +++ b/icing/query/suggestion-processor.h @@ -52,7 +52,7 @@ class SuggestionProcessor { // - One vector that represents the entire TermMetadata // INTERNAL_ERROR on all other errors libtextclassifier3::StatusOr<std::vector<TermMetadata>> QuerySuggestions( - const SuggestionSpecProto& suggestion_spec); + const SuggestionSpecProto& suggestion_spec, int64_t current_time_ms); private: explicit SuggestionProcessor(Index* index, diff --git a/icing/query/suggestion-processor_test.cc b/icing/query/suggestion-processor_test.cc index 4937f39..b1336b3 100644 --- a/icing/query/suggestion-processor_test.cc +++ b/icing/query/suggestion-processor_test.cc @@ -200,7 +200,8 @@ TEST_F(SuggestionProcessorTest, MultipleTermsTest_And) { ICING_ASSERT_OK_AND_ASSIGN( std::vector<TermMetadata> terms, - suggestion_processor_->QuerySuggestions(suggestion_spec)); + suggestion_processor_->QuerySuggestions( + suggestion_spec, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(RetrieveSuggestionsText(terms), UnorderedElementsAre("bar foo")); } @@ -249,7 +250,8 @@ TEST_F(SuggestionProcessorTest, MultipleTermsTest_AndNary) { ICING_ASSERT_OK_AND_ASSIGN( std::vector<TermMetadata> terms, - suggestion_processor_->QuerySuggestions(suggestion_spec)); + suggestion_processor_->QuerySuggestions( + suggestion_spec, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(RetrieveSuggestionsText(terms), UnorderedElementsAre("bar cat foo")); } @@ -301,7 +303,8 @@ TEST_F(SuggestionProcessorTest, MultipleTermsTest_Or) { ICING_ASSERT_OK_AND_ASSIGN( std::vector<TermMetadata> terms, - suggestion_processor_->QuerySuggestions(suggestion_spec)); + suggestion_processor_->QuerySuggestions( + suggestion_spec, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(RetrieveSuggestionsText(terms), UnorderedElementsAre("bar OR cat fo", "bar OR cat foo")); } @@ -363,7 +366,8 @@ TEST_F(SuggestionProcessorTest, MultipleTermsTest_OrNary) { ICING_ASSERT_OK_AND_ASSIGN( std::vector<TermMetadata> terms, - suggestion_processor_->QuerySuggestions(suggestion_spec)); + suggestion_processor_->QuerySuggestions( + suggestion_spec, fake_clock_.GetSystemTimeMilliseconds())); // "fo" in document1, "foo" in document2 and "fool" in document3 could match. EXPECT_THAT( RetrieveSuggestionsText(terms), @@ -417,7 +421,8 @@ TEST_F(SuggestionProcessorTest, MultipleTermsTest_NormalizedTerm) { ICING_ASSERT_OK_AND_ASSIGN( std::vector<TermMetadata> terms, - suggestion_processor_->QuerySuggestions(suggestion_spec)); + suggestion_processor_->QuerySuggestions( + suggestion_spec, fake_clock_.GetSystemTimeMilliseconds())); // The term is normalized. EXPECT_THAT(RetrieveSuggestionsText(terms), UnorderedElementsAre("bar foo", "bar fool")); @@ -425,7 +430,8 @@ TEST_F(SuggestionProcessorTest, MultipleTermsTest_NormalizedTerm) { // Search for "bar AND ḞÖ" suggestion_spec.set_prefix("bar ḞÖ"); ICING_ASSERT_OK_AND_ASSIGN( - terms, suggestion_processor_->QuerySuggestions(suggestion_spec)); + terms, suggestion_processor_->QuerySuggestions( + suggestion_spec, fake_clock_.GetSystemTimeMilliseconds())); // The term is normalized. EXPECT_THAT(RetrieveSuggestionsText(terms), UnorderedElementsAre("bar foo", "bar fool")); @@ -462,7 +468,8 @@ TEST_F(SuggestionProcessorTest, NonExistentPrefixTest) { ICING_ASSERT_OK_AND_ASSIGN( std::vector<TermMetadata> terms, - suggestion_processor_->QuerySuggestions(suggestion_spec)); + suggestion_processor_->QuerySuggestions( + suggestion_spec, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(terms, IsEmpty()); } @@ -497,7 +504,8 @@ TEST_F(SuggestionProcessorTest, PrefixTrailingSpaceTest) { ICING_ASSERT_OK_AND_ASSIGN( std::vector<TermMetadata> terms, - suggestion_processor_->QuerySuggestions(suggestion_spec)); + suggestion_processor_->QuerySuggestions( + suggestion_spec, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(terms, IsEmpty()); } @@ -531,22 +539,26 @@ TEST_F(SuggestionProcessorTest, NormalizePrefixTest) { TermMatchType::PREFIX); ICING_ASSERT_OK_AND_ASSIGN( std::vector<TermMetadata> terms, - suggestion_processor_->QuerySuggestions(suggestion_spec)); + suggestion_processor_->QuerySuggestions( + suggestion_spec, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(RetrieveSuggestionsText(terms), UnorderedElementsAre("foo")); suggestion_spec.set_prefix("fO"); ICING_ASSERT_OK_AND_ASSIGN( - terms, suggestion_processor_->QuerySuggestions(suggestion_spec)); + terms, suggestion_processor_->QuerySuggestions( + suggestion_spec, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(RetrieveSuggestionsText(terms), UnorderedElementsAre("foo")); suggestion_spec.set_prefix("Fo"); ICING_ASSERT_OK_AND_ASSIGN( - terms, suggestion_processor_->QuerySuggestions(suggestion_spec)); + terms, suggestion_processor_->QuerySuggestions( + suggestion_spec, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(RetrieveSuggestionsText(terms), UnorderedElementsAre("foo")); suggestion_spec.set_prefix("FO"); ICING_ASSERT_OK_AND_ASSIGN( - terms, suggestion_processor_->QuerySuggestions(suggestion_spec)); + terms, suggestion_processor_->QuerySuggestions( + suggestion_spec, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(RetrieveSuggestionsText(terms), UnorderedElementsAre("foo")); } @@ -581,17 +593,20 @@ TEST_F(SuggestionProcessorTest, ParenthesesOperatorPrefixTest) { ICING_ASSERT_OK_AND_ASSIGN( std::vector<TermMetadata> terms, - suggestion_processor_->QuerySuggestions(suggestion_spec)); + suggestion_processor_->QuerySuggestions( + suggestion_spec, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(terms, IsEmpty()); suggestion_spec.set_prefix("[f]"); ICING_ASSERT_OK_AND_ASSIGN( - terms, suggestion_processor_->QuerySuggestions(suggestion_spec)); + terms, suggestion_processor_->QuerySuggestions( + suggestion_spec, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(terms, IsEmpty()); suggestion_spec.set_prefix("(f)"); ICING_ASSERT_OK_AND_ASSIGN( - terms, suggestion_processor_->QuerySuggestions(suggestion_spec)); + terms, suggestion_processor_->QuerySuggestions( + suggestion_spec, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(terms, IsEmpty()); } @@ -624,7 +639,8 @@ TEST_F(SuggestionProcessorTest, OtherSpecialPrefixTest) { suggestion_spec.mutable_scoring_spec()->set_scoring_match_type( TermMatchType::PREFIX); - auto terms_or = suggestion_processor_->QuerySuggestions(suggestion_spec); + auto terms_or = suggestion_processor_->QuerySuggestions( + suggestion_spec, fake_clock_.GetSystemTimeMilliseconds()); if (SearchSpecProto::default_instance().search_type() == SearchSpecProto::SearchType::ICING_RAW_QUERY) { ICING_ASSERT_OK_AND_ASSIGN(std::vector<TermMetadata> terms, terms_or); @@ -638,12 +654,14 @@ TEST_F(SuggestionProcessorTest, OtherSpecialPrefixTest) { // within a TEXT token (rather than a MINUS token) when surrounded on both // sides by TEXT rather than just preceded by TEXT. suggestion_spec.set_prefix("f-"); - terms_or = suggestion_processor_->QuerySuggestions(suggestion_spec); + terms_or = suggestion_processor_->QuerySuggestions( + suggestion_spec, fake_clock_.GetSystemTimeMilliseconds()); ICING_ASSERT_OK_AND_ASSIGN(std::vector<TermMetadata> terms, terms_or); EXPECT_THAT(terms, IsEmpty()); suggestion_spec.set_prefix("f OR"); - terms_or = suggestion_processor_->QuerySuggestions(suggestion_spec); + terms_or = suggestion_processor_->QuerySuggestions( + suggestion_spec, fake_clock_.GetSystemTimeMilliseconds()); if (SearchSpecProto::default_instance().search_type() == SearchSpecProto::SearchType::ICING_RAW_QUERY) { ICING_ASSERT_OK_AND_ASSIGN(std::vector<TermMetadata> terms, terms_or); @@ -683,7 +701,8 @@ TEST_F(SuggestionProcessorTest, InvalidPrefixTest) { suggestion_spec.mutable_scoring_spec()->set_scoring_match_type( TermMatchType::PREFIX); - auto terms_or = suggestion_processor_->QuerySuggestions(suggestion_spec); + auto terms_or = suggestion_processor_->QuerySuggestions( + suggestion_spec, fake_clock_.GetSystemTimeMilliseconds()); if (SearchSpecProto::default_instance().search_type() == SearchSpecProto::SearchType::ICING_RAW_QUERY) { ICING_ASSERT_OK_AND_ASSIGN(std::vector<TermMetadata> terms, terms_or); diff --git a/icing/result/result-retriever-v2.cc b/icing/result/result-retriever-v2.cc index c7a8fcd..44fa602 100644 --- a/icing/result/result-retriever-v2.cc +++ b/icing/result/result-retriever-v2.cc @@ -100,10 +100,11 @@ bool GroupResultLimiterV2::ShouldBeRemoved( const ScoredDocumentHit& scored_document_hit, const std::unordered_map<int32_t, int>& entry_id_group_id_map, const DocumentStore& document_store, std::vector<int>& group_result_limits, - ResultSpecProto::ResultGroupingType result_group_type) const { + ResultSpecProto::ResultGroupingType result_group_type, + int64_t current_time_ms) const { auto document_filter_data_optional = document_store.GetAliveDocumentFilterData( - scored_document_hit.document_id()); + scored_document_hit.document_id(), current_time_ms); if (!document_filter_data_optional) { // The document doesn't exist. return true; @@ -153,7 +154,7 @@ ResultRetrieverV2::Create( } std::pair<PageResult, bool> ResultRetrieverV2::RetrieveNextPage( - ResultStateV2& result_state) const { + ResultStateV2& result_state, int64_t current_time_ms) const { absl_ports::unique_lock l(&result_state.mutex); // For calculating page @@ -171,8 +172,8 @@ std::pair<PageResult, bool> ResultRetrieverV2::RetrieveNextPage( if (group_result_limiter_->ShouldBeRemoved( next_best_document_hit.parent_scored_document_hit(), result_state.entry_id_group_id_map(), doc_store_, - result_state.group_result_limits, - result_state.result_group_type())) { + result_state.group_result_limits, result_state.result_group_type(), + current_time_ms)) { continue; } diff --git a/icing/result/result-retriever-v2.h b/icing/result/result-retriever-v2.h index 0499ae1..7b1a364 100644 --- a/icing/result/result-retriever-v2.h +++ b/icing/result/result-retriever-v2.h @@ -47,7 +47,8 @@ class GroupResultLimiterV2 { const std::unordered_map<int32_t, int>& entry_id_group_id_map, const DocumentStore& document_store, std::vector<int>& group_result_limits, - ResultSpecProto::ResultGroupingType result_group_type) const; + ResultSpecProto::ResultGroupingType result_group_type, + int64_t current_time_ms) const; }; class ResultRetrieverV2 { @@ -87,8 +88,8 @@ class ResultRetrieverV2 { // // Returns: // std::pair<PageResult, bool> - std::pair<PageResult, bool> RetrieveNextPage( - ResultStateV2& result_state) const; + std::pair<PageResult, bool> RetrieveNextPage(ResultStateV2& result_state, + int64_t current_time_ms) const; private: explicit ResultRetrieverV2( diff --git a/icing/result/result-retriever-v2_group-result-limiter_test.cc b/icing/result/result-retriever-v2_group-result-limiter_test.cc index c9e0587..5d8b589 100644 --- a/icing/result/result-retriever-v2_group-result-limiter_test.cc +++ b/icing/result/result-retriever-v2_group-result-limiter_test.cc @@ -171,8 +171,8 @@ TEST_F(ResultRetrieverV2GroupResultLimiterTest, // Only the top ranked document in "namespace" (document2), should be // returned. - auto [page_result, has_more_results] = - result_retriever->RetrieveNextPage(result_state); + auto [page_result, has_more_results] = result_retriever->RetrieveNextPage( + result_state, fake_clock_.GetSystemTimeMilliseconds()); ASSERT_THAT(page_result.results, SizeIs(1)); EXPECT_THAT(page_result.results.at(0).document(), EqualsProto(document2)); // Document1 has not been returned due to GroupResultLimiter, but since it was @@ -230,8 +230,8 @@ TEST_F(ResultRetrieverV2GroupResultLimiterTest, language_segmenter_.get(), normalizer_.get())); // First page: empty page - auto [page_result, has_more_results] = - result_retriever->RetrieveNextPage(result_state); + auto [page_result, has_more_results] = result_retriever->RetrieveNextPage( + result_state, fake_clock_.GetSystemTimeMilliseconds()); ASSERT_THAT(page_result.results, IsEmpty()); EXPECT_FALSE(has_more_results); } @@ -306,8 +306,8 @@ TEST_F(ResultRetrieverV2GroupResultLimiterTest, language_segmenter_.get(), normalizer_.get())); // First page: document4 and document3 should be returned. - auto [page_result1, has_more_results1] = - result_retriever->RetrieveNextPage(result_state); + auto [page_result1, has_more_results1] = result_retriever->RetrieveNextPage( + result_state, fake_clock_.GetSystemTimeMilliseconds()); ASSERT_THAT(page_result1.results, SizeIs(2)); EXPECT_THAT(page_result1.results.at(0).document(), EqualsProto(document4)); EXPECT_THAT(page_result1.results.at(1).document(), EqualsProto(document3)); @@ -316,8 +316,8 @@ TEST_F(ResultRetrieverV2GroupResultLimiterTest, // Second page: although there are valid document hits in result state, all of // them will be filtered out by group result limiter, so we should get an // empty page. - auto [page_result2, has_more_results2] = - result_retriever->RetrieveNextPage(result_state); + auto [page_result2, has_more_results2] = result_retriever->RetrieveNextPage( + result_state, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(page_result2.results, SizeIs(0)); EXPECT_FALSE(has_more_results2); } @@ -394,7 +394,10 @@ TEST_F(ResultRetrieverV2GroupResultLimiterTest, // All documents in "namespace2" should be returned. PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result.results, SizeIs(3)); EXPECT_THAT(page_result.results.at(0).document(), EqualsProto(document4)); EXPECT_THAT(page_result.results.at(1).document(), EqualsProto(document3)); @@ -457,7 +460,10 @@ TEST_F(ResultRetrieverV2GroupResultLimiterTest, // returned. The presence of "nonexistentNamespace" in the same result // grouping should have no effect. PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result.results, SizeIs(1)); EXPECT_THAT(page_result.results.at(0).document(), EqualsProto(document2)); } @@ -518,7 +524,10 @@ TEST_F(ResultRetrieverV2GroupResultLimiterTest, // returned. The presence of "nonexistentNamespace" in the same result // grouping should have no effect. PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result.results, SizeIs(1)); EXPECT_THAT(page_result.results.at(0).document(), EqualsProto(document2)); } @@ -624,7 +633,10 @@ TEST_F(ResultRetrieverV2GroupResultLimiterTest, // Only the top-ranked results across "namespace2" and "namespace3" // (document6, document5) should be returned. PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result.results, SizeIs(3)); EXPECT_THAT(page_result.results.at(0).document(), EqualsProto(document6)); EXPECT_THAT(page_result.results.at(1).document(), EqualsProto(document5)); @@ -732,7 +744,10 @@ TEST_F(ResultRetrieverV2GroupResultLimiterTest, // Only the top-ranked results across "Message" and "Person" // (document5, document3) should be returned. PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result.results, SizeIs(3)); EXPECT_THAT(page_result.results.at(0).document(), EqualsProto(document6)); EXPECT_THAT(page_result.results.at(1).document(), EqualsProto(document4)); @@ -845,7 +860,10 @@ TEST_F(ResultRetrieverV2GroupResultLimiterTest, // "namespace3xMessage" (document6, document5) should be returned. PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result.results, SizeIs(3)); EXPECT_THAT(page_result.results.at(0).document(), EqualsProto(document6)); EXPECT_THAT(page_result.results.at(1).document(), EqualsProto(document5)); @@ -905,7 +923,10 @@ TEST_F(ResultRetrieverV2GroupResultLimiterTest, // All documents in "namespace" should be returned. The presence of // "nonexistentNamespace" should have no effect. PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result.results, SizeIs(2)); EXPECT_THAT(page_result.results.at(0).document(), EqualsProto(document2)); EXPECT_THAT(page_result.results.at(1).document(), EqualsProto(document1)); @@ -964,7 +985,10 @@ TEST_F(ResultRetrieverV2GroupResultLimiterTest, // All documents in "Document" should be returned. The presence of // "nonexistentDocument" should have no effect. PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result.results, SizeIs(2)); EXPECT_THAT(page_result.results.at(0).document(), EqualsProto(document2)); EXPECT_THAT(page_result.results.at(1).document(), EqualsProto(document1)); @@ -1076,8 +1100,8 @@ TEST_F(ResultRetrieverV2GroupResultLimiterTest, // docuemnt3, document2 belong to namespace 1 (with max_results = 3). // Since num_per_page is 2, we expect to get document5 and document3 in the // first page. - auto [page_result1, has_more_results1] = - result_retriever->RetrieveNextPage(result_state); + auto [page_result1, has_more_results1] = result_retriever->RetrieveNextPage( + result_state, fake_clock_.GetSystemTimeMilliseconds()); ASSERT_THAT(page_result1.results, SizeIs(2)); ASSERT_THAT(page_result1.results.at(0).document(), EqualsProto(document5)); ASSERT_THAT(page_result1.results.at(1).document(), EqualsProto(document3)); @@ -1109,8 +1133,8 @@ TEST_F(ResultRetrieverV2GroupResultLimiterTest, // Although there are document2 and document1 left, since namespace2 has // reached its max results, document1 should be excluded from the second page. - auto [page_result2, has_more_results2] = - result_retriever->RetrieveNextPage(result_state); + auto [page_result2, has_more_results2] = result_retriever->RetrieveNextPage( + result_state, fake_clock_.GetSystemTimeMilliseconds()); ASSERT_THAT(page_result2.results, SizeIs(1)); ASSERT_THAT(page_result2.results.at(0).document(), EqualsProto(document2)); ASSERT_FALSE(has_more_results2); diff --git a/icing/result/result-retriever-v2_projection_test.cc b/icing/result/result-retriever-v2_projection_test.cc index 377e14c..6b868a5 100644 --- a/icing/result/result-retriever-v2_projection_test.cc +++ b/icing/result/result-retriever-v2_projection_test.cc @@ -312,7 +312,10 @@ TEST_F(ResultRetrieverV2ProjectionTest, ProjectionTopLevelLeadNodeFieldPath) { // 5. Verify that the returned results only contain the 'name' property. PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result.results, SizeIs(2)); DocumentProto projected_document_one = @@ -411,7 +414,10 @@ TEST_F(ResultRetrieverV2ProjectionTest, ProjectionNestedLeafNodeFieldPath) { // 5. Verify that the returned results only contain the 'sender.name' // property. PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result.results, SizeIs(2)); DocumentProto projected_document_one = @@ -520,7 +526,10 @@ TEST_F(ResultRetrieverV2ProjectionTest, ProjectionIntermediateNodeFieldPath) { // 5. Verify that the returned results only contain the 'sender' // property and all of the subproperties of 'sender'. PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result.results, SizeIs(2)); DocumentProto projected_document_one = @@ -633,7 +642,10 @@ TEST_F(ResultRetrieverV2ProjectionTest, ProjectionMultipleNestedFieldPaths) { // 5. Verify that the returned results only contain the 'sender.name' and // 'sender.address' properties. PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result.results, SizeIs(2)); DocumentProto projected_document_one = @@ -728,7 +740,10 @@ TEST_F(ResultRetrieverV2ProjectionTest, ProjectionEmptyFieldPath) { // 5. Verify that the returned results contain *no* properties. PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result.results, SizeIs(2)); DocumentProto projected_document_one = DocumentBuilder() @@ -807,7 +822,10 @@ TEST_F(ResultRetrieverV2ProjectionTest, ProjectionInvalidFieldPath) { // 5. Verify that the returned results contain *no* properties. PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result.results, SizeIs(2)); DocumentProto projected_document_one = DocumentBuilder() @@ -887,7 +905,10 @@ TEST_F(ResultRetrieverV2ProjectionTest, ProjectionValidAndInvalidFieldPath) { // 5. Verify that the returned results only contain the 'name' property. PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result.results, SizeIs(2)); DocumentProto projected_document_one = @@ -970,7 +991,10 @@ TEST_F(ResultRetrieverV2ProjectionTest, ProjectionMultipleTypesNoWildcards) { // 5. Verify that the returned Email results only contain the 'name' // property and the returned Person results have all of their properties. PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result.results, SizeIs(2)); DocumentProto projected_document_one = @@ -1056,7 +1080,10 @@ TEST_F(ResultRetrieverV2ProjectionTest, ProjectionMultipleTypesWildcard) { // 5. Verify that the returned Email results only contain the 'name' // property and the returned Person results only contain the 'name' property. PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result.results, SizeIs(2)); DocumentProto projected_document_one = @@ -1146,7 +1173,10 @@ TEST_F(ResultRetrieverV2ProjectionTest, // 5. Verify that the returned Email results only contain the 'body' // property and the returned Person results only contain the 'name' property. PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result.results, SizeIs(2)); DocumentProto projected_document_one = @@ -1245,7 +1275,10 @@ TEST_F(ResultRetrieverV2ProjectionTest, // 5. Verify that the returned Email results only contain the 'sender.name' // property and the returned Person results only contain the 'name' property. PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result.results, SizeIs(2)); DocumentProto projected_document_one = @@ -1348,7 +1381,10 @@ TEST_F(ResultRetrieverV2ProjectionTest, // 5. Verify that the returned Email results only contain the 'sender.name' // property and the returned Person results contain no properties. PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result.results, SizeIs(2)); DocumentProto projected_document_one = @@ -1478,7 +1514,10 @@ TEST_F(ResultRetrieverV2ProjectionTest, ProjectionJoinDocuments) { // - Person docs only contain the "name" property. // - Email docs only contain the "body" property. PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result.results, SizeIs(1)); // Check parent doc. @@ -1576,7 +1615,10 @@ TEST_F(ResultRetrieverV2ProjectionTest, ProjectionPolymorphism) { // 5. Verify that the returned Person and Artist results only contain the // 'name' property. PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result.results, SizeIs(2)); DocumentProto projected_document_one = @@ -1658,7 +1700,10 @@ TEST_F(ResultRetrieverV2ProjectionTest, ProjectionTransitivePolymorphism) { // 5. Verify that the returned Person and Musician results only contain the // 'name' property. PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result.results, SizeIs(2)); DocumentProto projected_document_one = @@ -1728,7 +1773,10 @@ TEST_F(ResultRetrieverV2ProjectionTest, // 5. Verify that the returned person document does not contain any property, // since 'emailAddress' is missing. PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result.results, SizeIs(1)); DocumentProto projected_document = DocumentBuilder() .SetKey("namespace", "uri") @@ -1803,7 +1851,10 @@ TEST_F(ResultRetrieverV2ProjectionTest, ProjectionPolymorphismMerge) { // property and the returned Artist results contain both the 'name' and // 'emailAddress' properties. PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result.results, SizeIs(2)); DocumentProto projected_document_one = @@ -1881,7 +1932,10 @@ TEST_F(ResultRetrieverV2ProjectionTest, ProjectionMultipleParentPolymorphism) { // 5. Verify that the returned document only contains the 'name' and the // 'phoneNumber' property. PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result.results, SizeIs(1)); DocumentProto projected_document = diff --git a/icing/result/result-retriever-v2_snippet_test.cc b/icing/result/result-retriever-v2_snippet_test.cc index b2ba8f7..27f16a0 100644 --- a/icing/result/result-retriever-v2_snippet_test.cc +++ b/icing/result/result-retriever-v2_snippet_test.cc @@ -242,7 +242,10 @@ TEST_F(ResultRetrieverV2SnippetTest, schema_store_.get(), SectionRestrictQueryTermsMap()), /*child_adjustment_info=*/nullptr, result_spec, *document_store_); PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result.results, SizeIs(3)); EXPECT_THAT(page_result.results.at(0).snippet(), EqualsProto(SnippetProto::default_instance())); @@ -293,7 +296,10 @@ TEST_F(ResultRetrieverV2SnippetTest, SimpleSnippeted) { /*child_adjustment_info=*/nullptr, result_spec, *document_store_); PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result.results, SizeIs(3)); EXPECT_THAT(page_result.num_results_with_snippets, Eq(3)); @@ -402,7 +408,10 @@ TEST_F(ResultRetrieverV2SnippetTest, OnlyOneDocumentSnippeted) { /*child_adjustment_info=*/nullptr, result_spec, *document_store_); PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result.results, SizeIs(3)); EXPECT_THAT(page_result.num_results_with_snippets, Eq(1)); @@ -478,7 +487,10 @@ TEST_F(ResultRetrieverV2SnippetTest, ShouldSnippetAllResults) { /*child_adjustment_info=*/nullptr, result_spec, *document_store_); PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; // num_to_snippet = 5, num_previously_returned_in = 0, // We can return 5 - 0 = 5 snippets at most. We're able to return all 3 // snippets here. @@ -537,7 +549,10 @@ TEST_F(ResultRetrieverV2SnippetTest, ShouldSnippetSomeResults) { } PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result.results, SizeIs(3)); EXPECT_THAT(page_result.results.at(0).snippet().entries(), Not(IsEmpty())); EXPECT_THAT(page_result.results.at(1).snippet().entries(), Not(IsEmpty())); @@ -594,7 +609,10 @@ TEST_F(ResultRetrieverV2SnippetTest, ShouldNotSnippetAnyResults) { // We can't return any snippets for this page. PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result.results, SizeIs(3)); EXPECT_THAT(page_result.results.at(0).snippet().entries(), IsEmpty()); EXPECT_THAT(page_result.results.at(1).snippet().entries(), IsEmpty()); @@ -654,7 +672,10 @@ TEST_F(ResultRetrieverV2SnippetTest, // We can't return any snippets for this page even though num_to_snippet > 0. PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result.results, SizeIs(3)); EXPECT_THAT(page_result.results.at(0).snippet().entries(), IsEmpty()); EXPECT_THAT(page_result.results.at(1).snippet().entries(), IsEmpty()); @@ -757,7 +778,10 @@ TEST_F(ResultRetrieverV2SnippetTest, JoinSnippeted) { parent_result_spec, *document_store_); PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result.results, SizeIs(3)); EXPECT_THAT(page_result.num_results_with_snippets, Eq(3)); @@ -985,7 +1009,10 @@ TEST_F(ResultRetrieverV2SnippetTest, ShouldSnippetAllJoinedResults) { // Only 1 parent document should be snippeted, but all of the child documents // should be snippeted. PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result.results, SizeIs(2)); // Result1: Person1 for parent and [Email1] for children. @@ -1101,7 +1128,10 @@ TEST_F(ResultRetrieverV2SnippetTest, ShouldSnippetSomeJoinedResults) { // All parents document should be snippeted. Only 2 child documents should be // snippeted. PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result.results, SizeIs(2)); // Result1: Person1 for parent and [Email1] for children. diff --git a/icing/result/result-retriever-v2_test.cc b/icing/result/result-retriever-v2_test.cc index 411562b..889dc60 100644 --- a/icing/result/result-retriever-v2_test.cc +++ b/icing/result/result-retriever-v2_test.cc @@ -86,7 +86,7 @@ class MockGroupResultLimiter : public GroupResultLimiterV2 { MOCK_METHOD(bool, ShouldBeRemoved, (const ScoredDocumentHit&, const EntryIdMap&, const DocumentStore&, std::vector<int>&, - ResultSpecProto::ResultGroupingType), + ResultSpecProto::ResultGroupingType, int64_t), (const, override)); }; @@ -310,8 +310,8 @@ TEST_F(ResultRetrieverV2Test, ShouldRetrieveSimpleResults) { *doc_store); // First page, 2 results - auto [page_result1, has_more_results1] = - result_retriever->RetrieveNextPage(result_state); + auto [page_result1, has_more_results1] = result_retriever->RetrieveNextPage( + result_state, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(page_result1.results, ElementsAre(EqualsProto(result1), EqualsProto(result2))); // num_results_with_snippets is 0 when there is no snippet. @@ -322,8 +322,8 @@ TEST_F(ResultRetrieverV2Test, ShouldRetrieveSimpleResults) { EXPECT_TRUE(has_more_results1); // Second page, 2 results - auto [page_result2, has_more_results2] = - result_retriever->RetrieveNextPage(result_state); + auto [page_result2, has_more_results2] = result_retriever->RetrieveNextPage( + result_state, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(page_result2.results, ElementsAre(EqualsProto(result3), EqualsProto(result4))); // num_results_with_snippets is 0 when there is no snippet. @@ -334,8 +334,8 @@ TEST_F(ResultRetrieverV2Test, ShouldRetrieveSimpleResults) { EXPECT_TRUE(has_more_results2); // Third page, 1 result - auto [page_result3, has_more_results3] = - result_retriever->RetrieveNextPage(result_state); + auto [page_result3, has_more_results3] = result_retriever->RetrieveNextPage( + result_state, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(page_result3.results, ElementsAre(EqualsProto(result5))); // num_results_with_snippets is 0 when there is no snippet. EXPECT_THAT(page_result3.num_results_with_snippets, Eq(0)); @@ -388,7 +388,10 @@ TEST_F(ResultRetrieverV2Test, ShouldIgnoreNonInternalErrors) { CreateResultSpec(/*num_per_page=*/3, ResultSpecProto::NAMESPACE), *doc_store); PageResult page_result1 = - result_retriever->RetrieveNextPage(result_state1).first; + result_retriever + ->RetrieveNextPage(result_state1, + fake_clock_.GetSystemTimeMilliseconds()) + .first; EXPECT_THAT(page_result1.results, ElementsAre(EqualsProto(result1), EqualsProto(result2))); @@ -406,7 +409,10 @@ TEST_F(ResultRetrieverV2Test, ShouldIgnoreNonInternalErrors) { CreateResultSpec(/*num_per_page=*/3, ResultSpecProto::NAMESPACE), *doc_store); PageResult page_result2 = - result_retriever->RetrieveNextPage(result_state2).first; + result_retriever + ->RetrieveNextPage(result_state2, + fake_clock_.GetSystemTimeMilliseconds()) + .first; EXPECT_THAT(page_result2.results, ElementsAre(EqualsProto(result1), EqualsProto(result2))); } @@ -556,8 +562,8 @@ TEST_F(ResultRetrieverV2Test, *child3->mutable_document() = email_document1; child3->set_score(3); - auto [page_result, has_more_results] = - result_retriever->RetrieveNextPage(result_state); + auto [page_result, has_more_results] = result_retriever->RetrieveNextPage( + result_state, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(page_result.results, ElementsAre(EqualsProto(result1), EqualsProto(result2))); // No more results. @@ -609,7 +615,10 @@ TEST_F(ResultRetrieverV2Test, ShouldIgnoreInternalErrors) { CreateResultSpec(/*num_per_page=*/2, ResultSpecProto::NAMESPACE), *doc_store); PageResult page_result = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; // We mocked mock_filesystem to return an internal error when retrieving doc2, // so doc2 should be skipped and doc1 should still be returned. EXPECT_THAT(page_result.results, ElementsAre(EqualsProto(result1))); @@ -659,7 +668,10 @@ TEST_F(ResultRetrieverV2Test, ShouldUpdateResultState) { // First page, 2 results PageResult page_result1 = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result1.results, SizeIs(2)); { absl_ports::shared_lock l(&result_state.mutex); @@ -673,7 +685,10 @@ TEST_F(ResultRetrieverV2Test, ShouldUpdateResultState) { // Second page, 2 results PageResult page_result2 = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result2.results, SizeIs(2)); { absl_ports::shared_lock l(&result_state.mutex); @@ -687,7 +702,10 @@ TEST_F(ResultRetrieverV2Test, ShouldUpdateResultState) { // Third page, 1 result PageResult page_result3 = - result_retriever->RetrieveNextPage(result_state).first; + result_retriever + ->RetrieveNextPage(result_state, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result3.results, SizeIs(1)); { absl_ports::shared_lock l(&result_state.mutex); @@ -769,14 +787,20 @@ TEST_F(ResultRetrieverV2Test, ShouldUpdateNumTotalHits) { // Should get 1 doc in the first page of result_state1, and num_total_hits // should be decremented by 1. PageResult page_result1 = - result_retriever->RetrieveNextPage(*result_state1).first; + result_retriever + ->RetrieveNextPage(*result_state1, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result1.results, SizeIs(1)); EXPECT_THAT(num_total_hits_, Eq(4)); // Should get 2 docs in the first page of result_state2, and num_total_hits // should be decremented by 2. PageResult page_result2 = - result_retriever->RetrieveNextPage(*result_state2).first; + result_retriever + ->RetrieveNextPage(*result_state2, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result2.results, SizeIs(2)); EXPECT_THAT(num_total_hits_, Eq(2)); @@ -784,7 +808,10 @@ TEST_F(ResultRetrieverV2Test, ShouldUpdateNumTotalHits) { // is 2, there is only 1 doc left), and num_total_hits should be decremented // by 1. PageResult page_result3 = - result_retriever->RetrieveNextPage(*result_state2).first; + result_retriever + ->RetrieveNextPage(*result_state2, + fake_clock_.GetSystemTimeMilliseconds()) + .first; ASSERT_THAT(page_result3.results, SizeIs(1)); EXPECT_THAT(num_total_hits_, Eq(1)); @@ -844,15 +871,15 @@ TEST_F(ResultRetrieverV2Test, ShouldLimitNumTotalBytesPerPage) { // First page. Only result1 should be returned, since its byte size meets // num_total_bytes_per_page_threshold and ResultRetriever should terminate // early even though # of results is still below num_per_page. - auto [page_result1, has_more_results1] = - result_retriever->RetrieveNextPage(result_state); + auto [page_result1, has_more_results1] = result_retriever->RetrieveNextPage( + result_state, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(page_result1.results, ElementsAre(EqualsProto(result1))); // Has more results. EXPECT_TRUE(has_more_results1); // Second page, result2. - auto [page_result2, has_more_results2] = - result_retriever->RetrieveNextPage(result_state); + auto [page_result2, has_more_results2] = result_retriever->RetrieveNextPage( + result_state, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(page_result2.results, ElementsAre(EqualsProto(result2))); // No more results. EXPECT_FALSE(has_more_results2); @@ -906,15 +933,15 @@ TEST_F(ResultRetrieverV2Test, // First page. Should return single result1 even though its byte size exceeds // num_total_bytes_per_page_threshold. - auto [page_result1, has_more_results1] = - result_retriever->RetrieveNextPage(result_state); + auto [page_result1, has_more_results1] = result_retriever->RetrieveNextPage( + result_state, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(page_result1.results, ElementsAre(EqualsProto(result1))); // Has more results. EXPECT_TRUE(has_more_results1); // Second page, result2. - auto [page_result2, has_more_results2] = - result_retriever->RetrieveNextPage(result_state); + auto [page_result2, has_more_results2] = result_retriever->RetrieveNextPage( + result_state, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(page_result2.results, ElementsAre(EqualsProto(result2))); // No more results. EXPECT_FALSE(has_more_results2); @@ -970,8 +997,8 @@ TEST_F(ResultRetrieverV2Test, // of results is still below num_per_page, so ResultRetriever should continue // the retrieval process and thus include result2 into this page, even though // finally total bytes of result1 + result2 exceed the threshold. - auto [page_result, has_more_results] = - result_retriever->RetrieveNextPage(result_state); + auto [page_result, has_more_results] = result_retriever->RetrieveNextPage( + result_state, fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(page_result.results, ElementsAre(EqualsProto(result1), EqualsProto(result2))); // No more results. diff --git a/icing/result/result-state-manager.cc b/icing/result/result-state-manager.cc index f2fb94f..382f7db 100644 --- a/icing/result/result-state-manager.cc +++ b/icing/result/result-state-manager.cc @@ -31,13 +31,11 @@ namespace icing { namespace lib { ResultStateManager::ResultStateManager(int max_total_hits, - const DocumentStore& document_store, - const Clock* clock) + const DocumentStore& document_store) : document_store_(document_store), max_total_hits_(max_total_hits), num_total_hits_(0), - random_generator_(GetSteadyTimeNanoseconds()), - clock_(*clock) {} + random_generator_(GetSteadyTimeNanoseconds()) {} libtextclassifier3::StatusOr<std::pair<uint64_t, PageResult>> ResultStateManager::CacheAndRetrieveFirstPage( @@ -45,7 +43,7 @@ ResultStateManager::CacheAndRetrieveFirstPage( std::unique_ptr<ResultAdjustmentInfo> parent_adjustment_info, std::unique_ptr<ResultAdjustmentInfo> child_adjustment_info, const ResultSpecProto& result_spec, const DocumentStore& document_store, - const ResultRetrieverV2& result_retriever) { + const ResultRetrieverV2& result_retriever, int64_t current_time_ms) { if (ranker == nullptr) { return absl_ports::InvalidArgumentError("Should not provide null ranker"); } @@ -59,7 +57,7 @@ ResultStateManager::CacheAndRetrieveFirstPage( // Retrieve docs outside of ResultStateManager critical section. // Will enter ResultState critical section inside ResultRetriever. auto [page_result, has_more_results] = - result_retriever.RetrieveNextPage(*result_state); + result_retriever.RetrieveNextPage(*result_state, current_time_ms); if (!has_more_results) { // No more pages, won't store ResultState, returns directly return std::make_pair(kInvalidNextPageToken, std::move(page_result)); @@ -86,37 +84,40 @@ ResultStateManager::CacheAndRetrieveFirstPage( absl_ports::unique_lock l(&mutex_); // Remove expired result states first. - InternalInvalidateExpiredResultStates(kDefaultResultStateTtlInMs); + InternalInvalidateExpiredResultStates(kDefaultResultStateTtlInMs, + current_time_ms); // Remove states to make room for this new state. RemoveStatesIfNeeded(num_hits_to_add); // Generate a new unique token and add it into result_state_map_. - next_page_token = Add(std::move(result_state)); + next_page_token = Add(std::move(result_state), current_time_ms); } return std::make_pair(next_page_token, std::move(page_result)); } -uint64_t ResultStateManager::Add(std::shared_ptr<ResultStateV2> result_state) { +uint64_t ResultStateManager::Add(std::shared_ptr<ResultStateV2> result_state, + int64_t current_time_ms) { uint64_t new_token = GetUniqueToken(); result_state_map_.emplace(new_token, std::move(result_state)); // Tracks the insertion order - token_queue_.push( - std::make_pair(new_token, clock_.GetSystemTimeMilliseconds())); + token_queue_.push(std::make_pair(new_token, current_time_ms)); return new_token; } libtextclassifier3::StatusOr<std::pair<uint64_t, PageResult>> ResultStateManager::GetNextPage(uint64_t next_page_token, - const ResultRetrieverV2& result_retriever) { + const ResultRetrieverV2& result_retriever, + int64_t current_time_ms) { std::shared_ptr<ResultStateV2> result_state = nullptr; { // ResultStateManager critical section absl_ports::unique_lock l(&mutex_); // Remove expired result states before fetching - InternalInvalidateExpiredResultStates(kDefaultResultStateTtlInMs); + InternalInvalidateExpiredResultStates(kDefaultResultStateTtlInMs, + current_time_ms); const auto& state_iterator = result_state_map_.find(next_page_token); if (state_iterator == result_state_map_.end()) { @@ -128,7 +129,7 @@ ResultStateManager::GetNextPage(uint64_t next_page_token, // Retrieve docs outside of ResultStateManager critical section. // Will enter ResultState critical section inside ResultRetriever. auto [page_result, has_more_results] = - result_retriever.RetrieveNextPage(*result_state); + result_retriever.RetrieveNextPage(*result_state, current_time_ms); if (!has_more_results) { { @@ -233,10 +234,9 @@ void ResultStateManager::InternalInvalidateResultState(uint64_t token) { } void ResultStateManager::InternalInvalidateExpiredResultStates( - int64_t result_state_ttl) { - int64_t current_time = clock_.GetSystemTimeMilliseconds(); + int64_t result_state_ttl, int64_t current_time_ms) { while (!token_queue_.empty() && - current_time - token_queue_.front().second >= result_state_ttl) { + current_time_ms - token_queue_.front().second >= result_state_ttl) { auto itr = result_state_map_.find(token_queue_.front().first); if (itr != result_state_map_.end()) { // We don't have to decrement num_total_hits_ here, since erasing the diff --git a/icing/result/result-state-manager.h b/icing/result/result-state-manager.h index 400187f..a64ae2c 100644 --- a/icing/result/result-state-manager.h +++ b/icing/result/result-state-manager.h @@ -47,8 +47,7 @@ inline constexpr int64_t kDefaultResultStateTtlInMs = 1LL * 60 * 60 * 1000; class ResultStateManager { public: explicit ResultStateManager(int max_total_hits, - const DocumentStore& document_store, - const Clock* clock); + const DocumentStore& document_store); ResultStateManager(const ResultStateManager&) = delete; ResultStateManager& operator=(const ResultStateManager&) = delete; @@ -78,7 +77,8 @@ class ResultStateManager { std::unique_ptr<ResultAdjustmentInfo> parent_adjustment_info, std::unique_ptr<ResultAdjustmentInfo> child_adjustment_info, const ResultSpecProto& result_spec, const DocumentStore& document_store, - const ResultRetrieverV2& result_retriever) ICING_LOCKS_EXCLUDED(mutex_); + const ResultRetrieverV2& result_retriever, int64_t current_time_ms) + ICING_LOCKS_EXCLUDED(mutex_); // Retrieves and returns PageResult for the next page. // The returned results won't exist in ResultStateManager anymore. If the @@ -93,8 +93,8 @@ class ResultStateManager { // A token and PageResult wrapped by std::pair on success // NOT_FOUND if failed to find any more results libtextclassifier3::StatusOr<std::pair<uint64_t, PageResult>> GetNextPage( - uint64_t next_page_token, const ResultRetrieverV2& result_retriever) - ICING_LOCKS_EXCLUDED(mutex_); + uint64_t next_page_token, const ResultRetrieverV2& result_retriever, + int64_t current_time_ms) ICING_LOCKS_EXCLUDED(mutex_); // Invalidates the result state associated with the given next-page token. void InvalidateResultState(uint64_t next_page_token) @@ -136,15 +136,13 @@ class ResultStateManager { // A random 64-bit number generator std::mt19937_64 random_generator_ ICING_GUARDED_BY(mutex_); - const Clock& clock_; // Does not own. - // Puts a new result state into the internal storage and returns a next-page // token associated with it. The token is guaranteed to be unique among all // currently valid tokens. When the maximum number of result states is // reached, the oldest / firstly added result state will be removed to make // room for the new state. - uint64_t Add(std::shared_ptr<ResultStateV2> result_state) - ICING_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + uint64_t Add(std::shared_ptr<ResultStateV2> result_state, + int64_t current_time_ms) ICING_EXCLUSIVE_LOCKS_REQUIRED(mutex_); // Helper method to generate a next-page token that is unique among all // existing tokens in token_queue_. @@ -171,7 +169,8 @@ class ResultStateManager { // Internal method to invalidate and remove expired result states / tokens // currently in ResultStateManager that were created before // current_time - result_state_ttl. - void InternalInvalidateExpiredResultStates(int64_t result_state_ttl) + void InternalInvalidateExpiredResultStates(int64_t result_state_ttl, + int64_t current_time_ms) ICING_EXCLUSIVE_LOCKS_REQUIRED(mutex_); }; diff --git a/icing/result/result-state-manager_test.cc b/icing/result/result-state-manager_test.cc index ce4589b..38d67e8 100644 --- a/icing/result/result-state-manager_test.cc +++ b/icing/result/result-state-manager_test.cc @@ -198,8 +198,7 @@ TEST_F(ResultStateManagerTest, ShouldCacheAndRetrieveFirstPageOnePage) { std::move(scored_document_hits), /*is_descending=*/true); ResultStateManager result_state_manager( - /*max_total_hits=*/std::numeric_limits<int>::max(), document_store(), - clock()); + /*max_total_hits=*/std::numeric_limits<int>::max(), document_store()); ICING_ASSERT_OK_AND_ASSIGN( PageResultInfo page_result_info, @@ -207,7 +206,8 @@ TEST_F(ResultStateManagerTest, ShouldCacheAndRetrieveFirstPageOnePage) { std::move(ranker), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/10, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); EXPECT_THAT(page_result_info.first, Eq(kInvalidNextPageToken)); @@ -243,8 +243,7 @@ TEST_F(ResultStateManagerTest, ShouldCacheAndRetrieveFirstPageMultiplePages) { std::move(scored_document_hits), /*is_descending=*/true); ResultStateManager result_state_manager( - /*max_total_hits=*/std::numeric_limits<int>::max(), document_store(), - clock()); + /*max_total_hits=*/std::numeric_limits<int>::max(), document_store()); // First page, 2 results ICING_ASSERT_OK_AND_ASSIGN( @@ -253,7 +252,8 @@ TEST_F(ResultStateManagerTest, ShouldCacheAndRetrieveFirstPageMultiplePages) { std::move(ranker), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/2, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); EXPECT_THAT(page_result_info1.first, Not(Eq(kInvalidNextPageToken))); ASSERT_THAT(page_result_info1.second.results, SizeIs(2)); EXPECT_THAT(page_result_info1.second.results.at(0).document(), @@ -266,7 +266,8 @@ TEST_F(ResultStateManagerTest, ShouldCacheAndRetrieveFirstPageMultiplePages) { // Second page, 2 results ICING_ASSERT_OK_AND_ASSIGN( PageResultInfo page_result_info2, - result_state_manager.GetNextPage(next_page_token, result_retriever())); + result_state_manager.GetNextPage(next_page_token, result_retriever(), + clock()->GetSystemTimeMilliseconds())); EXPECT_THAT(page_result_info2.first, Eq(next_page_token)); ASSERT_THAT(page_result_info2.second.results, SizeIs(2)); EXPECT_THAT(page_result_info2.second.results.at(0).document(), @@ -277,7 +278,8 @@ TEST_F(ResultStateManagerTest, ShouldCacheAndRetrieveFirstPageMultiplePages) { // Third page, 1 result ICING_ASSERT_OK_AND_ASSIGN( PageResultInfo page_result_info3, - result_state_manager.GetNextPage(next_page_token, result_retriever())); + result_state_manager.GetNextPage(next_page_token, result_retriever(), + clock()->GetSystemTimeMilliseconds())); EXPECT_THAT(page_result_info3.first, Eq(kInvalidNextPageToken)); ASSERT_THAT(page_result_info3.second.results, SizeIs(1)); EXPECT_THAT(page_result_info3.second.results.at(0).document(), @@ -285,28 +287,28 @@ TEST_F(ResultStateManagerTest, ShouldCacheAndRetrieveFirstPageMultiplePages) { // No results EXPECT_THAT( - result_state_manager.GetNextPage(next_page_token, result_retriever()), + result_state_manager.GetNextPage(next_page_token, result_retriever(), + clock()->GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::NOT_FOUND)); } TEST_F(ResultStateManagerTest, NullRankerShouldReturnError) { ResultStateManager result_state_manager( - /*max_total_hits=*/std::numeric_limits<int>::max(), document_store(), - clock()); + /*max_total_hits=*/std::numeric_limits<int>::max(), document_store()); EXPECT_THAT( result_state_manager.CacheAndRetrieveFirstPage( /*ranker=*/nullptr, /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever()), + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); } TEST_F(ResultStateManagerTest, EmptyRankerShouldReturnEmptyFirstPage) { ResultStateManager result_state_manager( - /*max_total_hits=*/std::numeric_limits<int>::max(), document_store(), - clock()); + /*max_total_hits=*/std::numeric_limits<int>::max(), document_store()); ICING_ASSERT_OK_AND_ASSIGN( PageResultInfo page_result_info, result_state_manager.CacheAndRetrieveFirstPage( @@ -315,7 +317,8 @@ TEST_F(ResultStateManagerTest, EmptyRankerShouldReturnEmptyFirstPage) { std::vector<ScoredDocumentHit>(), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); EXPECT_THAT(page_result_info.first, Eq(kInvalidNextPageToken)); EXPECT_THAT(page_result_info.second.results, IsEmpty()); @@ -331,8 +334,7 @@ TEST_F(ResultStateManagerTest, ShouldAllowEmptyFirstPage) { {document_id2, kSectionIdMaskNone, /*score=*/1}}; ResultStateManager result_state_manager( - /*max_total_hits=*/std::numeric_limits<int>::max(), document_store(), - clock()); + /*max_total_hits=*/std::numeric_limits<int>::max(), document_store()); // Create a ResultSpec that limits "namespace" to 0 results. ResultSpecProto result_spec = @@ -352,7 +354,8 @@ TEST_F(ResultStateManagerTest, ShouldAllowEmptyFirstPage) { PriorityQueueScoredDocumentHitsRanker<ScoredDocumentHit>>( std::move(scored_document_hits), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, - result_spec, document_store(), result_retriever())); + result_spec, document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); // If the first page has no result, then it should be the last page. EXPECT_THAT(page_result_info.first, Eq(kInvalidNextPageToken)); EXPECT_THAT(page_result_info.second.results, IsEmpty()); @@ -374,8 +377,7 @@ TEST_F(ResultStateManagerTest, ShouldAllowEmptyLastPage) { {document_id4, kSectionIdMaskNone, /*score=*/1}}; ResultStateManager result_state_manager( - /*max_total_hits=*/std::numeric_limits<int>::max(), document_store(), - clock()); + /*max_total_hits=*/std::numeric_limits<int>::max(), document_store()); // Create a ResultSpec that limits "namespace" to 2 results. ResultSpecProto result_spec = @@ -395,7 +397,8 @@ TEST_F(ResultStateManagerTest, ShouldAllowEmptyLastPage) { PriorityQueueScoredDocumentHitsRanker<ScoredDocumentHit>>( std::move(scored_document_hits), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, - result_spec, document_store(), result_retriever())); + result_spec, document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); EXPECT_THAT(page_result_info1.first, Not(Eq(kInvalidNextPageToken))); ASSERT_THAT(page_result_info1.second.results, SizeIs(2)); EXPECT_THAT(page_result_info1.second.results.at(0).document(), @@ -409,7 +412,8 @@ TEST_F(ResultStateManagerTest, ShouldAllowEmptyLastPage) { // limiter, so we should get an empty page. ICING_ASSERT_OK_AND_ASSIGN( PageResultInfo page_result_info2, - result_state_manager.GetNextPage(next_page_token, result_retriever())); + result_state_manager.GetNextPage(next_page_token, result_retriever(), + clock()->GetSystemTimeMilliseconds())); EXPECT_THAT(page_result_info2.first, Eq(kInvalidNextPageToken)); EXPECT_THAT(page_result_info2.second.results, IsEmpty()); } @@ -422,8 +426,7 @@ TEST_F(ResultStateManagerTest, {/*document_id=*/3, /*document_id=*/4, /*document_id=*/5}); ResultStateManager result_state_manager( - /*max_total_hits=*/std::numeric_limits<int>::max(), document_store(), - clock()); + /*max_total_hits=*/std::numeric_limits<int>::max(), document_store()); SectionRestrictQueryTermsMap query_terms; SearchSpecProto search_spec; @@ -444,7 +447,7 @@ TEST_F(ResultStateManagerTest, result_spec, &schema_store(), query_terms), /*child_adjustment_info=*/nullptr, result_spec, document_store(), - result_retriever())); + result_retriever(), clock()->GetSystemTimeMilliseconds())); ASSERT_THAT(page_result_info1.first, Not(Eq(kInvalidNextPageToken))); // Set time as 1hr1s and add state 2. @@ -460,7 +463,7 @@ TEST_F(ResultStateManagerTest, result_spec, &schema_store(), query_terms), /*child_adjustment_info=*/nullptr, result_spec, document_store(), - result_retriever())); + result_retriever(), clock()->GetSystemTimeMilliseconds())); // Calling CacheAndRetrieveFirstPage() on state 2 should invalidate the // expired state 1 internally. @@ -470,8 +473,9 @@ TEST_F(ResultStateManagerTest, // CacheAndRetrieveFirstPage() instead of the following GetNextPage(). clock()->SetSystemTimeMilliseconds(1000); // page_result_info1's token (page_result_info1.first) shouldn't be found. - EXPECT_THAT(result_state_manager.GetNextPage(page_result_info1.first, - result_retriever()), + EXPECT_THAT(result_state_manager.GetNextPage( + page_result_info1.first, result_retriever(), + clock()->GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::NOT_FOUND)); } @@ -483,8 +487,7 @@ TEST_F(ResultStateManagerTest, {/*document_id=*/3, /*document_id=*/4, /*document_id=*/5}); ResultStateManager result_state_manager( - /*max_total_hits=*/std::numeric_limits<int>::max(), document_store(), - clock()); + /*max_total_hits=*/std::numeric_limits<int>::max(), document_store()); // Set time as 1s and add state 1. clock()->SetSystemTimeMilliseconds(1000); @@ -496,7 +499,8 @@ TEST_F(ResultStateManagerTest, std::move(scored_document_hits1), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); ASSERT_THAT(page_result_info1.first, Not(Eq(kInvalidNextPageToken))); // Set time as 2s and add state 2. @@ -509,7 +513,8 @@ TEST_F(ResultStateManagerTest, std::move(scored_document_hits2), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); ASSERT_THAT(page_result_info2.first, Not(Eq(kInvalidNextPageToken))); // 1. Set time as 1hr1s. @@ -520,14 +525,16 @@ TEST_F(ResultStateManagerTest, // page_result_info2's token (page_result_info2.first) should be found ICING_ASSERT_OK_AND_ASSIGN(page_result_info2, result_state_manager.GetNextPage( - page_result_info2.first, result_retriever())); + page_result_info2.first, result_retriever(), + clock()->GetSystemTimeMilliseconds())); // We test the behavior by setting time back to 2s, to make sure the // invalidation of state 1 was done by the previous GetNextPage() instead of // the following GetNextPage(). clock()->SetSystemTimeMilliseconds(2000); // page_result_info1's token (page_result_info1.first) shouldn't be found. - EXPECT_THAT(result_state_manager.GetNextPage(page_result_info1.first, - result_retriever()), + EXPECT_THAT(result_state_manager.GetNextPage( + page_result_info1.first, result_retriever(), + clock()->GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::NOT_FOUND)); } @@ -539,8 +546,7 @@ TEST_F(ResultStateManagerTest, {/*document_id=*/3, /*document_id=*/4, /*document_id=*/5}); ResultStateManager result_state_manager( - /*max_total_hits=*/std::numeric_limits<int>::max(), document_store(), - clock()); + /*max_total_hits=*/std::numeric_limits<int>::max(), document_store()); // Set time as 1s and add state. clock()->SetSystemTimeMilliseconds(1000); @@ -552,15 +558,17 @@ TEST_F(ResultStateManagerTest, std::move(scored_document_hits1), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); ASSERT_THAT(page_result_info.first, Not(Eq(kInvalidNextPageToken))); // 1. Set time as 1hr1s. // 2. Then calling GetNextPage() on the state shouldn't get anything. clock()->SetSystemTimeMilliseconds(kDefaultResultStateTtlInMs + 1000); // page_result_info's token (page_result_info.first) shouldn't be found. - EXPECT_THAT(result_state_manager.GetNextPage(page_result_info.first, - result_retriever()), + EXPECT_THAT(result_state_manager.GetNextPage( + page_result_info.first, result_retriever(), + clock()->GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::NOT_FOUND)); } @@ -587,8 +595,7 @@ TEST_F(ResultStateManagerTest, ShouldInvalidateOneToken) { {document_id6, kSectionIdMaskNone, /*score=*/1}}; ResultStateManager result_state_manager( - /*max_total_hits=*/std::numeric_limits<int>::max(), document_store(), - clock()); + /*max_total_hits=*/std::numeric_limits<int>::max(), document_store()); ICING_ASSERT_OK_AND_ASSIGN( PageResultInfo page_result_info1, @@ -598,7 +605,8 @@ TEST_F(ResultStateManagerTest, ShouldInvalidateOneToken) { std::move(scored_document_hits1), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); ICING_ASSERT_OK_AND_ASSIGN( PageResultInfo page_result_info2, @@ -608,20 +616,23 @@ TEST_F(ResultStateManagerTest, ShouldInvalidateOneToken) { std::move(scored_document_hits2), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); // Invalidate first result state by the token. result_state_manager.InvalidateResultState(page_result_info1.first); // page_result_info1's token (page_result_info1.first) shouldn't be found - EXPECT_THAT(result_state_manager.GetNextPage(page_result_info1.first, - result_retriever()), + EXPECT_THAT(result_state_manager.GetNextPage( + page_result_info1.first, result_retriever(), + clock()->GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::NOT_FOUND)); // page_result_info2's token (page_result_info2.first) should still exist ICING_ASSERT_OK_AND_ASSIGN(page_result_info2, result_state_manager.GetNextPage( - page_result_info2.first, result_retriever())); + page_result_info2.first, result_retriever(), + clock()->GetSystemTimeMilliseconds())); // Should get docs. ASSERT_THAT(page_result_info2.second.results, SizeIs(1)); EXPECT_THAT(page_result_info2.second.results.at(0).document(), @@ -635,8 +646,7 @@ TEST_F(ResultStateManagerTest, ShouldInvalidateAllTokens) { {/*document_id=*/3, /*document_id=*/4, /*document_id=*/5}); ResultStateManager result_state_manager( - /*max_total_hits=*/std::numeric_limits<int>::max(), document_store(), - clock()); + /*max_total_hits=*/std::numeric_limits<int>::max(), document_store()); ICING_ASSERT_OK_AND_ASSIGN( PageResultInfo page_result_info1, @@ -646,7 +656,8 @@ TEST_F(ResultStateManagerTest, ShouldInvalidateAllTokens) { std::move(scored_document_hits1), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); ICING_ASSERT_OK_AND_ASSIGN( PageResultInfo page_result_info2, @@ -656,18 +667,21 @@ TEST_F(ResultStateManagerTest, ShouldInvalidateAllTokens) { std::move(scored_document_hits2), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); result_state_manager.InvalidateAllResultStates(); // page_result_info1's token (page_result_info1.first) shouldn't be found - EXPECT_THAT(result_state_manager.GetNextPage(page_result_info1.first, - result_retriever()), + EXPECT_THAT(result_state_manager.GetNextPage( + page_result_info1.first, result_retriever(), + clock()->GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::NOT_FOUND)); // page_result_info2's token (page_result_info2.first) shouldn't be found - EXPECT_THAT(result_state_manager.GetNextPage(page_result_info2.first, - result_retriever()), + EXPECT_THAT(result_state_manager.GetNextPage( + page_result_info2.first, result_retriever(), + clock()->GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::NOT_FOUND)); } @@ -680,7 +694,7 @@ TEST_F(ResultStateManagerTest, ShouldRemoveOldestResultState) { AddScoredDocuments({/*document_id=*/4, /*document_id=*/5}); ResultStateManager result_state_manager(/*max_total_hits=*/2, - document_store(), clock()); + document_store()); ICING_ASSERT_OK_AND_ASSIGN( PageResultInfo page_result_info1, @@ -690,7 +704,8 @@ TEST_F(ResultStateManagerTest, ShouldRemoveOldestResultState) { std::move(scored_document_hits1), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); ICING_ASSERT_OK_AND_ASSIGN( PageResultInfo page_result_info2, @@ -700,7 +715,8 @@ TEST_F(ResultStateManagerTest, ShouldRemoveOldestResultState) { std::move(scored_document_hits2), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); // Adding state 3 should cause state 1 to be removed. ICING_ASSERT_OK_AND_ASSIGN( @@ -711,22 +727,26 @@ TEST_F(ResultStateManagerTest, ShouldRemoveOldestResultState) { std::move(scored_document_hits3), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); - EXPECT_THAT(result_state_manager.GetNextPage(page_result_info1.first, - result_retriever()), + EXPECT_THAT(result_state_manager.GetNextPage( + page_result_info1.first, result_retriever(), + clock()->GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::NOT_FOUND)); ICING_ASSERT_OK_AND_ASSIGN(page_result_info2, result_state_manager.GetNextPage( - page_result_info2.first, result_retriever())); + page_result_info2.first, result_retriever(), + clock()->GetSystemTimeMilliseconds())); ASSERT_THAT(page_result_info2.second.results, SizeIs(1)); EXPECT_THAT(page_result_info2.second.results.at(0).document(), EqualsProto(document_protos2.at(1))); ICING_ASSERT_OK_AND_ASSIGN(page_result_info3, result_state_manager.GetNextPage( - page_result_info3.first, result_retriever())); + page_result_info3.first, result_retriever(), + clock()->GetSystemTimeMilliseconds())); ASSERT_THAT(page_result_info3.second.results, SizeIs(1)); EXPECT_THAT(page_result_info3.second.results.at(0).document(), EqualsProto(document_protos3.at(1))); @@ -747,7 +767,7 @@ TEST_F(ResultStateManagerTest, // result set of 2 hits. So each result will take up one hit of our three hit // budget. ResultStateManager result_state_manager(/*max_total_hits=*/3, - document_store(), clock()); + document_store()); ICING_ASSERT_OK_AND_ASSIGN( PageResultInfo page_result_info1, @@ -757,7 +777,8 @@ TEST_F(ResultStateManagerTest, std::move(scored_document_hits1), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); ICING_ASSERT_OK_AND_ASSIGN( PageResultInfo page_result_info2, @@ -767,7 +788,8 @@ TEST_F(ResultStateManagerTest, std::move(scored_document_hits2), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); ICING_ASSERT_OK_AND_ASSIGN( PageResultInfo page_result_info3, @@ -777,7 +799,8 @@ TEST_F(ResultStateManagerTest, std::move(scored_document_hits3), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); // Invalidates state 2, so that the number of hits current cached should be // decremented to 2. @@ -796,29 +819,34 @@ TEST_F(ResultStateManagerTest, std::move(scored_document_hits4), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); ICING_ASSERT_OK_AND_ASSIGN(page_result_info1, result_state_manager.GetNextPage( - page_result_info1.first, result_retriever())); + page_result_info1.first, result_retriever(), + clock()->GetSystemTimeMilliseconds())); ASSERT_THAT(page_result_info1.second.results, SizeIs(1)); EXPECT_THAT(page_result_info1.second.results.at(0).document(), EqualsProto(document_protos1.at(1))); - EXPECT_THAT(result_state_manager.GetNextPage(page_result_info2.first, - result_retriever()), + EXPECT_THAT(result_state_manager.GetNextPage( + page_result_info2.first, result_retriever(), + clock()->GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::NOT_FOUND)); ICING_ASSERT_OK_AND_ASSIGN(page_result_info3, result_state_manager.GetNextPage( - page_result_info3.first, result_retriever())); + page_result_info3.first, result_retriever(), + clock()->GetSystemTimeMilliseconds())); ASSERT_THAT(page_result_info3.second.results, SizeIs(1)); EXPECT_THAT(page_result_info3.second.results.at(0).document(), EqualsProto(document_protos3.at(1))); ICING_ASSERT_OK_AND_ASSIGN(page_result_info4, result_state_manager.GetNextPage( - page_result_info4.first, result_retriever())); + page_result_info4.first, result_retriever(), + clock()->GetSystemTimeMilliseconds())); ASSERT_THAT(page_result_info4.second.results, SizeIs(1)); EXPECT_THAT(page_result_info4.second.results.at(0).document(), EqualsProto(document_protos4.at(1))); @@ -839,7 +867,7 @@ TEST_F(ResultStateManagerTest, // result set of 2 hits. So each result will take up one hit of our three hit // budget. ResultStateManager result_state_manager(/*max_total_hits=*/3, - document_store(), clock()); + document_store()); ICING_ASSERT_OK_AND_ASSIGN( PageResultInfo page_result_info1, @@ -849,7 +877,8 @@ TEST_F(ResultStateManagerTest, std::move(scored_document_hits1), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); ICING_ASSERT_OK_AND_ASSIGN( PageResultInfo page_result_info2, @@ -859,7 +888,8 @@ TEST_F(ResultStateManagerTest, std::move(scored_document_hits2), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); ICING_ASSERT_OK_AND_ASSIGN( PageResultInfo page_result_info3, @@ -869,7 +899,8 @@ TEST_F(ResultStateManagerTest, std::move(scored_document_hits3), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); // Invalidates all states so that the current hit count will be 0. result_state_manager.InvalidateAllResultStates(); @@ -892,7 +923,8 @@ TEST_F(ResultStateManagerTest, std::move(scored_document_hits4), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); ICING_ASSERT_OK_AND_ASSIGN( PageResultInfo page_result_info5, @@ -902,7 +934,8 @@ TEST_F(ResultStateManagerTest, std::move(scored_document_hits5), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); ICING_ASSERT_OK_AND_ASSIGN( PageResultInfo page_result_info6, @@ -912,37 +945,44 @@ TEST_F(ResultStateManagerTest, std::move(scored_document_hits6), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); - EXPECT_THAT(result_state_manager.GetNextPage(page_result_info1.first, - result_retriever()), + EXPECT_THAT(result_state_manager.GetNextPage( + page_result_info1.first, result_retriever(), + clock()->GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::NOT_FOUND)); - EXPECT_THAT(result_state_manager.GetNextPage(page_result_info2.first, - result_retriever()), + EXPECT_THAT(result_state_manager.GetNextPage( + page_result_info2.first, result_retriever(), + clock()->GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::NOT_FOUND)); - EXPECT_THAT(result_state_manager.GetNextPage(page_result_info3.first, - result_retriever()), + EXPECT_THAT(result_state_manager.GetNextPage( + page_result_info3.first, result_retriever(), + clock()->GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::NOT_FOUND)); ICING_ASSERT_OK_AND_ASSIGN(page_result_info4, result_state_manager.GetNextPage( - page_result_info4.first, result_retriever())); + page_result_info4.first, result_retriever(), + clock()->GetSystemTimeMilliseconds())); ASSERT_THAT(page_result_info4.second.results, SizeIs(1)); EXPECT_THAT(page_result_info4.second.results.at(0).document(), EqualsProto(document_protos4.at(1))); ICING_ASSERT_OK_AND_ASSIGN(page_result_info5, result_state_manager.GetNextPage( - page_result_info5.first, result_retriever())); + page_result_info5.first, result_retriever(), + clock()->GetSystemTimeMilliseconds())); ASSERT_THAT(page_result_info5.second.results, SizeIs(1)); EXPECT_THAT(page_result_info5.second.results.at(0).document(), EqualsProto(document_protos5.at(1))); ICING_ASSERT_OK_AND_ASSIGN(page_result_info6, result_state_manager.GetNextPage( - page_result_info6.first, result_retriever())); + page_result_info6.first, result_retriever(), + clock()->GetSystemTimeMilliseconds())); ASSERT_THAT(page_result_info6.second.results, SizeIs(1)); EXPECT_THAT(page_result_info6.second.results.at(0).document(), EqualsProto(document_protos6.at(1))); @@ -964,7 +1004,7 @@ TEST_F( // result set of 2 hits. So each result will take up one hit of our three hit // budget. ResultStateManager result_state_manager(/*max_total_hits=*/3, - document_store(), clock()); + document_store()); ICING_ASSERT_OK_AND_ASSIGN( PageResultInfo page_result_info1, @@ -974,7 +1014,8 @@ TEST_F( std::move(scored_document_hits1), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); ICING_ASSERT_OK_AND_ASSIGN( PageResultInfo page_result_info2, @@ -984,7 +1025,8 @@ TEST_F( std::move(scored_document_hits2), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); ICING_ASSERT_OK_AND_ASSIGN( PageResultInfo page_result_info3, @@ -994,7 +1036,8 @@ TEST_F( std::move(scored_document_hits3), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); // Invalidates state 2, so that the number of hits current cached should be // decremented to 2. @@ -1013,7 +1056,8 @@ TEST_F( std::move(scored_document_hits4), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); // If invalidating result state 2 correctly decremented the current hit count // to 2 and adding state 4 correctly incremented it to 3, then adding this @@ -1028,33 +1072,39 @@ TEST_F( std::move(scored_document_hits5), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); - EXPECT_THAT(result_state_manager.GetNextPage(page_result_info1.first, - result_retriever()), + EXPECT_THAT(result_state_manager.GetNextPage( + page_result_info1.first, result_retriever(), + clock()->GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::NOT_FOUND)); - EXPECT_THAT(result_state_manager.GetNextPage(page_result_info2.first, - result_retriever()), + EXPECT_THAT(result_state_manager.GetNextPage( + page_result_info2.first, result_retriever(), + clock()->GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::NOT_FOUND)); ICING_ASSERT_OK_AND_ASSIGN(page_result_info3, result_state_manager.GetNextPage( - page_result_info3.first, result_retriever())); + page_result_info3.first, result_retriever(), + clock()->GetSystemTimeMilliseconds())); ASSERT_THAT(page_result_info3.second.results, SizeIs(1)); EXPECT_THAT(page_result_info3.second.results.at(0).document(), EqualsProto(document_protos3.at(1))); ICING_ASSERT_OK_AND_ASSIGN(page_result_info4, result_state_manager.GetNextPage( - page_result_info4.first, result_retriever())); + page_result_info4.first, result_retriever(), + clock()->GetSystemTimeMilliseconds())); ASSERT_THAT(page_result_info4.second.results, SizeIs(1)); EXPECT_THAT(page_result_info4.second.results.at(0).document(), EqualsProto(document_protos4.at(1))); ICING_ASSERT_OK_AND_ASSIGN(page_result_info5, result_state_manager.GetNextPage( - page_result_info5.first, result_retriever())); + page_result_info5.first, result_retriever(), + clock()->GetSystemTimeMilliseconds())); ASSERT_THAT(page_result_info5.second.results, SizeIs(1)); EXPECT_THAT(page_result_info5.second.results.at(0).document(), EqualsProto(document_protos5.at(1))); @@ -1074,7 +1124,7 @@ TEST_F(ResultStateManagerTest, GetNextPageShouldDecreaseCurrentHitsCount) { // result set of 2 hits. So each result will take up one hit of our three hit // budget. ResultStateManager result_state_manager(/*max_total_hits=*/3, - document_store(), clock()); + document_store()); ICING_ASSERT_OK_AND_ASSIGN( PageResultInfo page_result_info1, @@ -1084,7 +1134,8 @@ TEST_F(ResultStateManagerTest, GetNextPageShouldDecreaseCurrentHitsCount) { std::move(scored_document_hits1), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); ICING_ASSERT_OK_AND_ASSIGN( PageResultInfo page_result_info2, @@ -1094,7 +1145,8 @@ TEST_F(ResultStateManagerTest, GetNextPageShouldDecreaseCurrentHitsCount) { std::move(scored_document_hits2), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); ICING_ASSERT_OK_AND_ASSIGN( PageResultInfo page_result_info3, @@ -1104,13 +1156,15 @@ TEST_F(ResultStateManagerTest, GetNextPageShouldDecreaseCurrentHitsCount) { std::move(scored_document_hits3), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); // GetNextPage for result state 1 should return its result and decrement the // number of cached hits to 2. ICING_ASSERT_OK_AND_ASSIGN(page_result_info1, result_state_manager.GetNextPage( - page_result_info1.first, result_retriever())); + page_result_info1.first, result_retriever(), + clock()->GetSystemTimeMilliseconds())); ASSERT_THAT(page_result_info1.second.results, SizeIs(1)); EXPECT_THAT(page_result_info1.second.results.at(0).document(), EqualsProto(document_protos1.at(1))); @@ -1128,29 +1182,34 @@ TEST_F(ResultStateManagerTest, GetNextPageShouldDecreaseCurrentHitsCount) { std::move(scored_document_hits4), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); - EXPECT_THAT(result_state_manager.GetNextPage(page_result_info1.first, - result_retriever()), + EXPECT_THAT(result_state_manager.GetNextPage( + page_result_info1.first, result_retriever(), + clock()->GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::NOT_FOUND)); ICING_ASSERT_OK_AND_ASSIGN(page_result_info2, result_state_manager.GetNextPage( - page_result_info2.first, result_retriever())); + page_result_info2.first, result_retriever(), + clock()->GetSystemTimeMilliseconds())); ASSERT_THAT(page_result_info2.second.results, SizeIs(1)); EXPECT_THAT(page_result_info2.second.results.at(0).document(), EqualsProto(document_protos2.at(1))); ICING_ASSERT_OK_AND_ASSIGN(page_result_info3, result_state_manager.GetNextPage( - page_result_info3.first, result_retriever())); + page_result_info3.first, result_retriever(), + clock()->GetSystemTimeMilliseconds())); ASSERT_THAT(page_result_info3.second.results, SizeIs(1)); EXPECT_THAT(page_result_info3.second.results.at(0).document(), EqualsProto(document_protos3.at(1))); ICING_ASSERT_OK_AND_ASSIGN(page_result_info4, result_state_manager.GetNextPage( - page_result_info4.first, result_retriever())); + page_result_info4.first, result_retriever(), + clock()->GetSystemTimeMilliseconds())); ASSERT_THAT(page_result_info4.second.results, SizeIs(1)); EXPECT_THAT(page_result_info4.second.results.at(0).document(), EqualsProto(document_protos4.at(1))); @@ -1171,7 +1230,7 @@ TEST_F(ResultStateManagerTest, // result set of 2 hits. So each result will take up one hit of our three hit // budget. ResultStateManager result_state_manager(/*max_total_hits=*/3, - document_store(), clock()); + document_store()); ICING_ASSERT_OK_AND_ASSIGN( PageResultInfo page_result_info1, @@ -1181,7 +1240,8 @@ TEST_F(ResultStateManagerTest, std::move(scored_document_hits1), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); ICING_ASSERT_OK_AND_ASSIGN( PageResultInfo page_result_info2, @@ -1191,7 +1251,8 @@ TEST_F(ResultStateManagerTest, std::move(scored_document_hits2), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); ICING_ASSERT_OK_AND_ASSIGN( PageResultInfo page_result_info3, @@ -1201,13 +1262,15 @@ TEST_F(ResultStateManagerTest, std::move(scored_document_hits3), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); // GetNextPage for result state 1 should return its result and decrement the // number of cached hits to 2. ICING_ASSERT_OK_AND_ASSIGN(page_result_info1, result_state_manager.GetNextPage( - page_result_info1.first, result_retriever())); + page_result_info1.first, result_retriever(), + clock()->GetSystemTimeMilliseconds())); ASSERT_THAT(page_result_info1.second.results, SizeIs(1)); EXPECT_THAT(page_result_info1.second.results.at(0).document(), EqualsProto(document_protos1.at(1))); @@ -1225,7 +1288,8 @@ TEST_F(ResultStateManagerTest, std::move(scored_document_hits4), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); // If retrieving the next page for result state 1 correctly decremented the // current hit count to 2 and adding state 4 correctly incremented it to 3, @@ -1240,33 +1304,39 @@ TEST_F(ResultStateManagerTest, std::move(scored_document_hits5), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); - EXPECT_THAT(result_state_manager.GetNextPage(page_result_info1.first, - result_retriever()), + EXPECT_THAT(result_state_manager.GetNextPage( + page_result_info1.first, result_retriever(), + clock()->GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::NOT_FOUND)); - EXPECT_THAT(result_state_manager.GetNextPage(page_result_info2.first, - result_retriever()), + EXPECT_THAT(result_state_manager.GetNextPage( + page_result_info2.first, result_retriever(), + clock()->GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::NOT_FOUND)); ICING_ASSERT_OK_AND_ASSIGN(page_result_info3, result_state_manager.GetNextPage( - page_result_info3.first, result_retriever())); + page_result_info3.first, result_retriever(), + clock()->GetSystemTimeMilliseconds())); ASSERT_THAT(page_result_info3.second.results, SizeIs(1)); EXPECT_THAT(page_result_info3.second.results.at(0).document(), EqualsProto(document_protos3.at(1))); ICING_ASSERT_OK_AND_ASSIGN(page_result_info4, result_state_manager.GetNextPage( - page_result_info4.first, result_retriever())); + page_result_info4.first, result_retriever(), + clock()->GetSystemTimeMilliseconds())); ASSERT_THAT(page_result_info4.second.results, SizeIs(1)); EXPECT_THAT(page_result_info4.second.results.at(0).document(), EqualsProto(document_protos4.at(1))); ICING_ASSERT_OK_AND_ASSIGN(page_result_info5, result_state_manager.GetNextPage( - page_result_info5.first, result_retriever())); + page_result_info5.first, result_retriever(), + clock()->GetSystemTimeMilliseconds())); ASSERT_THAT(page_result_info5.second.results, SizeIs(1)); EXPECT_THAT(page_result_info5.second.results.at(0).document(), EqualsProto(document_protos5.at(1))); @@ -1284,7 +1354,7 @@ TEST_F(ResultStateManagerTest, // CacheAndRetrieveFirstPage). Each result state has a page size of 1. So 3 // hits will remain cached. ResultStateManager result_state_manager(/*max_total_hits=*/4, - document_store(), clock()); + document_store()); ICING_ASSERT_OK_AND_ASSIGN( PageResultInfo page_result_info1, @@ -1294,7 +1364,8 @@ TEST_F(ResultStateManagerTest, std::move(scored_document_hits1), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); ICING_ASSERT_OK_AND_ASSIGN( PageResultInfo page_result_info2, @@ -1304,7 +1375,8 @@ TEST_F(ResultStateManagerTest, std::move(scored_document_hits2), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); // Add a result state that is larger than the entire budget. This should // result in all previous result states being evicted, the first hit from @@ -1321,23 +1393,27 @@ TEST_F(ResultStateManagerTest, std::move(scored_document_hits3), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); EXPECT_THAT(page_result_info3.first, Not(Eq(kInvalidNextPageToken))); // GetNextPage for result state 1 and 2 should return NOT_FOUND. - EXPECT_THAT(result_state_manager.GetNextPage(page_result_info1.first, - result_retriever()), + EXPECT_THAT(result_state_manager.GetNextPage( + page_result_info1.first, result_retriever(), + clock()->GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::NOT_FOUND)); - EXPECT_THAT(result_state_manager.GetNextPage(page_result_info2.first, - result_retriever()), + EXPECT_THAT(result_state_manager.GetNextPage( + page_result_info2.first, result_retriever(), + clock()->GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::NOT_FOUND)); // Only the next four results in state 3 should be retrievable. uint64_t next_page_token3 = page_result_info3.first; ICING_ASSERT_OK_AND_ASSIGN( page_result_info3, - result_state_manager.GetNextPage(next_page_token3, result_retriever())); + result_state_manager.GetNextPage(next_page_token3, result_retriever(), + clock()->GetSystemTimeMilliseconds())); EXPECT_THAT(page_result_info3.first, Eq(next_page_token3)); ASSERT_THAT(page_result_info3.second.results, SizeIs(1)); EXPECT_THAT(page_result_info3.second.results.at(0).document(), @@ -1345,7 +1421,8 @@ TEST_F(ResultStateManagerTest, ICING_ASSERT_OK_AND_ASSIGN( page_result_info3, - result_state_manager.GetNextPage(next_page_token3, result_retriever())); + result_state_manager.GetNextPage(next_page_token3, result_retriever(), + clock()->GetSystemTimeMilliseconds())); EXPECT_THAT(page_result_info3.first, Eq(next_page_token3)); ASSERT_THAT(page_result_info3.second.results, SizeIs(1)); EXPECT_THAT(page_result_info3.second.results.at(0).document(), @@ -1353,7 +1430,8 @@ TEST_F(ResultStateManagerTest, ICING_ASSERT_OK_AND_ASSIGN( page_result_info3, - result_state_manager.GetNextPage(next_page_token3, result_retriever())); + result_state_manager.GetNextPage(next_page_token3, result_retriever(), + clock()->GetSystemTimeMilliseconds())); EXPECT_THAT(page_result_info3.first, Eq(next_page_token3)); ASSERT_THAT(page_result_info3.second.results, SizeIs(1)); EXPECT_THAT(page_result_info3.second.results.at(0).document(), @@ -1361,7 +1439,8 @@ TEST_F(ResultStateManagerTest, ICING_ASSERT_OK_AND_ASSIGN( page_result_info3, - result_state_manager.GetNextPage(next_page_token3, result_retriever())); + result_state_manager.GetNextPage(next_page_token3, result_retriever(), + clock()->GetSystemTimeMilliseconds())); // The final document should have been dropped because it exceeded the budget, // so the next page token of the second last round should be // kInvalidNextPageToken. @@ -1372,7 +1451,8 @@ TEST_F(ResultStateManagerTest, // Double check that next_page_token3 is not retrievable anymore. EXPECT_THAT( - result_state_manager.GetNextPage(next_page_token3, result_retriever()), + result_state_manager.GetNextPage(next_page_token3, result_retriever(), + clock()->GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::NOT_FOUND)); } @@ -1385,7 +1465,7 @@ TEST_F(ResultStateManagerTest, /*document_id=*/3, /*document_id=*/4, /*document_id=*/5}); ResultStateManager result_state_manager(/*max_total_hits=*/4, - document_store(), clock()); + document_store()); ICING_ASSERT_OK_AND_ASSIGN( PageResultInfo page_result_info1, @@ -1395,7 +1475,8 @@ TEST_F(ResultStateManagerTest, std::move(scored_document_hits1), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); // Add a result state. Because state2 + state1 is larger than the budget, // state1 should be evicted. @@ -1409,16 +1490,19 @@ TEST_F(ResultStateManagerTest, std::move(scored_document_hits2), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/1, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); // state1 should have been evicted and state2 should still be retrievable. - EXPECT_THAT(result_state_manager.GetNextPage(page_result_info1.first, - result_retriever()), + EXPECT_THAT(result_state_manager.GetNextPage( + page_result_info1.first, result_retriever(), + clock()->GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::NOT_FOUND)); ICING_ASSERT_OK_AND_ASSIGN(page_result_info2, result_state_manager.GetNextPage( - page_result_info2.first, result_retriever())); + page_result_info2.first, result_retriever(), + clock()->GetSystemTimeMilliseconds())); ASSERT_THAT(page_result_info2.second.results, SizeIs(1)); EXPECT_THAT(page_result_info2.second.results.at(0).document(), EqualsProto(document_protos2.at(1))); @@ -1434,7 +1518,7 @@ TEST_F(ResultStateManagerTest, /*document_id=*/3, /*document_id=*/4}); ResultStateManager result_state_manager(/*max_total_hits=*/4, - document_store(), clock()); + document_store()); // The 5 input scored document hits will not be truncated. The first page of // two hits will be returned immediately and the other three hits will fit @@ -1447,7 +1531,8 @@ TEST_F(ResultStateManagerTest, std::move(scored_document_hits), /*is_descending=*/true), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(/*num_per_page=*/2, ResultSpecProto::NAMESPACE), - document_store(), result_retriever())); + document_store(), result_retriever(), + clock()->GetSystemTimeMilliseconds())); // First page, 2 results ASSERT_THAT(page_result_info1.second.results, SizeIs(2)); @@ -1461,7 +1546,8 @@ TEST_F(ResultStateManagerTest, // Second page, 2 results. ICING_ASSERT_OK_AND_ASSIGN( PageResultInfo page_result_info2, - result_state_manager.GetNextPage(next_page_token, result_retriever())); + result_state_manager.GetNextPage(next_page_token, result_retriever(), + clock()->GetSystemTimeMilliseconds())); ASSERT_THAT(page_result_info2.second.results, SizeIs(2)); EXPECT_THAT(page_result_info2.second.results.at(0).document(), EqualsProto(document_protos.at(2))); @@ -1471,14 +1557,16 @@ TEST_F(ResultStateManagerTest, // Third page, 1 result. ICING_ASSERT_OK_AND_ASSIGN( PageResultInfo page_result_info3, - result_state_manager.GetNextPage(next_page_token, result_retriever())); + result_state_manager.GetNextPage(next_page_token, result_retriever(), + clock()->GetSystemTimeMilliseconds())); ASSERT_THAT(page_result_info3.second.results, SizeIs(1)); EXPECT_THAT(page_result_info3.second.results.at(0).document(), EqualsProto(document_protos.at(4))); // Fourth page, 0 results. EXPECT_THAT( - result_state_manager.GetNextPage(next_page_token, result_retriever()), + result_state_manager.GetNextPage(next_page_token, result_retriever(), + clock()->GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::NOT_FOUND)); } diff --git a/icing/result/result-state-manager_thread-safety_test.cc b/icing/result/result-state-manager_thread-safety_test.cc index 06eaaf4..53745e6 100644 --- a/icing/result/result-state-manager_thread-safety_test.cc +++ b/icing/result/result-state-manager_thread-safety_test.cc @@ -152,7 +152,7 @@ TEST_F(ResultStateManagerThreadSafetyTest, constexpr int kNumPerPage = 100; ResultStateManager result_state_manager(/*max_total_hits=*/kNumDocuments, - *document_store_, clock_.get()); + *document_store_); // Retrieve the first page. // Documents are ordered by score *ascending*, so the first page should @@ -164,7 +164,8 @@ TEST_F(ResultStateManagerThreadSafetyTest, PriorityQueueScoredDocumentHitsRanker<ScoredDocumentHit>>( std::move(scored_document_hits), /*is_descending=*/false), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, - CreateResultSpec(kNumPerPage), *document_store_, *result_retriever_)); + CreateResultSpec(kNumPerPage), *document_store_, *result_retriever_, + clock_->GetSystemTimeMilliseconds())); ASSERT_THAT(page_result_info1.second.results, SizeIs(kNumPerPage)); for (int i = 0; i < kNumPerPage; ++i) { ASSERT_THAT(page_result_info1.second.results[i].score(), Eq(i)); @@ -186,7 +187,8 @@ TEST_F(ResultStateManagerThreadSafetyTest, normalizer_.get())); ICING_ASSERT_OK_AND_ASSIGN( PageResultInfo page_result_info, - result_state_manager.GetNextPage(next_page_token, *result_retriever)); + result_state_manager.GetNextPage(next_page_token, *result_retriever, + clock_->GetSystemTimeMilliseconds())); page_results[thread_id] = std::make_optional<PageResultInfo>(std::move(page_result_info)); }; @@ -252,7 +254,7 @@ TEST_F(ResultStateManagerThreadSafetyTest, InvalidateResultStateWhileUsing) { constexpr int kNumPerPage = 100; ResultStateManager result_state_manager(/*max_total_hits=*/kNumDocuments, - *document_store_, clock_.get()); + *document_store_); // Retrieve the first page. // Documents are ordered by score *ascending*, so the first page should @@ -264,7 +266,8 @@ TEST_F(ResultStateManagerThreadSafetyTest, InvalidateResultStateWhileUsing) { PriorityQueueScoredDocumentHitsRanker<ScoredDocumentHit>>( std::move(scored_document_hits), /*is_descending=*/false), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, - CreateResultSpec(kNumPerPage), *document_store_, *result_retriever_)); + CreateResultSpec(kNumPerPage), *document_store_, *result_retriever_, + clock_->GetSystemTimeMilliseconds())); ASSERT_THAT(page_result_info1.second.results, SizeIs(kNumPerPage)); for (int i = 0; i < kNumPerPage; ++i) { ASSERT_THAT(page_result_info1.second.results[i].score(), Eq(i)); @@ -287,7 +290,8 @@ TEST_F(ResultStateManagerThreadSafetyTest, InvalidateResultStateWhileUsing) { normalizer_.get())); libtextclassifier3::StatusOr<PageResultInfo> page_result_info_or = - result_state_manager.GetNextPage(next_page_token, *result_retriever); + result_state_manager.GetNextPage(next_page_token, *result_retriever, + clock_->GetSystemTimeMilliseconds()); if (page_result_info_or.ok()) { page_results[thread_id] = std::make_optional<PageResultInfo>( std::move(page_result_info_or).ValueOrDie()); @@ -364,8 +368,7 @@ TEST_F(ResultStateManagerThreadSafetyTest, MultipleResultStates) { constexpr int kNumThreads = 50; constexpr int kNumPerPage = 30; ResultStateManager result_state_manager( - /*max_total_hits=*/kNumDocuments * kNumThreads, *document_store_, - clock_.get()); + /*max_total_hits=*/kNumDocuments * kNumThreads, *document_store_); // Create kNumThreads threads to: // - Call CacheAndRetrieveFirstPage() once to create its own ResultState. @@ -394,7 +397,8 @@ TEST_F(ResultStateManagerThreadSafetyTest, MultipleResultStates) { std::move(scored_document_hits_copy), /*is_descending=*/false), /*parent_adjustment_info=*/nullptr, /*child_adjustment_info=*/nullptr, CreateResultSpec(kNumPerPage), - *document_store_, *result_retriever)); + *document_store_, *result_retriever, + clock_->GetSystemTimeMilliseconds())); EXPECT_THAT(page_result_info1.second.results, SizeIs(kNumPerPage)); for (int i = 0; i < kNumPerPage; ++i) { EXPECT_THAT(page_result_info1.second.results[i].score(), Eq(i)); @@ -413,9 +417,10 @@ TEST_F(ResultStateManagerThreadSafetyTest, MultipleResultStates) { // each thread should retrieve 1, 2, 3, ..., kNumThreads pages. int num_subsequent_pages_to_retrieve = thread_id; for (int i = 0; i < num_subsequent_pages_to_retrieve; ++i) { - ICING_ASSERT_OK_AND_ASSIGN( - PageResultInfo page_result_info, - result_state_manager.GetNextPage(next_page_token, *result_retriever)); + ICING_ASSERT_OK_AND_ASSIGN(PageResultInfo page_result_info, + result_state_manager.GetNextPage( + next_page_token, *result_retriever, + clock_->GetSystemTimeMilliseconds())); EXPECT_THAT(page_result_info.second.results, SizeIs(kNumPerPage)); for (int j = 0; j < kNumPerPage; ++j) { EXPECT_THAT(page_result_info.second.results[j].score(), diff --git a/icing/schema/schema-store.h b/icing/schema/schema-store.h index 73d7848..6075f5b 100644 --- a/icing/schema/schema-store.h +++ b/icing/schema/schema-store.h @@ -74,7 +74,8 @@ class SchemaStore { overlay_created_(false), min_overlay_version_compatibility_( std::numeric_limits<int32_t>::max()) { - memset(padding, 0, kPaddingSize); + memset(overlay_created_padding_, 0, kOverlayCreatedPaddingSize); + memset(padding_, 0, kPaddingSize); } // RETURNS: @@ -112,12 +113,17 @@ class SchemaStore { uint32_t checksum_; bool overlay_created_; + // Three bytes of padding due to the fact that + // min_overlay_version_compatibility_ has an alignof() == 4 and the offset + // of overlay_created_padding_ == 9. + static constexpr int kOverlayCreatedPaddingSize = 3; + uint8_t overlay_created_padding_[kOverlayCreatedPaddingSize]; int32_t min_overlay_version_compatibility_; static constexpr int kPaddingSize = 1008; // Padding exists just to reserve space for additional values. - uint8_t padding[kPaddingSize]; + uint8_t padding_[kPaddingSize]; }; static_assert(sizeof(Header) == 1024); diff --git a/icing/scoring/advanced_scoring/advanced-scorer.cc b/icing/scoring/advanced_scoring/advanced-scorer.cc index 8925024..83c1519 100644 --- a/icing/scoring/advanced_scoring/advanced-scorer.cc +++ b/icing/scoring/advanced_scoring/advanced-scorer.cc @@ -30,7 +30,7 @@ libtextclassifier3::StatusOr<std::unique_ptr<AdvancedScorer>> AdvancedScorer::Create(const ScoringSpecProto& scoring_spec, double default_score, const DocumentStore* document_store, - const SchemaStore* schema_store, + const SchemaStore* schema_store, int64_t current_time_ms, const JoinChildrenFetcher* join_children_fetcher) { ICING_RETURN_ERROR_IF_NULL(document_store); ICING_RETURN_ERROR_IF_NULL(schema_store); @@ -46,10 +46,11 @@ AdvancedScorer::Create(const ScoringSpecProto& scoring_spec, ICING_ASSIGN_OR_RETURN(std::unique_ptr<SectionWeights> section_weights, SectionWeights::Create(schema_store, scoring_spec)); std::unique_ptr<Bm25fCalculator> bm25f_calculator = - std::make_unique<Bm25fCalculator>(document_store, section_weights.get()); + std::make_unique<Bm25fCalculator>(document_store, section_weights.get(), + current_time_ms); ScoringVisitor visitor(default_score, document_store, schema_store, section_weights.get(), bm25f_calculator.get(), - join_children_fetcher); + join_children_fetcher, current_time_ms); tree_root->Accept(&visitor); ICING_ASSIGN_OR_RETURN(std::unique_ptr<ScoreExpression> expression, diff --git a/icing/scoring/advanced_scoring/advanced-scorer.h b/icing/scoring/advanced_scoring/advanced-scorer.h index aa7914f..d69abad 100644 --- a/icing/scoring/advanced_scoring/advanced-scorer.h +++ b/icing/scoring/advanced_scoring/advanced-scorer.h @@ -39,6 +39,7 @@ class AdvancedScorer : public Scorer { static libtextclassifier3::StatusOr<std::unique_ptr<AdvancedScorer>> Create( const ScoringSpecProto& scoring_spec, double default_score, const DocumentStore* document_store, const SchemaStore* schema_store, + int64_t current_time_ms, const JoinChildrenFetcher* join_children_fetcher = nullptr); double GetScore(const DocHitInfo& hit_info, diff --git a/icing/scoring/advanced_scoring/advanced-scorer_fuzz_test.cc b/icing/scoring/advanced_scoring/advanced-scorer_fuzz_test.cc index 8db592a..bdafa28 100644 --- a/icing/scoring/advanced_scoring/advanced-scorer_fuzz_test.cc +++ b/icing/scoring/advanced_scoring/advanced-scorer_fuzz_test.cc @@ -55,7 +55,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { AdvancedScorer::Create(scoring_spec, /*default_score=*/10, document_store.get(), - schema_store.get()); + schema_store.get(), + fake_clock.GetSystemTimeMilliseconds()); // Not able to test the GetScore method of AdvancedScorer, since it will only // be available after AdvancedScorer is successfully created. However, the diff --git a/icing/scoring/advanced_scoring/advanced-scorer_test.cc b/icing/scoring/advanced_scoring/advanced-scorer_test.cc index f7a0670..0ecc21d 100644 --- a/icing/scoring/advanced_scoring/advanced-scorer_test.cc +++ b/icing/scoring/advanced_scoring/advanced-scorer_test.cc @@ -191,19 +191,19 @@ TEST_F(AdvancedScorerTest, InvalidAdvancedScoringSpec) { ScoringSpecProto scoring_spec; scoring_spec.set_rank_by( ScoringSpecProto::RankingStrategy::ADVANCED_SCORING_EXPRESSION); - EXPECT_THAT( - scorer_factory::Create(scoring_spec, /*default_score=*/10, - document_store_.get(), schema_store_.get()), - StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); + EXPECT_THAT(scorer_factory::Create(scoring_spec, /*default_score=*/10, + document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds()), + StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); // Non-empty scoring expression for normal scoring scoring_spec = ScoringSpecProto::default_instance(); scoring_spec.set_rank_by(ScoringSpecProto::RankingStrategy::DOCUMENT_SCORE); scoring_spec.set_advanced_scoring_expression("1"); - EXPECT_THAT( - scorer_factory::Create(scoring_spec, /*default_score=*/10, - document_store_.get(), schema_store_.get()), - StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); + EXPECT_THAT(scorer_factory::Create(scoring_spec, /*default_score=*/10, + document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds()), + StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); } TEST_F(AdvancedScorerTest, SimpleExpression) { @@ -215,7 +215,8 @@ TEST_F(AdvancedScorerTest, SimpleExpression) { std::unique_ptr<Scorer> scorer, AdvancedScorer::Create(CreateAdvancedScoringSpec("123"), /*default_score=*/10, document_store_.get(), - schema_store_.get())); + schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); DocHitInfo docHitInfo = DocHitInfo(document_id); @@ -232,42 +233,43 @@ TEST_F(AdvancedScorerTest, BasicPureArithmeticExpression) { std::unique_ptr<Scorer> scorer, AdvancedScorer::Create(CreateAdvancedScoringSpec("1 + 2"), /*default_score=*/10, document_store_.get(), - schema_store_.get())); + schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(scorer->GetScore(docHitInfo), Eq(3)); ICING_ASSERT_OK_AND_ASSIGN( - scorer, - AdvancedScorer::Create(CreateAdvancedScoringSpec("-1 + 2"), - /*default_score=*/10, document_store_.get(), - schema_store_.get())); + scorer, AdvancedScorer::Create(CreateAdvancedScoringSpec("-1 + 2"), + /*default_score=*/10, + document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(scorer->GetScore(docHitInfo), Eq(1)); ICING_ASSERT_OK_AND_ASSIGN( - scorer, - AdvancedScorer::Create(CreateAdvancedScoringSpec("1 + -2"), - /*default_score=*/10, document_store_.get(), - schema_store_.get())); + scorer, AdvancedScorer::Create(CreateAdvancedScoringSpec("1 + -2"), + /*default_score=*/10, + document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(scorer->GetScore(docHitInfo), Eq(-1)); ICING_ASSERT_OK_AND_ASSIGN( - scorer, - AdvancedScorer::Create(CreateAdvancedScoringSpec("1 - 2"), - /*default_score=*/10, document_store_.get(), - schema_store_.get())); + scorer, AdvancedScorer::Create(CreateAdvancedScoringSpec("1 - 2"), + /*default_score=*/10, + document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(scorer->GetScore(docHitInfo), Eq(-1)); ICING_ASSERT_OK_AND_ASSIGN( - scorer, - AdvancedScorer::Create(CreateAdvancedScoringSpec("1 * 2"), - /*default_score=*/10, document_store_.get(), - schema_store_.get())); + scorer, AdvancedScorer::Create(CreateAdvancedScoringSpec("1 * 2"), + /*default_score=*/10, + document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(scorer->GetScore(docHitInfo), Eq(2)); ICING_ASSERT_OK_AND_ASSIGN( - scorer, - AdvancedScorer::Create(CreateAdvancedScoringSpec("1 / 2"), - /*default_score=*/10, document_store_.get(), - schema_store_.get())); + scorer, AdvancedScorer::Create(CreateAdvancedScoringSpec("1 / 2"), + /*default_score=*/10, + document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(scorer->GetScore(docHitInfo), Eq(0.5)); } @@ -281,91 +283,102 @@ TEST_F(AdvancedScorerTest, BasicMathFunctionExpression) { std::unique_ptr<Scorer> scorer, AdvancedScorer::Create(CreateAdvancedScoringSpec("log(10, 1000)"), /*default_score=*/10, document_store_.get(), - schema_store_.get())); + schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(scorer->GetScore(docHitInfo), DoubleNear(3, kEps)); ICING_ASSERT_OK_AND_ASSIGN( scorer, AdvancedScorer::Create( CreateAdvancedScoringSpec("log(2.718281828459045)"), - /*default_score=*/10, document_store_.get(), schema_store_.get())); + /*default_score=*/10, document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(scorer->GetScore(docHitInfo), DoubleNear(1, kEps)); ICING_ASSERT_OK_AND_ASSIGN( - scorer, - AdvancedScorer::Create(CreateAdvancedScoringSpec("pow(2, 10)"), - /*default_score=*/10, document_store_.get(), - schema_store_.get())); + scorer, AdvancedScorer::Create(CreateAdvancedScoringSpec("pow(2, 10)"), + /*default_score=*/10, + document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(scorer->GetScore(docHitInfo), Eq(1024)); ICING_ASSERT_OK_AND_ASSIGN( scorer, AdvancedScorer::Create( CreateAdvancedScoringSpec("max(10, 11, 12, 13, 14)"), - /*default_score=*/10, document_store_.get(), schema_store_.get())); + /*default_score=*/10, document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(scorer->GetScore(docHitInfo), Eq(14)); ICING_ASSERT_OK_AND_ASSIGN( scorer, AdvancedScorer::Create( CreateAdvancedScoringSpec("min(10, 11, 12, 13, 14)"), - /*default_score=*/10, document_store_.get(), schema_store_.get())); + /*default_score=*/10, document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(scorer->GetScore(docHitInfo), Eq(10)); ICING_ASSERT_OK_AND_ASSIGN( scorer, AdvancedScorer::Create( CreateAdvancedScoringSpec("len(10, 11, 12, 13, 14)"), - /*default_score=*/10, document_store_.get(), schema_store_.get())); + /*default_score=*/10, document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(scorer->GetScore(docHitInfo), Eq(5)); ICING_ASSERT_OK_AND_ASSIGN( scorer, AdvancedScorer::Create( CreateAdvancedScoringSpec("sum(10, 11, 12, 13, 14)"), - /*default_score=*/10, document_store_.get(), schema_store_.get())); + /*default_score=*/10, document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(scorer->GetScore(docHitInfo), Eq(10 + 11 + 12 + 13 + 14)); ICING_ASSERT_OK_AND_ASSIGN( scorer, AdvancedScorer::Create( CreateAdvancedScoringSpec("avg(10, 11, 12, 13, 14)"), - /*default_score=*/10, document_store_.get(), schema_store_.get())); + /*default_score=*/10, document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(scorer->GetScore(docHitInfo), Eq((10 + 11 + 12 + 13 + 14) / 5.)); ICING_ASSERT_OK_AND_ASSIGN( - scorer, - AdvancedScorer::Create(CreateAdvancedScoringSpec("sqrt(2)"), - /*default_score=*/10, document_store_.get(), - schema_store_.get())); + scorer, AdvancedScorer::Create(CreateAdvancedScoringSpec("sqrt(2)"), + /*default_score=*/10, + document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(scorer->GetScore(docHitInfo), DoubleNear(sqrt(2), kEps)); ICING_ASSERT_OK_AND_ASSIGN( scorer, AdvancedScorer::Create(CreateAdvancedScoringSpec("abs(-2) + abs(2)"), /*default_score=*/10, document_store_.get(), - schema_store_.get())); + schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(scorer->GetScore(docHitInfo), Eq(4)); ICING_ASSERT_OK_AND_ASSIGN( scorer, AdvancedScorer::Create( CreateAdvancedScoringSpec("sin(3.141592653589793)"), - /*default_score=*/10, document_store_.get(), schema_store_.get())); + /*default_score=*/10, document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(scorer->GetScore(docHitInfo), DoubleNear(0, kEps)); ICING_ASSERT_OK_AND_ASSIGN( scorer, AdvancedScorer::Create( CreateAdvancedScoringSpec("cos(3.141592653589793)"), - /*default_score=*/10, document_store_.get(), schema_store_.get())); + /*default_score=*/10, document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(scorer->GetScore(docHitInfo), DoubleNear(-1, kEps)); ICING_ASSERT_OK_AND_ASSIGN( scorer, AdvancedScorer::Create( CreateAdvancedScoringSpec("tan(3.141592653589793 / 4)"), - /*default_score=*/10, document_store_.get(), schema_store_.get())); + /*default_score=*/10, document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(scorer->GetScore(docHitInfo), DoubleNear(1, kEps)); } @@ -381,14 +394,16 @@ TEST_F(AdvancedScorerTest, DocumentScoreCreationTimestampFunctionExpression) { std::unique_ptr<Scorer> scorer, AdvancedScorer::Create(CreateAdvancedScoringSpec("this.documentScore()"), /*default_score=*/10, document_store_.get(), - schema_store_.get())); + schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(scorer->GetScore(docHitInfo), Eq(123)); ICING_ASSERT_OK_AND_ASSIGN( scorer, AdvancedScorer::Create( CreateAdvancedScoringSpec("this.creationTimestamp()"), - /*default_score=*/10, document_store_.get(), schema_store_.get())); + /*default_score=*/10, document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(scorer->GetScore(docHitInfo), Eq(kDefaultCreationTimestampMs)); ICING_ASSERT_OK_AND_ASSIGN( @@ -396,7 +411,8 @@ TEST_F(AdvancedScorerTest, DocumentScoreCreationTimestampFunctionExpression) { AdvancedScorer::Create( CreateAdvancedScoringSpec( "this.documentScore() + this.creationTimestamp()"), - /*default_score=*/10, document_store_.get(), schema_store_.get())); + /*default_score=*/10, document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(scorer->GetScore(docHitInfo), Eq(123 + kDefaultCreationTimestampMs)); } @@ -412,7 +428,8 @@ TEST_F(AdvancedScorerTest, DocumentUsageFunctionExpression) { AdvancedScorer::Create( CreateAdvancedScoringSpec("this.usageCount(1) + this.usageCount(2) " "+ this.usageLastUsedTimestamp(3)"), - /*default_score=*/10, document_store_.get(), schema_store_.get())); + /*default_score=*/10, document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(scorer->GetScore(docHitInfo), Eq(0)); ICING_ASSERT_OK(document_store_->ReportUsage( CreateUsageReport("namespace", "uri", 100000, UsageReport::USAGE_TYPE1))); @@ -428,19 +445,22 @@ TEST_F(AdvancedScorerTest, DocumentUsageFunctionExpression) { scorer, AdvancedScorer::Create( CreateAdvancedScoringSpec("this.usageLastUsedTimestamp(1)"), - /*default_score=*/10, document_store_.get(), schema_store_.get())); + /*default_score=*/10, document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(scorer->GetScore(docHitInfo), Eq(100000)); ICING_ASSERT_OK_AND_ASSIGN( scorer, AdvancedScorer::Create( CreateAdvancedScoringSpec("this.usageLastUsedTimestamp(2)"), - /*default_score=*/10, document_store_.get(), schema_store_.get())); + /*default_score=*/10, document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(scorer->GetScore(docHitInfo), Eq(200000)); ICING_ASSERT_OK_AND_ASSIGN( scorer, AdvancedScorer::Create( CreateAdvancedScoringSpec("this.usageLastUsedTimestamp(3)"), - /*default_score=*/10, document_store_.get(), schema_store_.get())); + /*default_score=*/10, document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(scorer->GetScore(docHitInfo), Eq(300000)); } @@ -459,19 +479,22 @@ TEST_F(AdvancedScorerTest, DocumentUsageFunctionOutOfRange) { std::unique_ptr<Scorer> scorer, AdvancedScorer::Create(CreateAdvancedScoringSpec("this.usageCount(4)"), default_score, document_store_.get(), - schema_store_.get())); + schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(scorer->GetScore(docHitInfo), Eq(default_score)); ICING_ASSERT_OK_AND_ASSIGN( scorer, AdvancedScorer::Create( CreateAdvancedScoringSpec("this.usageCount(0)"), - default_score, document_store_.get(), schema_store_.get())); + default_score, document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(scorer->GetScore(docHitInfo), Eq(default_score)); ICING_ASSERT_OK_AND_ASSIGN( scorer, AdvancedScorer::Create( CreateAdvancedScoringSpec("this.usageCount(1.5)"), - default_score, document_store_.get(), schema_store_.get())); + default_score, document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(scorer->GetScore(docHitInfo), Eq(default_score)); } @@ -493,7 +516,8 @@ TEST_F(AdvancedScorerTest, RelevanceScoreFunctionScoreExpression) { std::unique_ptr<AdvancedScorer> scorer, AdvancedScorer::Create(CreateAdvancedScoringSpec("this.relevanceScore()"), /*default_score=*/10, document_store_.get(), - schema_store_.get())); + schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); scorer->PrepareToScore(/*query_term_iterators=*/{}); // Should get the default score. @@ -541,7 +565,8 @@ TEST_F(AdvancedScorerTest, ChildrenScoresFunctionScoreExpression) { std::unique_ptr<AdvancedScorer> scorer, AdvancedScorer::Create( CreateAdvancedScoringSpec("len(this.childrenRankingSignals())"), - default_score, document_store_.get(), schema_store_.get(), &fetcher)); + default_score, document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds(), &fetcher)); // document_id_1 has two children. EXPECT_THAT(scorer->GetScore(docHitInfo1, /*query_it=*/nullptr), Eq(2)); // document_id_2 has one child. @@ -553,7 +578,8 @@ TEST_F(AdvancedScorerTest, ChildrenScoresFunctionScoreExpression) { scorer, AdvancedScorer::Create( CreateAdvancedScoringSpec("sum(this.childrenRankingSignals())"), - default_score, document_store_.get(), schema_store_.get(), &fetcher)); + default_score, document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds(), &fetcher)); // document_id_1 has two children with scores 1 and 2. EXPECT_THAT(scorer->GetScore(docHitInfo1, /*query_it=*/nullptr), Eq(3)); // document_id_2 has one child with score 4. @@ -565,7 +591,8 @@ TEST_F(AdvancedScorerTest, ChildrenScoresFunctionScoreExpression) { scorer, AdvancedScorer::Create( CreateAdvancedScoringSpec("avg(this.childrenRankingSignals())"), - default_score, document_store_.get(), schema_store_.get(), &fetcher)); + default_score, document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds(), &fetcher)); // document_id_1 has two children with scores 1 and 2. EXPECT_THAT(scorer->GetScore(docHitInfo1, /*query_it=*/nullptr), Eq(3 / 2.)); // document_id_2 has one child with score 4. @@ -576,13 +603,13 @@ TEST_F(AdvancedScorerTest, ChildrenScoresFunctionScoreExpression) { Eq(default_score)); ICING_ASSERT_OK_AND_ASSIGN( - scorer, - AdvancedScorer::Create( - CreateAdvancedScoringSpec( - // Equivalent to "avg(this.childrenRankingSignals())" - "sum(this.childrenRankingSignals()) / " - "len(this.childrenRankingSignals())"), - default_score, document_store_.get(), schema_store_.get(), &fetcher)); + scorer, AdvancedScorer::Create( + CreateAdvancedScoringSpec( + // Equivalent to "avg(this.childrenRankingSignals())" + "sum(this.childrenRankingSignals()) / " + "len(this.childrenRankingSignals())"), + default_score, document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds(), &fetcher)); // document_id_1 has two children with scores 1 and 2. EXPECT_THAT(scorer->GetScore(docHitInfo1, /*query_it=*/nullptr), Eq(3 / 2.)); // document_id_2 has one child with score 4. @@ -643,7 +670,8 @@ TEST_F(AdvancedScorerTest, PropertyWeightsFunctionScoreExpression) { std::unique_ptr<AdvancedScorer> scorer, AdvancedScorer::Create(spec_proto, /*default_score=*/10, document_store_.get(), - schema_store_.get())); + schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); // min([1]) = 1 EXPECT_THAT(scorer->GetScore(doc_hit_info_1, /*query_it=*/nullptr), Eq(1)); // min([0.5, 0.8]) = 0.5 @@ -653,10 +681,10 @@ TEST_F(AdvancedScorerTest, PropertyWeightsFunctionScoreExpression) { spec_proto.set_advanced_scoring_expression("max(this.propertyWeights())"); ICING_ASSERT_OK_AND_ASSIGN( - scorer, - AdvancedScorer::Create(spec_proto, - /*default_score=*/10, document_store_.get(), - schema_store_.get())); + scorer, AdvancedScorer::Create(spec_proto, + /*default_score=*/10, + document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); // max([1]) = 1 EXPECT_THAT(scorer->GetScore(doc_hit_info_1, /*query_it=*/nullptr), Eq(1)); // max([0.5, 0.8]) = 0.8 @@ -666,10 +694,10 @@ TEST_F(AdvancedScorerTest, PropertyWeightsFunctionScoreExpression) { spec_proto.set_advanced_scoring_expression("sum(this.propertyWeights())"); ICING_ASSERT_OK_AND_ASSIGN( - scorer, - AdvancedScorer::Create(spec_proto, - /*default_score=*/10, document_store_.get(), - schema_store_.get())); + scorer, AdvancedScorer::Create(spec_proto, + /*default_score=*/10, + document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); // sum([1]) = 1 EXPECT_THAT(scorer->GetScore(doc_hit_info_1, /*query_it=*/nullptr), Eq(1)); // sum([0.5, 0.8]) = 1.3 @@ -719,7 +747,8 @@ TEST_F(AdvancedScorerTest, std::unique_ptr<AdvancedScorer> scorer, AdvancedScorer::Create(spec_proto, /*default_score=*/10, document_store_.get(), - schema_store_.get())); + schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); // min([1]) = 1 EXPECT_THAT(scorer->GetScore(doc_hit_info_1, /*query_it=*/nullptr), Eq(1)); // min([0.5, 1, 0.5]) = 0.5 @@ -727,10 +756,10 @@ TEST_F(AdvancedScorerTest, spec_proto.set_advanced_scoring_expression("max(this.propertyWeights())"); ICING_ASSERT_OK_AND_ASSIGN( - scorer, - AdvancedScorer::Create(spec_proto, - /*default_score=*/10, document_store_.get(), - schema_store_.get())); + scorer, AdvancedScorer::Create(spec_proto, + /*default_score=*/10, + document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); // max([1]) = 1 EXPECT_THAT(scorer->GetScore(doc_hit_info_1, /*query_it=*/nullptr), Eq(1)); // max([0.5, 1, 0.5]) = 1 @@ -738,10 +767,10 @@ TEST_F(AdvancedScorerTest, spec_proto.set_advanced_scoring_expression("sum(this.propertyWeights())"); ICING_ASSERT_OK_AND_ASSIGN( - scorer, - AdvancedScorer::Create(spec_proto, - /*default_score=*/10, document_store_.get(), - schema_store_.get())); + scorer, AdvancedScorer::Create(spec_proto, + /*default_score=*/10, + document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); // sum([1]) = 1 EXPECT_THAT(scorer->GetScore(doc_hit_info_1, /*query_it=*/nullptr), Eq(1)); // sum([0.5, 1, 0.5]) = 2 @@ -757,6 +786,7 @@ TEST_F(AdvancedScorerTest, InvalidChildrenScoresFunctionScoreExpression) { AdvancedScorer::Create( CreateAdvancedScoringSpec("len(this.childrenRankingSignals())"), default_score, document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds(), /*join_children_fetcher=*/nullptr), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); @@ -767,7 +797,7 @@ TEST_F(AdvancedScorerTest, InvalidChildrenScoresFunctionScoreExpression) { EXPECT_THAT(AdvancedScorer::Create( CreateAdvancedScoringSpec("this.childrenRankingSignals()"), default_score, document_store_.get(), schema_store_.get(), - &fake_fetcher), + fake_clock_.GetSystemTimeMilliseconds(), &fake_fetcher), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); } @@ -791,7 +821,8 @@ TEST_F(AdvancedScorerTest, ComplexExpression) { // This should evaluate to default score. "+ this.relevanceScore()"), /*default_score=*/10, document_store_.get(), - schema_store_.get())); + schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_FALSE(scorer->is_constant()); scorer->PrepareToScore(/*query_term_iterators=*/{}); @@ -816,17 +847,18 @@ TEST_F(AdvancedScorerTest, ConstantExpression) { "+ log(2, 122) / 12.34" "* (10 * pow(2 * 1, sin(2)) + 10 * (2 + 10))"), /*default_score=*/10, document_store_.get(), - schema_store_.get())); + schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_TRUE(scorer->is_constant()); } // Should be a parsing Error TEST_F(AdvancedScorerTest, EmptyExpression) { - EXPECT_THAT( - AdvancedScorer::Create(CreateAdvancedScoringSpec(""), - /*default_score=*/10, document_store_.get(), - schema_store_.get()), - StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); + EXPECT_THAT(AdvancedScorer::Create(CreateAdvancedScoringSpec(""), + /*default_score=*/10, + document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds()), + StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); } TEST_F(AdvancedScorerTest, EvaluationErrorShouldReturnDefaultScore) { @@ -840,25 +872,29 @@ TEST_F(AdvancedScorerTest, EvaluationErrorShouldReturnDefaultScore) { ICING_ASSERT_OK_AND_ASSIGN( std::unique_ptr<Scorer> scorer, AdvancedScorer::Create(CreateAdvancedScoringSpec("log(0)"), default_score, - document_store_.get(), schema_store_.get())); + document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(scorer->GetScore(docHitInfo), DoubleNear(default_score, kEps)); ICING_ASSERT_OK_AND_ASSIGN( scorer, AdvancedScorer::Create(CreateAdvancedScoringSpec("1 / 0"), default_score, - document_store_.get(), schema_store_.get())); + document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(scorer->GetScore(docHitInfo), DoubleNear(default_score, kEps)); ICING_ASSERT_OK_AND_ASSIGN( scorer, AdvancedScorer::Create(CreateAdvancedScoringSpec("sqrt(-1)"), default_score, document_store_.get(), - schema_store_.get())); + schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(scorer->GetScore(docHitInfo), DoubleNear(default_score, kEps)); ICING_ASSERT_OK_AND_ASSIGN( scorer, AdvancedScorer::Create(CreateAdvancedScoringSpec("pow(-1, 0.5)"), default_score, document_store_.get(), - schema_store_.get())); + schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(scorer->GetScore(docHitInfo), DoubleNear(default_score, kEps)); } @@ -869,67 +905,80 @@ TEST_F(AdvancedScorerTest, MathTypeError) { EXPECT_THAT( AdvancedScorer::Create(CreateAdvancedScoringSpec("test"), default_score, - document_store_.get(), schema_store_.get()), + document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); EXPECT_THAT( AdvancedScorer::Create(CreateAdvancedScoringSpec("log()"), default_score, - document_store_.get(), schema_store_.get()), + document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); EXPECT_THAT(AdvancedScorer::Create(CreateAdvancedScoringSpec("log(1, 2, 3)"), default_score, document_store_.get(), - schema_store_.get()), + schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); EXPECT_THAT(AdvancedScorer::Create(CreateAdvancedScoringSpec("log(1, this)"), default_score, document_store_.get(), - schema_store_.get()), + schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); EXPECT_THAT( AdvancedScorer::Create(CreateAdvancedScoringSpec("pow(1)"), default_score, - document_store_.get(), schema_store_.get()), + document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); EXPECT_THAT(AdvancedScorer::Create(CreateAdvancedScoringSpec("sqrt(1, 2)"), default_score, document_store_.get(), - schema_store_.get()), + schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); EXPECT_THAT(AdvancedScorer::Create(CreateAdvancedScoringSpec("abs(1, 2)"), default_score, document_store_.get(), - schema_store_.get()), + schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); EXPECT_THAT(AdvancedScorer::Create(CreateAdvancedScoringSpec("sin(1, 2)"), default_score, document_store_.get(), - schema_store_.get()), + schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); EXPECT_THAT(AdvancedScorer::Create(CreateAdvancedScoringSpec("cos(1, 2)"), default_score, document_store_.get(), - schema_store_.get()), + schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); EXPECT_THAT(AdvancedScorer::Create(CreateAdvancedScoringSpec("tan(1, 2)"), default_score, document_store_.get(), - schema_store_.get()), + schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); EXPECT_THAT( AdvancedScorer::Create(CreateAdvancedScoringSpec("this"), default_score, - document_store_.get(), schema_store_.get()), + document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); EXPECT_THAT( AdvancedScorer::Create(CreateAdvancedScoringSpec("-this"), default_score, - document_store_.get(), schema_store_.get()), + document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); EXPECT_THAT(AdvancedScorer::Create(CreateAdvancedScoringSpec("1 + this"), default_score, document_store_.get(), - schema_store_.get()), + schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); } @@ -938,39 +987,48 @@ TEST_F(AdvancedScorerTest, DocumentFunctionTypeError) { EXPECT_THAT(AdvancedScorer::Create( CreateAdvancedScoringSpec("documentScore(1)"), default_score, - document_store_.get(), schema_store_.get()), + document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); EXPECT_THAT(AdvancedScorer::Create( CreateAdvancedScoringSpec("this.creationTimestamp(1)"), - default_score, document_store_.get(), schema_store_.get()), + default_score, document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); EXPECT_THAT(AdvancedScorer::Create( CreateAdvancedScoringSpec("this.usageCount()"), default_score, - document_store_.get(), schema_store_.get()), + document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); EXPECT_THAT(AdvancedScorer::Create( CreateAdvancedScoringSpec("usageLastUsedTimestamp(1, 1)"), - default_score, document_store_.get(), schema_store_.get()), + default_score, document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); EXPECT_THAT(AdvancedScorer::Create( CreateAdvancedScoringSpec("relevanceScore(1)"), default_score, - document_store_.get(), schema_store_.get()), + document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); EXPECT_THAT(AdvancedScorer::Create( CreateAdvancedScoringSpec("documentScore(this)"), - default_score, document_store_.get(), schema_store_.get()), + default_score, document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); EXPECT_THAT(AdvancedScorer::Create( CreateAdvancedScoringSpec("that.documentScore()"), - default_score, document_store_.get(), schema_store_.get()), + default_score, document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); EXPECT_THAT(AdvancedScorer::Create( CreateAdvancedScoringSpec("this.this.creationTimestamp()"), - default_score, document_store_.get(), schema_store_.get()), + default_score, document_store_.get(), schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); EXPECT_THAT(AdvancedScorer::Create(CreateAdvancedScoringSpec("this.log(2)"), default_score, document_store_.get(), - schema_store_.get()), + schema_store_.get(), + fake_clock_.GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT)); } diff --git a/icing/scoring/advanced_scoring/score-expression.cc b/icing/scoring/advanced_scoring/score-expression.cc index 7a16135..e8a2a89 100644 --- a/icing/scoring/advanced_scoring/score-expression.cc +++ b/icing/scoring/advanced_scoring/score-expression.cc @@ -303,7 +303,8 @@ libtextclassifier3::StatusOr<std::unique_ptr<DocumentFunctionScoreExpression>> DocumentFunctionScoreExpression::Create( FunctionType function_type, std::vector<std::unique_ptr<ScoreExpression>> args, - const DocumentStore* document_store, double default_score) { + const DocumentStore* document_store, double default_score, + int64_t current_time_ms) { if (args.empty()) { return absl_ports::InvalidArgumentError( "Document-based functions must have at least one argument."); @@ -336,7 +337,8 @@ DocumentFunctionScoreExpression::Create( } return std::unique_ptr<DocumentFunctionScoreExpression>( new DocumentFunctionScoreExpression(function_type, std::move(args), - document_store, default_score)); + document_store, default_score, + current_time_ms)); } libtextclassifier3::StatusOr<double> DocumentFunctionScoreExpression::eval( @@ -365,7 +367,8 @@ libtextclassifier3::StatusOr<double> DocumentFunctionScoreExpression::eval( "Usage type must be an integer from 1 to 3"); } std::optional<UsageStore::UsageScores> usage_scores = - document_store_.GetUsageScores(hit_info.document_id()); + document_store_.GetUsageScores(hit_info.document_id(), + current_time_ms_); if (!usage_scores) { // If there's no UsageScores entry present for this doc, then just // treat it as a default instance. @@ -465,8 +468,8 @@ libtextclassifier3::StatusOr< std::unique_ptr<PropertyWeightsFunctionScoreExpression>> PropertyWeightsFunctionScoreExpression::Create( std::vector<std::unique_ptr<ScoreExpression>> args, - const DocumentStore* document_store, - const SectionWeights* section_weights) { + const DocumentStore* document_store, const SectionWeights* section_weights, + int64_t current_time_ms) { if (args.size() != 1) { return absl_ports::InvalidArgumentError( "propertyWeights must have 1 argument."); @@ -478,8 +481,8 @@ PropertyWeightsFunctionScoreExpression::Create( "propertyWeights must take \"this\" as its argument."); } return std::unique_ptr<PropertyWeightsFunctionScoreExpression>( - new PropertyWeightsFunctionScoreExpression(document_store, - section_weights)); + new PropertyWeightsFunctionScoreExpression( + document_store, section_weights, current_time_ms)); } libtextclassifier3::StatusOr<std::vector<double>> @@ -501,12 +504,12 @@ PropertyWeightsFunctionScoreExpression::eval_list( SchemaTypeId PropertyWeightsFunctionScoreExpression::GetSchemaTypeId( DocumentId document_id) const { auto filter_data_optional = - document_store_.GetAliveDocumentFilterData(document_id); + document_store_.GetAliveDocumentFilterData(document_id, current_time_ms_); if (!filter_data_optional) { // This should never happen. The only failure case for - // GetDocumentFilterData is if the document_id is outside of the range of - // allocated document_ids, which shouldn't be possible since we're getting - // this document_id from the posting lists. + // GetAliveDocumentFilterData is if the document_id is outside of the range + // of allocated document_ids, which shouldn't be possible since we're + // getting this document_id from the posting lists. ICING_LOG(WARNING) << "No document filter data for document [" << document_id << "]"; return kInvalidSchemaTypeId; diff --git a/icing/scoring/advanced_scoring/score-expression.h b/icing/scoring/advanced_scoring/score-expression.h index 3c721bf..08d7997 100644 --- a/icing/scoring/advanced_scoring/score-expression.h +++ b/icing/scoring/advanced_scoring/score-expression.h @@ -219,7 +219,8 @@ class DocumentFunctionScoreExpression : public ScoreExpression { std::unique_ptr<DocumentFunctionScoreExpression>> Create(FunctionType function_type, std::vector<std::unique_ptr<ScoreExpression>> args, - const DocumentStore* document_store, double default_score); + const DocumentStore* document_store, double default_score, + int64_t current_time_ms); libtextclassifier3::StatusOr<double> eval( const DocHitInfo& hit_info, @@ -233,16 +234,19 @@ class DocumentFunctionScoreExpression : public ScoreExpression { explicit DocumentFunctionScoreExpression( FunctionType function_type, std::vector<std::unique_ptr<ScoreExpression>> args, - const DocumentStore* document_store, double default_score) + const DocumentStore* document_store, double default_score, + int64_t current_time_ms) : args_(std::move(args)), document_store_(*document_store), default_score_(default_score), - function_type_(function_type) {} + function_type_(function_type), + current_time_ms_(current_time_ms) {} std::vector<std::unique_ptr<ScoreExpression>> args_; const DocumentStore& document_store_; double default_score_; FunctionType function_type_; + int64_t current_time_ms_; }; class RelevanceScoreFunctionScoreExpression : public ScoreExpression { @@ -315,7 +319,7 @@ class PropertyWeightsFunctionScoreExpression : public ScoreExpression { std::unique_ptr<PropertyWeightsFunctionScoreExpression>> Create(std::vector<std::unique_ptr<ScoreExpression>> args, const DocumentStore* document_store, - const SectionWeights* section_weights); + const SectionWeights* section_weights, int64_t current_time_ms); libtextclassifier3::StatusOr<std::vector<double>> eval_list( const DocHitInfo& hit_info, const DocHitInfoIterator*) const override; @@ -329,10 +333,13 @@ class PropertyWeightsFunctionScoreExpression : public ScoreExpression { private: explicit PropertyWeightsFunctionScoreExpression( const DocumentStore* document_store, - const SectionWeights* section_weights) - : document_store_(*document_store), section_weights_(*section_weights) {} + const SectionWeights* section_weights, int64_t current_time_ms) + : document_store_(*document_store), + section_weights_(*section_weights), + current_time_ms_(current_time_ms) {} const DocumentStore& document_store_; const SectionWeights& section_weights_; + int64_t current_time_ms_; }; } // namespace lib diff --git a/icing/scoring/advanced_scoring/scoring-visitor.cc b/icing/scoring/advanced_scoring/scoring-visitor.cc index 14bc4d5..e2b24a2 100644 --- a/icing/scoring/advanced_scoring/scoring-visitor.cc +++ b/icing/scoring/advanced_scoring/scoring-visitor.cc @@ -72,7 +72,7 @@ void ScoringVisitor::VisitMember(const MemberNode* node) { absl_ports::StrCat("Expect a numeric literal, but got ", value)); return; } - stack.push_back(ConstantScoreExpression::Create(number)); + stack_.push_back(ConstantScoreExpression::Create(number)); } void ScoringVisitor::VisitFunctionHelper(const FunctionNode* node, @@ -98,7 +98,7 @@ void ScoringVisitor::VisitFunctionHelper(const FunctionNode* node, // Document-based function expression = DocumentFunctionScoreExpression::Create( DocumentFunctionScoreExpression::kFunctionNames.at(function_name), - std::move(args), &document_store_, default_score_); + std::move(args), &document_store_, default_score_, current_time_ms_); } else if (function_name == RelevanceScoreFunctionScoreExpression::kFunctionName) { // relevanceScore function @@ -113,7 +113,7 @@ void ScoringVisitor::VisitFunctionHelper(const FunctionNode* node, PropertyWeightsFunctionScoreExpression::kFunctionName) { // propertyWeights function expression = PropertyWeightsFunctionScoreExpression::Create( - std::move(args), &document_store_, §ion_weights_); + std::move(args), &document_store_, §ion_weights_, current_time_ms_); } else if (MathFunctionScoreExpression::kFunctionNames.find(function_name) != MathFunctionScoreExpression::kFunctionNames.end()) { // Math functions @@ -126,7 +126,7 @@ void ScoringVisitor::VisitFunctionHelper(const FunctionNode* node, pending_error_ = expression.status(); return; } - stack.push_back(std::move(expression).ValueOrDie()); + stack_.push_back(std::move(expression).ValueOrDie()); } void ScoringVisitor::VisitUnaryOperator(const UnaryOperatorNode* node) { @@ -150,7 +150,7 @@ void ScoringVisitor::VisitUnaryOperator(const UnaryOperatorNode* node) { pending_error_ = expression.status(); return; } - stack.push_back(std::move(expression).ValueOrDie()); + stack_.push_back(std::move(expression).ValueOrDie()); } void ScoringVisitor::VisitNaryOperator(const NaryOperatorNode* node) { @@ -184,7 +184,7 @@ void ScoringVisitor::VisitNaryOperator(const NaryOperatorNode* node) { pending_error_ = expression.status(); return; } - stack.push_back(std::move(expression).ValueOrDie()); + stack_.push_back(std::move(expression).ValueOrDie()); } } // namespace lib diff --git a/icing/scoring/advanced_scoring/scoring-visitor.h b/icing/scoring/advanced_scoring/scoring-visitor.h index 9d9c105..cfee25b 100644 --- a/icing/scoring/advanced_scoring/scoring-visitor.h +++ b/icing/scoring/advanced_scoring/scoring-visitor.h @@ -35,13 +35,15 @@ class ScoringVisitor : public AbstractSyntaxTreeVisitor { const SchemaStore* schema_store, SectionWeights* section_weights, Bm25fCalculator* bm25f_calculator, - const JoinChildrenFetcher* join_children_fetcher) + const JoinChildrenFetcher* join_children_fetcher, + int64_t current_time_ms) : default_score_(default_score), document_store_(*document_store), schema_store_(*schema_store), section_weights_(*section_weights), bm25f_calculator_(*bm25f_calculator), - join_children_fetcher_(join_children_fetcher) {} + join_children_fetcher_(join_children_fetcher), + current_time_ms_(current_time_ms) {} void VisitFunctionName(const FunctionNameNode* node) override; void VisitString(const StringNode* node) override; @@ -65,13 +67,13 @@ class ScoringVisitor : public AbstractSyntaxTreeVisitor { if (has_pending_error()) { return pending_error_; } - if (stack.size() != 1) { + if (stack_.size() != 1) { return absl_ports::InternalError(IcingStringUtil::StringPrintf( "Expect to get only one result from " "ScoringVisitor, but got %zu. There must be inconsistencies.", - stack.size())); + stack_.size())); } - return std::move(stack[0]); + return std::move(stack_[0]); } private: @@ -82,8 +84,8 @@ class ScoringVisitor : public AbstractSyntaxTreeVisitor { bool has_pending_error() const { return !pending_error_.ok(); } std::unique_ptr<ScoreExpression> pop_stack() { - std::unique_ptr<ScoreExpression> result = std::move(stack.back()); - stack.pop_back(); + std::unique_ptr<ScoreExpression> result = std::move(stack_.back()); + stack_.pop_back(); return result; } @@ -96,7 +98,8 @@ class ScoringVisitor : public AbstractSyntaxTreeVisitor { const JoinChildrenFetcher* join_children_fetcher_; // Does not own. libtextclassifier3::Status pending_error_; - std::vector<std::unique_ptr<ScoreExpression>> stack; + std::vector<std::unique_ptr<ScoreExpression>> stack_; + int64_t current_time_ms_; }; } // namespace lib diff --git a/icing/scoring/bm25f-calculator.cc b/icing/scoring/bm25f-calculator.cc index 9120cc7..a80ef34 100644 --- a/icing/scoring/bm25f-calculator.cc +++ b/icing/scoring/bm25f-calculator.cc @@ -43,8 +43,11 @@ constexpr float b_ = 0.7f; // TODO(b/158603900): add tests for Bm25fCalculator Bm25fCalculator::Bm25fCalculator(const DocumentStore* document_store, - SectionWeights* section_weights) - : document_store_(document_store), section_weights_(*section_weights) {} + SectionWeights* section_weights, + int64_t current_time_ms) + : document_store_(document_store), + section_weights_(*section_weights), + current_time_ms_(current_time_ms) {} // During initialization, Bm25fCalculator iterates through // hit-iterators for each query term to pre-compute n(q_i) for each corpus under @@ -227,13 +230,13 @@ float Bm25fCalculator::ComputeTermFrequencyForMatchedSections( } SchemaTypeId Bm25fCalculator::GetSchemaTypeId(DocumentId document_id) const { - auto filter_data_optional = - document_store_->GetAliveDocumentFilterData(document_id); + auto filter_data_optional = document_store_->GetAliveDocumentFilterData( + document_id, current_time_ms_); if (!filter_data_optional) { // This should never happen. The only failure case for - // GetDocumentFilterData is if the document_id is outside of the range of - // allocated document_ids, which shouldn't be possible since we're getting - // this document_id from the posting lists. + // GetAliveDocumentFilterData is if the document_id is outside of the range + // of allocated document_ids, which shouldn't be possible since we're + // getting this document_id from the posting lists. ICING_LOG(WARNING) << "No document filter data for document [" << document_id << "]"; return kInvalidSchemaTypeId; diff --git a/icing/scoring/bm25f-calculator.h b/icing/scoring/bm25f-calculator.h index dc5e081..36f9c68 100644 --- a/icing/scoring/bm25f-calculator.h +++ b/icing/scoring/bm25f-calculator.h @@ -64,7 +64,8 @@ namespace lib { class Bm25fCalculator { public: explicit Bm25fCalculator(const DocumentStore *document_store, - SectionWeights *section_weights); + SectionWeights *section_weights, + int64_t current_time_ms); // Precompute and cache statistics relevant to BM25F. // Populates term_id_map_ and corpus_nqi_map_ for use while scoring other @@ -166,6 +167,8 @@ class Bm25fCalculator { // Map from <corpus ID, term ID> to IDF(q_i) (inverse document frequency). std::unordered_map<CorpusTermInfo::Value, float> corpus_idf_map_; + + int64_t current_time_ms_; }; } // namespace lib diff --git a/icing/scoring/score-and-rank_benchmark.cc b/icing/scoring/score-and-rank_benchmark.cc index ddc21a2..abb019f 100644 --- a/icing/scoring/score-and-rank_benchmark.cc +++ b/icing/scoring/score-and-rank_benchmark.cc @@ -133,7 +133,8 @@ void BM_ScoreAndRankDocumentHitsByDocumentScore(benchmark::State& state) { ICING_ASSERT_OK_AND_ASSIGN( std::unique_ptr<ScoringProcessor> scoring_processor, ScoringProcessor::Create(scoring_spec, document_store.get(), - schema_store.get())); + schema_store.get(), + clock.GetSystemTimeMilliseconds())); int num_to_score = state.range(0); int num_of_documents = state.range(1); @@ -238,7 +239,8 @@ void BM_ScoreAndRankDocumentHitsByCreationTime(benchmark::State& state) { ICING_ASSERT_OK_AND_ASSIGN( std::unique_ptr<ScoringProcessor> scoring_processor, ScoringProcessor::Create(scoring_spec, document_store.get(), - schema_store.get())); + schema_store.get(), + clock.GetSystemTimeMilliseconds())); int num_to_score = state.range(0); int num_of_documents = state.range(1); @@ -344,7 +346,8 @@ void BM_ScoreAndRankDocumentHitsNoScoring(benchmark::State& state) { ICING_ASSERT_OK_AND_ASSIGN( std::unique_ptr<ScoringProcessor> scoring_processor, ScoringProcessor::Create(scoring_spec, document_store.get(), - schema_store.get())); + schema_store.get(), + clock.GetSystemTimeMilliseconds())); int num_to_score = state.range(0); int num_of_documents = state.range(1); @@ -445,7 +448,8 @@ void BM_ScoreAndRankDocumentHitsByRelevanceScoring(benchmark::State& state) { ICING_ASSERT_OK_AND_ASSIGN( std::unique_ptr<ScoringProcessor> scoring_processor, ScoringProcessor::Create(scoring_spec, document_store.get(), - schema_store.get())); + schema_store.get(), + clock.GetSystemTimeMilliseconds())); int num_to_score = state.range(0); int num_of_documents = state.range(1); diff --git a/icing/scoring/scorer-factory.cc b/icing/scoring/scorer-factory.cc index 5b8609b..e56f10c 100644 --- a/icing/scoring/scorer-factory.cc +++ b/icing/scoring/scorer-factory.cc @@ -111,15 +111,17 @@ class UsageScorer : public Scorer { public: UsageScorer(const DocumentStore* document_store, ScoringSpecProto::RankingStrategy::Code ranking_strategy, - double default_score) + double default_score, int64_t current_time_ms) : document_store_(*document_store), ranking_strategy_(ranking_strategy), - default_score_(default_score) {} + default_score_(default_score), + current_time_ms_(current_time_ms) {} double GetScore(const DocHitInfo& hit_info, const DocHitInfoIterator*) override { std::optional<UsageStore::UsageScores> usage_scores = - document_store_.GetUsageScores(hit_info.document_id()); + document_store_.GetUsageScores(hit_info.document_id(), + current_time_ms_); if (!usage_scores) { // If there's no UsageScores entry present for this doc, then just // treat it as a default instance. @@ -149,6 +151,7 @@ class UsageScorer : public Scorer { const DocumentStore& document_store_; ScoringSpecProto::RankingStrategy::Code ranking_strategy_; double default_score_; + int64_t current_time_ms_; }; // A special scorer which does nothing but assigns the default score to each @@ -171,7 +174,7 @@ namespace scorer_factory { libtextclassifier3::StatusOr<std::unique_ptr<Scorer>> Create( const ScoringSpecProto& scoring_spec, double default_score, const DocumentStore* document_store, const SchemaStore* schema_store, - const JoinChildrenFetcher* join_children_fetcher) { + int64_t current_time_ms, const JoinChildrenFetcher* join_children_fetcher) { ICING_RETURN_ERROR_IF_NULL(document_store); ICING_RETURN_ERROR_IF_NULL(schema_store); @@ -196,7 +199,7 @@ libtextclassifier3::StatusOr<std::unique_ptr<Scorer>> Create( SectionWeights::Create(schema_store, scoring_spec)); auto bm25f_calculator = std::make_unique<Bm25fCalculator>( - document_store, section_weights.get()); + document_store, section_weights.get(), current_time_ms); return std::make_unique<RelevanceScoreScorer>(std::move(section_weights), std::move(bm25f_calculator), default_score); @@ -212,15 +215,17 @@ libtextclassifier3::StatusOr<std::unique_ptr<Scorer>> Create( case ScoringSpecProto::RankingStrategy::USAGE_TYPE2_LAST_USED_TIMESTAMP: [[fallthrough]]; case ScoringSpecProto::RankingStrategy::USAGE_TYPE3_LAST_USED_TIMESTAMP: - return std::make_unique<UsageScorer>( - document_store, scoring_spec.rank_by(), default_score); + return std::make_unique<UsageScorer>(document_store, + scoring_spec.rank_by(), + default_score, current_time_ms); case ScoringSpecProto::RankingStrategy::ADVANCED_SCORING_EXPRESSION: if (scoring_spec.advanced_scoring_expression().empty()) { return absl_ports::InvalidArgumentError( "Advanced scoring is enabled, but the expression is empty!"); } return AdvancedScorer::Create(scoring_spec, default_score, document_store, - schema_store, join_children_fetcher); + schema_store, current_time_ms, + join_children_fetcher); case ScoringSpecProto::RankingStrategy::JOIN_AGGREGATE_SCORE: // Use join aggregate score to rank. Since the aggregation score is // calculated by child documents after joining (in JoinProcessor), we can diff --git a/icing/scoring/scorer-factory.h b/icing/scoring/scorer-factory.h index 460e5bb..659bebd 100644 --- a/icing/scoring/scorer-factory.h +++ b/icing/scoring/scorer-factory.h @@ -38,6 +38,7 @@ namespace scorer_factory { libtextclassifier3::StatusOr<std::unique_ptr<Scorer>> Create( const ScoringSpecProto& scoring_spec, double default_score, const DocumentStore* document_store, const SchemaStore* schema_store, + int64_t current_time_ms, const JoinChildrenFetcher* join_children_fetcher = nullptr); } // namespace scorer_factory diff --git a/icing/scoring/scorer_test.cc b/icing/scoring/scorer_test.cc index 1c7d2ab..4a97a87 100644 --- a/icing/scoring/scorer_test.cc +++ b/icing/scoring/scorer_test.cc @@ -133,7 +133,8 @@ TEST_P(ScorerTest, CreationWithNullDocumentStoreShouldFail) { scorer_factory::Create( CreateScoringSpecForRankingStrategy( ScoringSpecProto::RankingStrategy::DOCUMENT_SCORE, GetParam()), - /*default_score=*/0, /*document_store=*/nullptr, schema_store()), + /*default_score=*/0, /*document_store=*/nullptr, schema_store(), + fake_clock1().GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::FAILED_PRECONDITION)); } @@ -143,7 +144,7 @@ TEST_P(ScorerTest, CreationWithNullSchemaStoreShouldFail) { CreateScoringSpecForRankingStrategy( ScoringSpecProto::RankingStrategy::DOCUMENT_SCORE, GetParam()), /*default_score=*/0, document_store(), - /*schema_store=*/nullptr), + /*schema_store=*/nullptr, fake_clock1().GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::FAILED_PRECONDITION)); } @@ -153,7 +154,8 @@ TEST_P(ScorerTest, ShouldGetDefaultScoreIfDocumentDoesntExist) { scorer_factory::Create( CreateScoringSpecForRankingStrategy( ScoringSpecProto::RankingStrategy::DOCUMENT_SCORE, GetParam()), - /*default_score=*/10, document_store(), schema_store())); + /*default_score=*/10, document_store(), schema_store(), + fake_clock1().GetSystemTimeMilliseconds())); // Non existent document id DocHitInfo docHitInfo = DocHitInfo(/*document_id_in=*/1); @@ -161,70 +163,6 @@ TEST_P(ScorerTest, ShouldGetDefaultScoreIfDocumentDoesntExist) { EXPECT_THAT(scorer->GetScore(docHitInfo), Eq(10)); } -TEST_P(ScorerTest, ShouldGetDefaultScoreIfDocumentIsDeleted) { - // Creates a test document with a provided score - DocumentProto test_document = DocumentBuilder() - .SetKey("icing", "email/1") - .SetSchema("email") - .AddStringProperty("subject", "subject foo") - .SetScore(42) - .Build(); - - ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id, - document_store()->Put(test_document)); - - ICING_ASSERT_OK_AND_ASSIGN( - std::unique_ptr<Scorer> scorer, - scorer_factory::Create( - CreateScoringSpecForRankingStrategy( - ScoringSpecProto::RankingStrategy::DOCUMENT_SCORE, GetParam()), - /*default_score=*/10, document_store(), schema_store())); - - DocHitInfo docHitInfo = DocHitInfo(document_id); - - // The document's score is returned - EXPECT_THAT(scorer->GetScore(docHitInfo), Eq(42)); - - // Delete the document and check that the caller-provided default score is - // returned - EXPECT_THAT(document_store()->Delete(document_id), IsOk()); - EXPECT_THAT(scorer->GetScore(docHitInfo), Eq(10)); -} - -TEST_P(ScorerTest, ShouldGetDefaultScoreIfDocumentIsExpired) { - // Creates a test document with a provided score - int64_t creation_time = fake_clock1().GetSystemTimeMilliseconds(); - int64_t ttl = 100; - DocumentProto test_document = DocumentBuilder() - .SetKey("icing", "email/1") - .SetSchema("email") - .AddStringProperty("subject", "subject foo") - .SetScore(42) - .SetCreationTimestampMs(creation_time) - .SetTtlMs(ttl) - .Build(); - - ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id, - document_store()->Put(test_document)); - - ICING_ASSERT_OK_AND_ASSIGN( - std::unique_ptr<Scorer> scorer, - scorer_factory::Create( - CreateScoringSpecForRankingStrategy( - ScoringSpecProto::RankingStrategy::DOCUMENT_SCORE, GetParam()), - /*default_score=*/10, document_store(), schema_store())); - - DocHitInfo docHitInfo = DocHitInfo(document_id); - - // The document's score is returned since the document hasn't expired yet. - EXPECT_THAT(scorer->GetScore(docHitInfo), Eq(42)); - - // Expire the document and check that the caller-provided default score is - // returned - SetFakeClock1Time(creation_time + ttl + 10); - EXPECT_THAT(scorer->GetScore(docHitInfo), Eq(10)); -} - TEST_P(ScorerTest, ShouldGetDefaultDocumentScore) { // Creates a test document with the default document score 0 DocumentProto test_document = @@ -242,7 +180,8 @@ TEST_P(ScorerTest, ShouldGetDefaultDocumentScore) { scorer_factory::Create( CreateScoringSpecForRankingStrategy( ScoringSpecProto::RankingStrategy::DOCUMENT_SCORE, GetParam()), - /*default_score=*/10, document_store(), schema_store())); + /*default_score=*/10, document_store(), schema_store(), + fake_clock1().GetSystemTimeMilliseconds())); DocHitInfo docHitInfo = DocHitInfo(document_id); EXPECT_THAT(scorer->GetScore(docHitInfo), Eq(0)); @@ -266,7 +205,8 @@ TEST_P(ScorerTest, ShouldGetCorrectDocumentScore) { scorer_factory::Create( CreateScoringSpecForRankingStrategy( ScoringSpecProto::RankingStrategy::DOCUMENT_SCORE, GetParam()), - /*default_score=*/0, document_store(), schema_store())); + /*default_score=*/0, document_store(), schema_store(), + fake_clock1().GetSystemTimeMilliseconds())); DocHitInfo docHitInfo = DocHitInfo(document_id); EXPECT_THAT(scorer->GetScore(docHitInfo), Eq(5)); @@ -292,7 +232,8 @@ TEST_P(ScorerTest, QueryIteratorNullRelevanceScoreShouldReturnDefaultScore) { scorer_factory::Create( CreateScoringSpecForRankingStrategy( ScoringSpecProto::RankingStrategy::RELEVANCE_SCORE, GetParam()), - /*default_score=*/10, document_store(), schema_store())); + /*default_score=*/10, document_store(), schema_store(), + fake_clock1().GetSystemTimeMilliseconds())); DocHitInfo docHitInfo = DocHitInfo(document_id); EXPECT_THAT(scorer->GetScore(docHitInfo), Eq(10)); @@ -326,7 +267,8 @@ TEST_P(ScorerTest, ShouldGetCorrectCreationTimestampScore) { CreateScoringSpecForRankingStrategy( ScoringSpecProto::RankingStrategy::CREATION_TIMESTAMP, GetParam()), - /*default_score=*/0, document_store(), schema_store())); + /*default_score=*/0, document_store(), schema_store(), + fake_clock1().GetSystemTimeMilliseconds())); DocHitInfo docHitInfo1 = DocHitInfo(document_id1); DocHitInfo docHitInfo2 = DocHitInfo(document_id2); @@ -354,19 +296,22 @@ TEST_P(ScorerTest, ShouldGetCorrectUsageCountScoreForType1) { scorer_factory::Create( CreateScoringSpecForRankingStrategy( ScoringSpecProto::RankingStrategy::USAGE_TYPE1_COUNT, GetParam()), - /*default_score=*/0, document_store(), schema_store())); + /*default_score=*/0, document_store(), schema_store(), + fake_clock1().GetSystemTimeMilliseconds())); ICING_ASSERT_OK_AND_ASSIGN( std::unique_ptr<Scorer> scorer2, scorer_factory::Create( CreateScoringSpecForRankingStrategy( ScoringSpecProto::RankingStrategy::USAGE_TYPE2_COUNT, GetParam()), - /*default_score=*/0, document_store(), schema_store())); + /*default_score=*/0, document_store(), schema_store(), + fake_clock1().GetSystemTimeMilliseconds())); ICING_ASSERT_OK_AND_ASSIGN( std::unique_ptr<Scorer> scorer3, scorer_factory::Create( CreateScoringSpecForRankingStrategy( ScoringSpecProto::RankingStrategy::USAGE_TYPE3_COUNT, GetParam()), - /*default_score=*/0, document_store(), schema_store())); + /*default_score=*/0, document_store(), schema_store(), + fake_clock1().GetSystemTimeMilliseconds())); DocHitInfo docHitInfo = DocHitInfo(document_id); EXPECT_THAT(scorer1->GetScore(docHitInfo), Eq(0)); EXPECT_THAT(scorer2->GetScore(docHitInfo), Eq(0)); @@ -401,19 +346,22 @@ TEST_P(ScorerTest, ShouldGetCorrectUsageCountScoreForType2) { scorer_factory::Create( CreateScoringSpecForRankingStrategy( ScoringSpecProto::RankingStrategy::USAGE_TYPE1_COUNT, GetParam()), - /*default_score=*/0, document_store(), schema_store())); + /*default_score=*/0, document_store(), schema_store(), + fake_clock1().GetSystemTimeMilliseconds())); ICING_ASSERT_OK_AND_ASSIGN( std::unique_ptr<Scorer> scorer2, scorer_factory::Create( CreateScoringSpecForRankingStrategy( ScoringSpecProto::RankingStrategy::USAGE_TYPE2_COUNT, GetParam()), - /*default_score=*/0, document_store(), schema_store())); + /*default_score=*/0, document_store(), schema_store(), + fake_clock1().GetSystemTimeMilliseconds())); ICING_ASSERT_OK_AND_ASSIGN( std::unique_ptr<Scorer> scorer3, scorer_factory::Create( CreateScoringSpecForRankingStrategy( ScoringSpecProto::RankingStrategy::USAGE_TYPE3_COUNT, GetParam()), - /*default_score=*/0, document_store(), schema_store())); + /*default_score=*/0, document_store(), schema_store(), + fake_clock1().GetSystemTimeMilliseconds())); DocHitInfo docHitInfo = DocHitInfo(document_id); EXPECT_THAT(scorer1->GetScore(docHitInfo), Eq(0)); EXPECT_THAT(scorer2->GetScore(docHitInfo), Eq(0)); @@ -448,19 +396,22 @@ TEST_P(ScorerTest, ShouldGetCorrectUsageCountScoreForType3) { scorer_factory::Create( CreateScoringSpecForRankingStrategy( ScoringSpecProto::RankingStrategy::USAGE_TYPE1_COUNT, GetParam()), - /*default_score=*/0, document_store(), schema_store())); + /*default_score=*/0, document_store(), schema_store(), + fake_clock1().GetSystemTimeMilliseconds())); ICING_ASSERT_OK_AND_ASSIGN( std::unique_ptr<Scorer> scorer2, scorer_factory::Create( CreateScoringSpecForRankingStrategy( ScoringSpecProto::RankingStrategy::USAGE_TYPE2_COUNT, GetParam()), - /*default_score=*/0, document_store(), schema_store())); + /*default_score=*/0, document_store(), schema_store(), + fake_clock1().GetSystemTimeMilliseconds())); ICING_ASSERT_OK_AND_ASSIGN( std::unique_ptr<Scorer> scorer3, scorer_factory::Create( CreateScoringSpecForRankingStrategy( ScoringSpecProto::RankingStrategy::USAGE_TYPE3_COUNT, GetParam()), - /*default_score=*/0, document_store(), schema_store())); + /*default_score=*/0, document_store(), schema_store(), + fake_clock1().GetSystemTimeMilliseconds())); DocHitInfo docHitInfo = DocHitInfo(document_id); EXPECT_THAT(scorer1->GetScore(docHitInfo), Eq(0)); EXPECT_THAT(scorer2->GetScore(docHitInfo), Eq(0)); @@ -497,7 +448,8 @@ TEST_P(ScorerTest, ShouldGetCorrectUsageTimestampScoreForType1) { USAGE_TYPE1_LAST_USED_TIMESTAMP, GetParam()), /*default_score=*/0, document_store(), - schema_store())); + schema_store(), + fake_clock1().GetSystemTimeMilliseconds())); ICING_ASSERT_OK_AND_ASSIGN( std::unique_ptr<Scorer> scorer2, scorer_factory::Create(CreateScoringSpecForRankingStrategy( @@ -505,7 +457,8 @@ TEST_P(ScorerTest, ShouldGetCorrectUsageTimestampScoreForType1) { USAGE_TYPE2_LAST_USED_TIMESTAMP, GetParam()), /*default_score=*/0, document_store(), - schema_store())); + schema_store(), + fake_clock1().GetSystemTimeMilliseconds())); ICING_ASSERT_OK_AND_ASSIGN( std::unique_ptr<Scorer> scorer3, scorer_factory::Create(CreateScoringSpecForRankingStrategy( @@ -513,7 +466,8 @@ TEST_P(ScorerTest, ShouldGetCorrectUsageTimestampScoreForType1) { USAGE_TYPE3_LAST_USED_TIMESTAMP, GetParam()), /*default_score=*/0, document_store(), - schema_store())); + schema_store(), + fake_clock1().GetSystemTimeMilliseconds())); DocHitInfo docHitInfo = DocHitInfo(document_id); EXPECT_THAT(scorer1->GetScore(docHitInfo), Eq(0)); EXPECT_THAT(scorer2->GetScore(docHitInfo), Eq(0)); @@ -566,7 +520,8 @@ TEST_P(ScorerTest, ShouldGetCorrectUsageTimestampScoreForType2) { USAGE_TYPE1_LAST_USED_TIMESTAMP, GetParam()), /*default_score=*/0, document_store(), - schema_store())); + schema_store(), + fake_clock1().GetSystemTimeMilliseconds())); ICING_ASSERT_OK_AND_ASSIGN( std::unique_ptr<Scorer> scorer2, scorer_factory::Create(CreateScoringSpecForRankingStrategy( @@ -574,7 +529,8 @@ TEST_P(ScorerTest, ShouldGetCorrectUsageTimestampScoreForType2) { USAGE_TYPE2_LAST_USED_TIMESTAMP, GetParam()), /*default_score=*/0, document_store(), - schema_store())); + schema_store(), + fake_clock1().GetSystemTimeMilliseconds())); ICING_ASSERT_OK_AND_ASSIGN( std::unique_ptr<Scorer> scorer3, scorer_factory::Create(CreateScoringSpecForRankingStrategy( @@ -582,7 +538,8 @@ TEST_P(ScorerTest, ShouldGetCorrectUsageTimestampScoreForType2) { USAGE_TYPE3_LAST_USED_TIMESTAMP, GetParam()), /*default_score=*/0, document_store(), - schema_store())); + schema_store(), + fake_clock1().GetSystemTimeMilliseconds())); DocHitInfo docHitInfo = DocHitInfo(document_id); EXPECT_THAT(scorer1->GetScore(docHitInfo), Eq(0)); EXPECT_THAT(scorer2->GetScore(docHitInfo), Eq(0)); @@ -635,7 +592,8 @@ TEST_P(ScorerTest, ShouldGetCorrectUsageTimestampScoreForType3) { USAGE_TYPE1_LAST_USED_TIMESTAMP, GetParam()), /*default_score=*/0, document_store(), - schema_store())); + schema_store(), + fake_clock1().GetSystemTimeMilliseconds())); ICING_ASSERT_OK_AND_ASSIGN( std::unique_ptr<Scorer> scorer2, scorer_factory::Create(CreateScoringSpecForRankingStrategy( @@ -643,7 +601,8 @@ TEST_P(ScorerTest, ShouldGetCorrectUsageTimestampScoreForType3) { USAGE_TYPE2_LAST_USED_TIMESTAMP, GetParam()), /*default_score=*/0, document_store(), - schema_store())); + schema_store(), + fake_clock1().GetSystemTimeMilliseconds())); ICING_ASSERT_OK_AND_ASSIGN( std::unique_ptr<Scorer> scorer3, scorer_factory::Create(CreateScoringSpecForRankingStrategy( @@ -651,7 +610,8 @@ TEST_P(ScorerTest, ShouldGetCorrectUsageTimestampScoreForType3) { USAGE_TYPE3_LAST_USED_TIMESTAMP, GetParam()), /*default_score=*/0, document_store(), - schema_store())); + schema_store(), + fake_clock1().GetSystemTimeMilliseconds())); DocHitInfo docHitInfo = DocHitInfo(document_id); EXPECT_THAT(scorer1->GetScore(docHitInfo), Eq(0)); EXPECT_THAT(scorer2->GetScore(docHitInfo), Eq(0)); @@ -690,7 +650,8 @@ TEST_P(ScorerTest, NoScorerShouldAlwaysReturnDefaultScore) { scorer_factory::Create( CreateScoringSpecForRankingStrategy( ScoringSpecProto::RankingStrategy::NONE, GetParam()), - /*default_score=*/3, document_store(), schema_store())); + /*default_score=*/3, document_store(), schema_store(), + fake_clock1().GetSystemTimeMilliseconds())); DocHitInfo docHitInfo1 = DocHitInfo(/*document_id_in=*/0); DocHitInfo docHitInfo2 = DocHitInfo(/*document_id_in=*/1); @@ -703,7 +664,8 @@ TEST_P(ScorerTest, NoScorerShouldAlwaysReturnDefaultScore) { scorer, scorer_factory::Create( CreateScoringSpecForRankingStrategy( ScoringSpecProto::RankingStrategy::NONE, GetParam()), - /*default_score=*/111, document_store(), schema_store())); + /*default_score=*/111, document_store(), schema_store(), + fake_clock1().GetSystemTimeMilliseconds())); docHitInfo1 = DocHitInfo(/*document_id_in=*/4); docHitInfo2 = DocHitInfo(/*document_id_in=*/5); @@ -732,7 +694,8 @@ TEST_P(ScorerTest, ShouldScaleUsageTimestampScoreForMaxTimestamp) { USAGE_TYPE1_LAST_USED_TIMESTAMP, GetParam()), /*default_score=*/0, document_store(), - schema_store())); + schema_store(), + fake_clock1().GetSystemTimeMilliseconds())); DocHitInfo docHitInfo = DocHitInfo(document_id); // Create usage report for the maximum allowable timestamp. diff --git a/icing/scoring/scoring-processor.cc b/icing/scoring/scoring-processor.cc index 894852d..8284426 100644 --- a/icing/scoring/scoring-processor.cc +++ b/icing/scoring/scoring-processor.cc @@ -44,6 +44,7 @@ libtextclassifier3::StatusOr<std::unique_ptr<ScoringProcessor>> ScoringProcessor::Create(const ScoringSpecProto& scoring_spec, const DocumentStore* document_store, const SchemaStore* schema_store, + int64_t current_time_ms, const JoinChildrenFetcher* join_children_fetcher) { ICING_RETURN_ERROR_IF_NULL(document_store); ICING_RETURN_ERROR_IF_NULL(schema_store); @@ -53,11 +54,12 @@ ScoringProcessor::Create(const ScoringSpecProto& scoring_spec, ICING_ASSIGN_OR_RETURN( std::unique_ptr<Scorer> scorer, - scorer_factory::Create( - scoring_spec, - is_descending_order ? kDefaultScoreInDescendingOrder - : kDefaultScoreInAscendingOrder, - document_store, schema_store, join_children_fetcher)); + scorer_factory::Create(scoring_spec, + is_descending_order + ? kDefaultScoreInDescendingOrder + : kDefaultScoreInAscendingOrder, + document_store, schema_store, current_time_ms, + join_children_fetcher)); // Using `new` to access a non-public constructor. return std::unique_ptr<ScoringProcessor>( new ScoringProcessor(std::move(scorer))); diff --git a/icing/scoring/scoring-processor.h b/icing/scoring/scoring-processor.h index 9cd4d85..e9efda7 100644 --- a/icing/scoring/scoring-processor.h +++ b/icing/scoring/scoring-processor.h @@ -42,7 +42,7 @@ class ScoringProcessor { // FAILED_PRECONDITION on any null pointer input static libtextclassifier3::StatusOr<std::unique_ptr<ScoringProcessor>> Create( const ScoringSpecProto& scoring_spec, const DocumentStore* document_store, - const SchemaStore* schema_store, + const SchemaStore* schema_store, int64_t current_time_ms, const JoinChildrenFetcher* join_children_fetcher = nullptr); // Assigns scores to DocHitInfos from the given DocHitInfoIterator and returns diff --git a/icing/scoring/scoring-processor_test.cc b/icing/scoring/scoring-processor_test.cc index 10f3eb5..644e013 100644 --- a/icing/scoring/scoring-processor_test.cc +++ b/icing/scoring/scoring-processor_test.cc @@ -108,6 +108,8 @@ class ScoringProcessorTest SchemaStore* schema_store() { return schema_store_.get(); } + const FakeClock& fake_clock() const { return fake_clock_; } + private: const std::string test_dir_; const std::string doc_store_dir_; @@ -184,23 +186,27 @@ PropertyWeight CreatePropertyWeight(std::string path, double weight) { TEST_F(ScoringProcessorTest, CreationWithNullDocumentStoreShouldFail) { ScoringSpecProto spec_proto; - EXPECT_THAT(ScoringProcessor::Create(spec_proto, /*document_store=*/nullptr, - schema_store()), + EXPECT_THAT(ScoringProcessor::Create( + spec_proto, /*document_store=*/nullptr, schema_store(), + fake_clock().GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::FAILED_PRECONDITION)); } TEST_F(ScoringProcessorTest, CreationWithNullSchemaStoreShouldFail) { ScoringSpecProto spec_proto; - EXPECT_THAT(ScoringProcessor::Create(spec_proto, document_store(), - /*schema_store=*/nullptr), - StatusIs(libtextclassifier3::StatusCode::FAILED_PRECONDITION)); + EXPECT_THAT( + ScoringProcessor::Create(spec_proto, document_store(), + /*schema_store=*/nullptr, + fake_clock().GetSystemTimeMilliseconds()), + StatusIs(libtextclassifier3::StatusCode::FAILED_PRECONDITION)); } TEST_P(ScoringProcessorTest, ShouldCreateInstance) { ScoringSpecProto spec_proto = CreateScoringSpecForRankingStrategy( ScoringSpecProto::RankingStrategy::DOCUMENT_SCORE, GetParam()); ICING_EXPECT_OK( - ScoringProcessor::Create(spec_proto, document_store(), schema_store())); + ScoringProcessor::Create(spec_proto, document_store(), schema_store(), + fake_clock().GetSystemTimeMilliseconds())); } TEST_P(ScoringProcessorTest, ShouldHandleEmptyDocHitIterator) { @@ -215,7 +221,8 @@ TEST_P(ScoringProcessorTest, ShouldHandleEmptyDocHitIterator) { // Creates a ScoringProcessor ICING_ASSERT_OK_AND_ASSIGN( std::unique_ptr<ScoringProcessor> scoring_processor, - ScoringProcessor::Create(spec_proto, document_store(), schema_store())); + ScoringProcessor::Create(spec_proto, document_store(), schema_store(), + fake_clock().GetSystemTimeMilliseconds())); EXPECT_THAT(scoring_processor->Score(std::move(doc_hit_info_iterator), /*num_to_score=*/5), @@ -241,7 +248,8 @@ TEST_P(ScoringProcessorTest, ShouldHandleNonPositiveNumToScore) { // Creates a ScoringProcessor ICING_ASSERT_OK_AND_ASSIGN( std::unique_ptr<ScoringProcessor> scoring_processor, - ScoringProcessor::Create(spec_proto, document_store(), schema_store())); + ScoringProcessor::Create(spec_proto, document_store(), schema_store(), + fake_clock().GetSystemTimeMilliseconds())); EXPECT_THAT(scoring_processor->Score(std::move(doc_hit_info_iterator), /*num_to_score=*/-1), @@ -271,7 +279,8 @@ TEST_P(ScoringProcessorTest, ShouldRespectNumToScore) { // Creates a ScoringProcessor ICING_ASSERT_OK_AND_ASSIGN( std::unique_ptr<ScoringProcessor> scoring_processor, - ScoringProcessor::Create(spec_proto, document_store(), schema_store())); + ScoringProcessor::Create(spec_proto, document_store(), schema_store(), + fake_clock().GetSystemTimeMilliseconds())); EXPECT_THAT(scoring_processor->Score(std::move(doc_hit_info_iterator), /*num_to_score=*/2), @@ -303,7 +312,8 @@ TEST_P(ScoringProcessorTest, ShouldScoreByDocumentScore) { // Creates a ScoringProcessor ICING_ASSERT_OK_AND_ASSIGN( std::unique_ptr<ScoringProcessor> scoring_processor, - ScoringProcessor::Create(spec_proto, document_store(), schema_store())); + ScoringProcessor::Create(spec_proto, document_store(), schema_store(), + fake_clock().GetSystemTimeMilliseconds())); EXPECT_THAT(scoring_processor->Score(std::move(doc_hit_info_iterator), /*num_to_score=*/3), @@ -358,7 +368,8 @@ TEST_P(ScoringProcessorTest, // Creates a ScoringProcessor ICING_ASSERT_OK_AND_ASSIGN( std::unique_ptr<ScoringProcessor> scoring_processor, - ScoringProcessor::Create(spec_proto, document_store(), schema_store())); + ScoringProcessor::Create(spec_proto, document_store(), schema_store(), + fake_clock().GetSystemTimeMilliseconds())); std::unordered_map<std::string, std::unique_ptr<DocHitInfoIterator>> query_term_iterators; @@ -427,7 +438,8 @@ TEST_P(ScoringProcessorTest, // Creates a ScoringProcessor ICING_ASSERT_OK_AND_ASSIGN( std::unique_ptr<ScoringProcessor> scoring_processor, - ScoringProcessor::Create(spec_proto, document_store(), schema_store())); + ScoringProcessor::Create(spec_proto, document_store(), schema_store(), + fake_clock().GetSystemTimeMilliseconds())); std::unordered_map<std::string, std::unique_ptr<DocHitInfoIterator>> query_term_iterators; @@ -500,7 +512,8 @@ TEST_P(ScoringProcessorTest, // Creates a ScoringProcessor ICING_ASSERT_OK_AND_ASSIGN( std::unique_ptr<ScoringProcessor> scoring_processor, - ScoringProcessor::Create(spec_proto, document_store(), schema_store())); + ScoringProcessor::Create(spec_proto, document_store(), schema_store(), + fake_clock().GetSystemTimeMilliseconds())); std::unordered_map<std::string, std::unique_ptr<DocHitInfoIterator>> query_term_iterators; @@ -549,7 +562,8 @@ TEST_P(ScoringProcessorTest, // Creates a ScoringProcessor ICING_ASSERT_OK_AND_ASSIGN( std::unique_ptr<ScoringProcessor> scoring_processor, - ScoringProcessor::Create(spec_proto, document_store(), schema_store())); + ScoringProcessor::Create(spec_proto, document_store(), schema_store(), + fake_clock().GetSystemTimeMilliseconds())); std::unordered_map<std::string, std::unique_ptr<DocHitInfoIterator>> query_term_iterators; @@ -614,7 +628,8 @@ TEST_P(ScoringProcessorTest, // Creates a ScoringProcessor ICING_ASSERT_OK_AND_ASSIGN( std::unique_ptr<ScoringProcessor> scoring_processor, - ScoringProcessor::Create(spec_proto, document_store(), schema_store())); + ScoringProcessor::Create(spec_proto, document_store(), schema_store(), + fake_clock().GetSystemTimeMilliseconds())); std::unordered_map<std::string, std::unique_ptr<DocHitInfoIterator>> query_term_iterators; @@ -684,7 +699,8 @@ TEST_P(ScoringProcessorTest, // Creates a ScoringProcessor ICING_ASSERT_OK_AND_ASSIGN( std::unique_ptr<ScoringProcessor> scoring_processor, - ScoringProcessor::Create(spec_proto, document_store(), schema_store())); + ScoringProcessor::Create(spec_proto, document_store(), schema_store(), + fake_clock().GetSystemTimeMilliseconds())); std::unordered_map<std::string, std::unique_ptr<DocHitInfoIterator>> query_term_iterators; @@ -745,7 +761,8 @@ TEST_P(ScoringProcessorTest, // Creates a ScoringProcessor with no explicit weights set. ICING_ASSERT_OK_AND_ASSIGN( std::unique_ptr<ScoringProcessor> scoring_processor, - ScoringProcessor::Create(spec_proto, document_store(), schema_store())); + ScoringProcessor::Create(spec_proto, document_store(), schema_store(), + fake_clock().GetSystemTimeMilliseconds())); ScoringSpecProto spec_proto_with_weights = CreateScoringSpecForRankingStrategy( @@ -761,7 +778,8 @@ TEST_P(ScoringProcessorTest, ICING_ASSERT_OK_AND_ASSIGN( std::unique_ptr<ScoringProcessor> scoring_processor_with_weights, ScoringProcessor::Create(spec_proto_with_weights, document_store(), - schema_store())); + schema_store(), + fake_clock().GetSystemTimeMilliseconds())); std::unordered_map<std::string, std::unique_ptr<DocHitInfoIterator>> query_term_iterators; @@ -847,7 +865,8 @@ TEST_P(ScoringProcessorTest, // Creates a ScoringProcessor ICING_ASSERT_OK_AND_ASSIGN( std::unique_ptr<ScoringProcessor> scoring_processor, - ScoringProcessor::Create(spec_proto, document_store(), schema_store())); + ScoringProcessor::Create(spec_proto, document_store(), schema_store(), + fake_clock().GetSystemTimeMilliseconds())); std::unordered_map<std::string, std::unique_ptr<DocHitInfoIterator>> query_term_iterators; @@ -909,7 +928,8 @@ TEST_P(ScoringProcessorTest, ShouldScoreByCreationTimestamp) { // Creates a ScoringProcessor which ranks in descending order ICING_ASSERT_OK_AND_ASSIGN( std::unique_ptr<ScoringProcessor> scoring_processor, - ScoringProcessor::Create(spec_proto, document_store(), schema_store())); + ScoringProcessor::Create(spec_proto, document_store(), schema_store(), + fake_clock().GetSystemTimeMilliseconds())); EXPECT_THAT(scoring_processor->Score(std::move(doc_hit_info_iterator), /*num_to_score=*/3), @@ -969,7 +989,8 @@ TEST_P(ScoringProcessorTest, ShouldScoreByUsageCount) { // Creates a ScoringProcessor which ranks in descending order ICING_ASSERT_OK_AND_ASSIGN( std::unique_ptr<ScoringProcessor> scoring_processor, - ScoringProcessor::Create(spec_proto, document_store(), schema_store())); + ScoringProcessor::Create(spec_proto, document_store(), schema_store(), + fake_clock().GetSystemTimeMilliseconds())); EXPECT_THAT(scoring_processor->Score(std::move(doc_hit_info_iterator), /*num_to_score=*/3), @@ -1029,7 +1050,8 @@ TEST_P(ScoringProcessorTest, ShouldScoreByUsageTimestamp) { // Creates a ScoringProcessor which ranks in descending order ICING_ASSERT_OK_AND_ASSIGN( std::unique_ptr<ScoringProcessor> scoring_processor, - ScoringProcessor::Create(spec_proto, document_store(), schema_store())); + ScoringProcessor::Create(spec_proto, document_store(), schema_store(), + fake_clock().GetSystemTimeMilliseconds())); EXPECT_THAT(scoring_processor->Score(std::move(doc_hit_info_iterator), /*num_to_score=*/3), @@ -1065,7 +1087,8 @@ TEST_P(ScoringProcessorTest, ShouldHandleNoScores) { // Creates a ScoringProcessor which ranks in descending order ICING_ASSERT_OK_AND_ASSIGN( std::unique_ptr<ScoringProcessor> scoring_processor, - ScoringProcessor::Create(spec_proto, document_store(), schema_store())); + ScoringProcessor::Create(spec_proto, document_store(), schema_store(), + fake_clock().GetSystemTimeMilliseconds())); EXPECT_THAT(scoring_processor->Score(std::move(doc_hit_info_iterator), /*num_to_score=*/4), ElementsAre(EqualsScoredDocumentHit(scored_document_hit_default), @@ -1114,7 +1137,8 @@ TEST_P(ScoringProcessorTest, ShouldWrapResultsWhenNoScoring) { // Creates a ScoringProcessor which ranks in descending order ICING_ASSERT_OK_AND_ASSIGN( std::unique_ptr<ScoringProcessor> scoring_processor, - ScoringProcessor::Create(spec_proto, document_store(), schema_store())); + ScoringProcessor::Create(spec_proto, document_store(), schema_store(), + fake_clock().GetSystemTimeMilliseconds())); EXPECT_THAT(scoring_processor->Score(std::move(doc_hit_info_iterator), /*num_to_score=*/3), diff --git a/icing/store/document-store.cc b/icing/store/document-store.cc index b49d0de..e99bacf 100644 --- a/icing/store/document-store.cc +++ b/icing/store/document-store.cc @@ -1010,7 +1010,8 @@ libtextclassifier3::StatusOr<DocumentId> DocumentStore::InternalPut( // Delete the old document. It's fine if it's not found since it might have // been deleted previously. - auto delete_status = Delete(old_document_id); + auto delete_status = + Delete(old_document_id, clock_.GetSystemTimeMilliseconds()); if (!delete_status.ok() && !absl_ports::IsNotFound(delete_status)) { // Real error, pass it up. return delete_status; @@ -1055,7 +1056,9 @@ libtextclassifier3::StatusOr<DocumentProto> DocumentStore::Get( libtextclassifier3::StatusOr<DocumentProto> DocumentStore::Get( DocumentId document_id, bool clear_internal_fields) const { - auto document_filter_data_optional_ = GetAliveDocumentFilterData(document_id); + int64_t current_time_ms = clock_.GetSystemTimeMilliseconds(); + auto document_filter_data_optional_ = + GetAliveDocumentFilterData(document_id, current_time_ms); if (!document_filter_data_optional_) { // The document doesn't exist. Let's check if the document id is invalid, we // will return InvalidArgumentError. Otherwise we should return NOT_FOUND @@ -1118,6 +1121,7 @@ std::vector<std::string> DocumentStore::GetAllNamespaces() const { GetNamespaceIdsToNamespaces(namespace_mapper_.get()); std::unordered_set<NamespaceId> existing_namespace_ids; + int64_t current_time_ms = clock_.GetSystemTimeMilliseconds(); for (DocumentId document_id = 0; document_id < filter_cache_->num_elements(); ++document_id) { // filter_cache_->Get can only fail if document_id is < 0 @@ -1130,7 +1134,7 @@ std::vector<std::string> DocumentStore::GetAllNamespaces() const { } const DocumentFilterData* data = status_or_data.ValueOrDie(); - if (GetAliveDocumentFilterData(document_id)) { + if (GetAliveDocumentFilterData(document_id, current_time_ms)) { existing_namespace_ids.insert(data->namespace_id()); } } @@ -1144,14 +1148,11 @@ std::vector<std::string> DocumentStore::GetAllNamespaces() const { } std::optional<DocumentFilterData> DocumentStore::GetAliveDocumentFilterData( - DocumentId document_id) const { - if (!IsDocumentIdValid(document_id)) { - return std::nullopt; - } + DocumentId document_id, int64_t current_time_ms) const { if (IsDeleted(document_id)) { return std::nullopt; } - return GetNonExpiredDocumentFilterData(document_id); + return GetNonExpiredDocumentFilterData(document_id, current_time_ms); } bool DocumentStore::IsDeleted(DocumentId document_id) const { @@ -1171,7 +1172,8 @@ bool DocumentStore::IsDeleted(DocumentId document_id) const { // Returns DocumentFilterData if the document is not expired. Otherwise, // std::nullopt. std::optional<DocumentFilterData> -DocumentStore::GetNonExpiredDocumentFilterData(DocumentId document_id) const { +DocumentStore::GetNonExpiredDocumentFilterData(DocumentId document_id, + int64_t current_time_ms) const { auto filter_data_or = filter_cache_->GetCopy(document_id); if (!filter_data_or.ok()) { // This would only happen if document_id is out of range of the @@ -1184,15 +1186,15 @@ DocumentStore::GetNonExpiredDocumentFilterData(DocumentId document_id) const { DocumentFilterData document_filter_data = filter_data_or.ValueOrDie(); // Check if it's past the expiration time - if (clock_.GetSystemTimeMilliseconds() >= - document_filter_data.expiration_timestamp_ms()) { + if (current_time_ms >= document_filter_data.expiration_timestamp_ms()) { return std::nullopt; } return document_filter_data; } libtextclassifier3::Status DocumentStore::Delete( - const std::string_view name_space, const std::string_view uri) { + const std::string_view name_space, const std::string_view uri, + int64_t current_time_ms) { // Try to get the DocumentId first auto document_id_or = GetDocumentId(name_space, uri); if (!document_id_or.ok()) { @@ -1201,11 +1203,13 @@ libtextclassifier3::Status DocumentStore::Delete( absl_ports::StrCat("Failed to delete Document. namespace: ", name_space, ", uri: ", uri)); } - return Delete(document_id_or.ValueOrDie()); + return Delete(document_id_or.ValueOrDie(), current_time_ms); } -libtextclassifier3::Status DocumentStore::Delete(DocumentId document_id) { - auto document_filter_data_optional_ = GetAliveDocumentFilterData(document_id); +libtextclassifier3::Status DocumentStore::Delete(DocumentId document_id, + int64_t current_time_ms) { + auto document_filter_data_optional_ = + GetAliveDocumentFilterData(document_id, current_time_ms); if (!document_filter_data_optional_) { // The document doesn't exist. We should return InvalidArgumentError if the // document id is invalid. Otherwise we should return NOT_FOUND error. @@ -1292,24 +1296,16 @@ libtextclassifier3::StatusOr<int32_t> DocumentStore::GetResultGroupingEntryId( libtextclassifier3::StatusOr<DocumentAssociatedScoreData> DocumentStore::GetDocumentAssociatedScoreData(DocumentId document_id) const { - if (!GetAliveDocumentFilterData(document_id)) { - return absl_ports::NotFoundError(IcingStringUtil::StringPrintf( - "Can't get usage scores, document id '%d' doesn't exist", document_id)); - } - auto score_data_or = score_cache_->GetCopy(document_id); if (!score_data_or.ok()) { ICING_LOG(ERROR) << " while trying to access DocumentId " << document_id << " from score_cache_"; - return score_data_or.status(); + return absl_ports::NotFoundError( + std::move(score_data_or).status().error_message()); } DocumentAssociatedScoreData document_associated_score_data = std::move(score_data_or).ValueOrDie(); - if (document_associated_score_data.document_score() < 0) { - // An negative / invalid score means that the score data has been deleted. - return absl_ports::NotFoundError("Document score data not found."); - } return document_associated_score_data; } @@ -1344,9 +1340,9 @@ DocumentStore::GetCorpusAssociatedScoreDataToUpdate(CorpusId corpus_id) const { // TODO(b/273826815): Decide on and adopt a consistent pattern for handling // NOT_FOUND 'errors' returned by our internal classes. std::optional<UsageStore::UsageScores> DocumentStore::GetUsageScores( - DocumentId document_id) const { + DocumentId document_id, int64_t current_time_ms) const { std::optional<DocumentFilterData> opt = - GetAliveDocumentFilterData(document_id); + GetAliveDocumentFilterData(document_id, current_time_ms); if (!opt) { return std::nullopt; } @@ -1370,7 +1366,8 @@ libtextclassifier3::Status DocumentStore::ReportUsage( // We can use the internal version here because we got our document_id from // our internal data structures. We would have thrown some error if the // namespace and/or uri were incorrect. - if (!GetAliveDocumentFilterData(document_id)) { + int64_t current_time_ms = clock_.GetSystemTimeMilliseconds(); + if (!GetAliveDocumentFilterData(document_id, current_time_ms)) { // Document was probably deleted or expired. return absl_ports::NotFoundError(absl_ports::StrCat( "Couldn't report usage on a nonexistent document: (namespace: '", @@ -1446,6 +1443,7 @@ libtextclassifier3::StatusOr<int> DocumentStore::BatchDelete( // Traverse FilterCache and delete all docs that match namespace_id and // schema_type_id. + int64_t current_time_ms = clock_.GetSystemTimeMilliseconds(); for (DocumentId document_id = 0; document_id < filter_cache_->num_elements(); ++document_id) { // filter_cache_->Get can only fail if document_id is < 0 @@ -1473,7 +1471,8 @@ libtextclassifier3::StatusOr<int> DocumentStore::BatchDelete( // The document has the desired namespace and schema type, it either // exists or has expired. - libtextclassifier3::Status delete_status = Delete(document_id); + libtextclassifier3::Status delete_status = + Delete(document_id, current_time_ms); if (absl_ports::IsNotFound(delete_status)) { continue; } else if (!delete_status.ok()) { @@ -1545,6 +1544,7 @@ DocumentStorageInfoProto DocumentStore::CalculateDocumentStatusCounts( std::unordered_map<std::string, NamespaceStorageInfoProto> namespace_to_storage_info; + int64_t current_time_ms = clock_.GetSystemTimeMilliseconds(); for (DocumentId document_id = 0; document_id < document_id_mapper_->num_elements(); ++document_id) { // Check if it's deleted first. @@ -1588,7 +1588,7 @@ DocumentStorageInfoProto DocumentStore::CalculateDocumentStatusCounts( UsageStore::UsageScores usage_scores = usage_scores_or.ValueOrDie(); // Update our stats - if (!GetNonExpiredDocumentFilterData(document_id)) { + if (!GetNonExpiredDocumentFilterData(document_id, current_time_ms)) { ++total_num_expired; namespace_storage_info.set_num_expired_documents( namespace_storage_info.num_expired_documents() + 1); @@ -1651,6 +1651,7 @@ libtextclassifier3::Status DocumentStore::UpdateSchemaStore( document_validator_.UpdateSchemaStore(schema_store); int size = document_id_mapper_->num_elements(); + int64_t current_time_ms = clock_.GetSystemTimeMilliseconds(); for (DocumentId document_id = 0; document_id < size; document_id++) { auto document_or = Get(document_id); if (absl_ports::IsNotFound(document_or.status())) { @@ -1680,7 +1681,8 @@ libtextclassifier3::Status DocumentStore::UpdateSchemaStore( } else { // Document is no longer valid with the new SchemaStore. Mark as // deleted - auto delete_status = Delete(document.namespace_(), document.uri()); + auto delete_status = + Delete(document.namespace_(), document.uri(), current_time_ms); if (!delete_status.ok() && !absl_ports::IsNotFound(delete_status)) { // Real error, pass up return delete_status; @@ -1704,8 +1706,9 @@ libtextclassifier3::Status DocumentStore::OptimizedUpdateSchemaStore( document_validator_.UpdateSchemaStore(schema_store); int size = document_id_mapper_->num_elements(); + int64_t current_time_ms = clock_.GetSystemTimeMilliseconds(); for (DocumentId document_id = 0; document_id < size; document_id++) { - if (!GetAliveDocumentFilterData(document_id)) { + if (!GetAliveDocumentFilterData(document_id, current_time_ms)) { // Skip nonexistent documents continue; } @@ -1749,7 +1752,7 @@ libtextclassifier3::Status DocumentStore::OptimizedUpdateSchemaStore( if (delete_document) { // Document is no longer valid with the new SchemaStore. Mark as deleted - auto delete_status = Delete(document_id); + auto delete_status = Delete(document_id, current_time_ms); if (!delete_status.ok() && !absl_ports::IsNotFound(delete_status)) { // Real error, pass up return delete_status; @@ -1791,12 +1794,14 @@ DocumentStore::OptimizeInto(const std::string& new_directory, int num_expired = 0; UsageStore::UsageScores default_usage; std::vector<DocumentId> document_id_old_to_new(size, kInvalidDocumentId); + int64_t current_time_ms = clock_.GetSystemTimeMilliseconds(); for (DocumentId document_id = 0; document_id < size; document_id++) { auto document_or = Get(document_id, /*clear_internal_fields=*/false); if (absl_ports::IsNotFound(document_or.status())) { if (IsDeleted(document_id)) { ++num_deleted; - } else if (!GetNonExpiredDocumentFilterData(document_id)) { + } else if (!GetNonExpiredDocumentFilterData(document_id, + current_time_ms)) { ++num_expired; } continue; @@ -1866,9 +1871,10 @@ DocumentStore::GetOptimizeInfo() const { // Figure out our ratio of optimizable/total docs. int32_t num_documents = document_id_mapper_->num_elements(); + int64_t current_time_ms = clock_.GetSystemTimeMilliseconds(); for (DocumentId document_id = kMinDocumentId; document_id < num_documents; ++document_id) { - if (!GetAliveDocumentFilterData(document_id)) { + if (!GetAliveDocumentFilterData(document_id, current_time_ms)) { ++optimize_info.optimizable_docs; } @@ -1979,9 +1985,10 @@ DocumentStore::CollectCorpusInfo() const { std::unordered_map<NamespaceId, std::string> namespace_id_to_namespace = GetNamespaceIdsToNamespaces(namespace_mapper_.get()); const SchemaProto* schema_proto = schema_proto_or.ValueOrDie(); + int64_t current_time_ms = clock_.GetSystemTimeMilliseconds(); for (DocumentId document_id = 0; document_id < filter_cache_->num_elements(); ++document_id) { - if (!GetAliveDocumentFilterData(document_id)) { + if (!GetAliveDocumentFilterData(document_id, current_time_ms)) { continue; } ICING_ASSIGN_OR_RETURN(const DocumentFilterData* filter_data, diff --git a/icing/store/document-store.h b/icing/store/document-store.h index 3bb04f4..3941f6d 100644 --- a/icing/store/document-store.h +++ b/icing/store/document-store.h @@ -229,7 +229,8 @@ class DocumentStore { // NOT_FOUND if no document exists with namespace, uri // INTERNAL_ERROR on IO error libtextclassifier3::Status Delete(std::string_view name_space, - std::string_view uri); + std::string_view uri, + int64_t current_time_ms); // Deletes the document identified by the given document_id. The document // proto will be erased immediately. @@ -243,7 +244,8 @@ class DocumentStore { // NOT_FOUND if the document doesn't exist (i.e. deleted or expired) // INTERNAL_ERROR on IO error // INVALID_ARGUMENT if document_id is invalid. - libtextclassifier3::Status Delete(DocumentId document_id); + libtextclassifier3::Status Delete(DocumentId document_id, + int64_t current_time_ms); // Returns the NamespaceId of the string namespace // @@ -339,7 +341,7 @@ class DocumentStore { // True:DocumentFilterData if the given document exists. // False if the given document doesn't exist. std::optional<DocumentFilterData> GetAliveDocumentFilterData( - DocumentId document_id) const; + DocumentId document_id, int64_t current_time_ms) const; // Gets the usage scores of a document. // @@ -347,7 +349,7 @@ class DocumentStore { // UsageScores on success // nullopt if there are no usage scores stored for the requested docid. std::optional<UsageStore::UsageScores> GetUsageScores( - DocumentId document_id) const; + DocumentId document_id, int64_t current_time_ms) const; // Reports usage. The corresponding usage scores of the specified document in // the report will be updated. @@ -714,7 +716,7 @@ class DocumentStore { // True:DocumentFilterData if the given document isn't expired. // False if the given doesn't document is expired. std::optional<DocumentFilterData> GetNonExpiredDocumentFilterData( - DocumentId document_id) const; + DocumentId document_id, int64_t current_time_ms) const; // Updates the entry in the score cache for document_id. libtextclassifier3::Status UpdateDocumentAssociatedScoreCache( diff --git a/icing/store/document-store_benchmark.cc b/icing/store/document-store_benchmark.cc index 61906a9..75995e9 100644 --- a/icing/store/document-store_benchmark.cc +++ b/icing/store/document-store_benchmark.cc @@ -162,7 +162,8 @@ void BM_DoesDocumentExistBenchmark(benchmark::State& state) { // stuff. ICING_ASSERT_OK(document_store->Put( CreateDocument("namespace", /*uri=*/std::to_string(i)))); - document_store->Delete("namespace", /*uri=*/std::to_string(i)); + document_store->Delete("namespace", /*uri=*/std::to_string(i), + clock.GetSystemTimeMilliseconds()); } std::default_random_engine random; @@ -171,8 +172,8 @@ void BM_DoesDocumentExistBenchmark(benchmark::State& state) { // Check random document ids to see if they exist. Hopefully to simulate // page faulting in different sections of our mmapped derived files. int document_id = dist(random); - benchmark::DoNotOptimize( - document_store->GetAliveDocumentFilterData(document_id)); + benchmark::DoNotOptimize(document_store->GetAliveDocumentFilterData( + document_id, clock.GetSystemTimeMilliseconds())); } } BENCHMARK(BM_DoesDocumentExistBenchmark); @@ -259,7 +260,8 @@ void BM_Delete(benchmark::State& state) { ICING_ASSERT_OK(document_store->Put(document)); state.ResumeTiming(); - benchmark::DoNotOptimize(document_store->Delete("namespace", "uri")); + benchmark::DoNotOptimize(document_store->Delete( + "namespace", "uri", clock.GetSystemTimeMilliseconds())); } } BENCHMARK(BM_Delete); diff --git a/icing/store/document-store_test.cc b/icing/store/document-store_test.cc index 146191f..9a1f4a6 100644 --- a/icing/store/document-store_test.cc +++ b/icing/store/document-store_test.cc @@ -71,7 +71,6 @@ using ::testing::Ge; using ::testing::Gt; using ::testing::HasSubstr; using ::testing::IsEmpty; -using ::testing::IsFalse; using ::testing::IsTrue; using ::testing::Not; using ::testing::Return; @@ -373,22 +372,27 @@ TEST_F(DocumentStoreTest, IsDocumentExistingWithoutStatus) { ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id2, doc_store->Put(DocumentProto(test_document2_))); - EXPECT_TRUE(doc_store->GetAliveDocumentFilterData(document_id1)); - EXPECT_TRUE(doc_store->GetAliveDocumentFilterData(document_id2)); + EXPECT_TRUE(doc_store->GetAliveDocumentFilterData( + document_id1, fake_clock_.GetSystemTimeMilliseconds())); + EXPECT_TRUE(doc_store->GetAliveDocumentFilterData( + document_id2, fake_clock_.GetSystemTimeMilliseconds())); DocumentId invalid_document_id_negative = -1; - EXPECT_FALSE( - doc_store->GetAliveDocumentFilterData(invalid_document_id_negative)); + EXPECT_FALSE(doc_store->GetAliveDocumentFilterData( + invalid_document_id_negative, fake_clock_.GetSystemTimeMilliseconds())); DocumentId invalid_document_id_greater_than_max = kMaxDocumentId + 2; EXPECT_FALSE(doc_store->GetAliveDocumentFilterData( - invalid_document_id_greater_than_max)); + invalid_document_id_greater_than_max, + fake_clock_.GetSystemTimeMilliseconds())); - EXPECT_FALSE(doc_store->GetAliveDocumentFilterData(kInvalidDocumentId)); + EXPECT_FALSE(doc_store->GetAliveDocumentFilterData( + kInvalidDocumentId, fake_clock_.GetSystemTimeMilliseconds())); DocumentId invalid_document_id_out_of_range = document_id2 + 1; - EXPECT_FALSE( - doc_store->GetAliveDocumentFilterData(invalid_document_id_out_of_range)); + EXPECT_FALSE(doc_store->GetAliveDocumentFilterData( + invalid_document_id_out_of_range, + fake_clock_.GetSystemTimeMilliseconds())); } TEST_F(DocumentStoreTest, GetDeletedDocumentNotFound) { @@ -404,8 +408,9 @@ TEST_F(DocumentStoreTest, GetDeletedDocumentNotFound) { document_store->Get(test_document1_.namespace_(), test_document1_.uri()), IsOkAndHolds(EqualsProto(test_document1_))); - ICING_EXPECT_OK(document_store->Delete(test_document1_.namespace_(), - test_document1_.uri())); + ICING_EXPECT_OK(document_store->Delete( + test_document1_.namespace_(), test_document1_.uri(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT( document_store->Get(test_document1_.namespace_(), test_document1_.uri()), StatusIs(libtextclassifier3::StatusCode::NOT_FOUND)); @@ -488,9 +493,9 @@ TEST_F(DocumentStoreTest, DeleteNonexistentDocumentNotFound) { DocumentLogCreator::GetDocumentLogFilename()) .c_str()); - EXPECT_THAT( - document_store->Delete("nonexistent_namespace", "nonexistent_uri"), - StatusIs(libtextclassifier3::StatusCode::NOT_FOUND)); + EXPECT_THAT(document_store->Delete("nonexistent_namespace", "nonexistent_uri", + fake_clock_.GetSystemTimeMilliseconds()), + StatusIs(libtextclassifier3::StatusCode::NOT_FOUND)); int64_t document_log_size_after = filesystem_.GetFileSize( absl_ports::StrCat(document_store_dir_, "/", @@ -514,8 +519,8 @@ TEST_F(DocumentStoreTest, DeleteNonexistentDocumentPrintableErrorMessage) { DocumentLogCreator::GetDocumentLogFilename()) .c_str()); - libtextclassifier3::Status status = - document_store->Delete("android$contacts/", "661"); + libtextclassifier3::Status status = document_store->Delete( + "android$contacts/", "661", fake_clock_.GetSystemTimeMilliseconds()); EXPECT_THAT(status, StatusIs(libtextclassifier3::StatusCode::NOT_FOUND)); for (char c : status.error_message()) { EXPECT_THAT(std::isprint(c), IsTrue()); @@ -539,12 +544,14 @@ TEST_F(DocumentStoreTest, DeleteAlreadyDeletedDocumentNotFound) { ICING_EXPECT_OK(document_store->Put(test_document1_)); // First time is OK - ICING_EXPECT_OK(document_store->Delete(test_document1_.namespace_(), - test_document1_.uri())); + ICING_EXPECT_OK(document_store->Delete( + test_document1_.namespace_(), test_document1_.uri(), + fake_clock_.GetSystemTimeMilliseconds())); // Deleting it again is NOT_FOUND EXPECT_THAT(document_store->Delete(test_document1_.namespace_(), - test_document1_.uri()), + test_document1_.uri(), + fake_clock_.GetSystemTimeMilliseconds()), StatusIs(libtextclassifier3::StatusCode::NOT_FOUND)); } @@ -626,8 +633,9 @@ TEST_F(DocumentStoreTest, DeleteByNamespaceNoExistingDocumentsNotFound) { std::move(create_result.document_store); ICING_EXPECT_OK(document_store->Put(test_document1_)); - ICING_EXPECT_OK(document_store->Delete(test_document1_.namespace_(), - test_document1_.uri())); + ICING_EXPECT_OK(document_store->Delete( + test_document1_.namespace_(), test_document1_.uri(), + fake_clock_.GetSystemTimeMilliseconds())); // At this point, there are no existing documents with the namespace, even // though Icing's derived files know about this namespace. We should still @@ -829,8 +837,9 @@ TEST_F(DocumentStoreTest, DeleteBySchemaTypeNoExistingDocumentsNotFound) { std::move(create_result.document_store); ICING_EXPECT_OK(document_store->Put(test_document1_)); - ICING_EXPECT_OK(document_store->Delete(test_document1_.namespace_(), - test_document1_.uri())); + ICING_EXPECT_OK(document_store->Delete( + test_document1_.namespace_(), test_document1_.uri(), + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT( document_store->DeleteBySchemaType(test_document1_.schema()).status, @@ -925,8 +934,9 @@ TEST_F(DocumentStoreTest, PutDeleteThenPut) { std::unique_ptr<DocumentStore> doc_store = std::move(create_result.document_store); ICING_EXPECT_OK(doc_store->Put(test_document1_)); - ICING_EXPECT_OK( - doc_store->Delete(test_document1_.namespace_(), test_document1_.uri())); + ICING_EXPECT_OK(doc_store->Delete(test_document1_.namespace_(), + test_document1_.uri(), + fake_clock_.GetSystemTimeMilliseconds())); ICING_EXPECT_OK(doc_store->Put(test_document1_)); } @@ -1092,7 +1102,8 @@ TEST_F(DocumentStoreTest, OptimizeInto) { // is deleted ASSERT_TRUE(filesystem_.DeleteDirectoryRecursively(optimized_dir.c_str())); ASSERT_TRUE(filesystem_.CreateDirectoryRecursively(optimized_dir.c_str())); - ICING_ASSERT_OK(doc_store->Delete("namespace", "uri1")); + ICING_ASSERT_OK(doc_store->Delete("namespace", "uri1", + fake_clock_.GetSystemTimeMilliseconds())); // DocumentId 0 is removed. EXPECT_THAT(doc_store->OptimizeInto(optimized_dir, lang_segmenter_.get(), /*namespace_id_fingerprint=*/false), @@ -1121,7 +1132,8 @@ TEST_F(DocumentStoreTest, OptimizeInto) { // Delete the last document ASSERT_TRUE(filesystem_.DeleteDirectoryRecursively(optimized_dir.c_str())); ASSERT_TRUE(filesystem_.CreateDirectoryRecursively(optimized_dir.c_str())); - ICING_ASSERT_OK(doc_store->Delete("namespace", "uri2")); + ICING_ASSERT_OK(doc_store->Delete("namespace", "uri2", + fake_clock_.GetSystemTimeMilliseconds())); // DocumentId 0 and 1 is removed, and DocumentId 2 is expired. EXPECT_THAT(doc_store->OptimizeInto(optimized_dir, lang_segmenter_.get(), /*namespace_id_fingerprint=*/false), @@ -1184,7 +1196,9 @@ TEST_F(DocumentStoreTest, ShouldRecoverFromDataLoss) { /*num_docs=*/2, /*sum_length_in_tokens=*/8))); // Delete document 1 - EXPECT_THAT(doc_store->Delete("icing", "email/1"), IsOk()); + EXPECT_THAT(doc_store->Delete("icing", "email/1", + fake_clock_.GetSystemTimeMilliseconds()), + IsOk()); EXPECT_THAT(doc_store->Get(document_id1), StatusIs(libtextclassifier3::StatusCode::NOT_FOUND)); EXPECT_THAT(doc_store->Get(document_id2), @@ -1218,7 +1232,8 @@ TEST_F(DocumentStoreTest, ShouldRecoverFromDataLoss) { // Checks derived filter cache ICING_ASSERT_HAS_VALUE_AND_ASSIGN( DocumentFilterData doc_filter_data, - doc_store->GetAliveDocumentFilterData(document_id2)); + doc_store->GetAliveDocumentFilterData( + document_id2, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(doc_filter_data, Eq(DocumentFilterData( /*namespace_id=*/0, @@ -1271,7 +1286,9 @@ TEST_F(DocumentStoreTest, ShouldRecoverFromCorruptDerivedFile) { IsOkAndHolds(CorpusAssociatedScoreData( /*num_docs=*/2, /*sum_length_in_tokens=*/8))); // Delete document 1 - EXPECT_THAT(doc_store->Delete("icing", "email/1"), IsOk()); + EXPECT_THAT(doc_store->Delete("icing", "email/1", + fake_clock_.GetSystemTimeMilliseconds()), + IsOk()); EXPECT_THAT(doc_store->Get(document_id1), StatusIs(libtextclassifier3::StatusCode::NOT_FOUND)); EXPECT_THAT(doc_store->Get(document_id2), @@ -1316,7 +1333,8 @@ TEST_F(DocumentStoreTest, ShouldRecoverFromCorruptDerivedFile) { // Checks derived filter cache ICING_ASSERT_HAS_VALUE_AND_ASSIGN( DocumentFilterData doc_filter_data, - doc_store->GetAliveDocumentFilterData(document_id2)); + doc_store->GetAliveDocumentFilterData( + document_id2, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(doc_filter_data, Eq(DocumentFilterData( /*namespace_id=*/0, @@ -1336,8 +1354,10 @@ TEST_F(DocumentStoreTest, ShouldRecoverFromCorruptDerivedFile) { // scratch. UsageStore::UsageScores expected_scores; expected_scores.usage_type1_count = 1; - ICING_ASSERT_HAS_VALUE_AND_ASSIGN(UsageStore::UsageScores actual_scores, - doc_store->GetUsageScores(document_id2)); + ICING_ASSERT_HAS_VALUE_AND_ASSIGN( + UsageStore::UsageScores actual_scores, + doc_store->GetUsageScores(document_id2, + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(actual_scores, Eq(expected_scores)); } @@ -1377,7 +1397,9 @@ TEST_F(DocumentStoreTest, ShouldRecoverFromDiscardDerivedFiles) { IsOkAndHolds(CorpusAssociatedScoreData( /*num_docs=*/2, /*sum_length_in_tokens=*/8))); // Delete document 1 - EXPECT_THAT(doc_store->Delete("icing", "email/1"), IsOk()); + EXPECT_THAT(doc_store->Delete("icing", "email/1", + fake_clock_.GetSystemTimeMilliseconds()), + IsOk()); EXPECT_THAT(doc_store->Get(document_id1), StatusIs(libtextclassifier3::StatusCode::NOT_FOUND)); EXPECT_THAT(doc_store->Get(document_id2), @@ -1409,7 +1431,8 @@ TEST_F(DocumentStoreTest, ShouldRecoverFromDiscardDerivedFiles) { // Checks derived filter cache ICING_ASSERT_HAS_VALUE_AND_ASSIGN( DocumentFilterData doc_filter_data, - doc_store->GetAliveDocumentFilterData(document_id2)); + doc_store->GetAliveDocumentFilterData( + document_id2, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(doc_filter_data, Eq(DocumentFilterData( /*namespace_id=*/0, @@ -1429,8 +1452,10 @@ TEST_F(DocumentStoreTest, ShouldRecoverFromDiscardDerivedFiles) { // scratch. UsageStore::UsageScores expected_scores; expected_scores.usage_type1_count = 1; - ICING_ASSERT_HAS_VALUE_AND_ASSIGN(UsageStore::UsageScores actual_scores, - doc_store->GetUsageScores(document_id2)); + ICING_ASSERT_HAS_VALUE_AND_ASSIGN( + UsageStore::UsageScores actual_scores, + doc_store->GetUsageScores(document_id2, + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(actual_scores, Eq(expected_scores)); } @@ -1469,7 +1494,9 @@ TEST_F(DocumentStoreTest, ShouldRecoverFromBadChecksum) { EXPECT_THAT(doc_store->GetCorpusAssociatedScoreData(/*corpus_id=*/0), IsOkAndHolds(CorpusAssociatedScoreData( /*num_docs=*/2, /*sum_length_in_tokens=*/8))); - EXPECT_THAT(doc_store->Delete("icing", "email/1"), IsOk()); + EXPECT_THAT(doc_store->Delete("icing", "email/1", + fake_clock_.GetSystemTimeMilliseconds()), + IsOk()); EXPECT_THAT(doc_store->Get(document_id1), StatusIs(libtextclassifier3::StatusCode::NOT_FOUND)); EXPECT_THAT(doc_store->Get(document_id2), @@ -1493,7 +1520,8 @@ TEST_F(DocumentStoreTest, ShouldRecoverFromBadChecksum) { // Checks derived filter cache ICING_ASSERT_HAS_VALUE_AND_ASSIGN( DocumentFilterData doc_filter_data, - doc_store->GetAliveDocumentFilterData(document_id2)); + doc_store->GetAliveDocumentFilterData( + document_id2, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(doc_filter_data, Eq(DocumentFilterData( /*namespace_id=*/0, @@ -1568,7 +1596,8 @@ TEST_F(DocumentStoreTest, MaxDocumentId) { EXPECT_THAT(doc_store->last_added_document_id(), Eq(document_id1)); // Still returns the last DocumentId even if it was deleted - ICING_ASSERT_OK(doc_store->Delete("icing", "email/1")); + ICING_ASSERT_OK(doc_store->Delete("icing", "email/1", + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(doc_store->last_added_document_id(), Eq(document_id1)); ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id2, @@ -1904,7 +1933,8 @@ TEST_F(DocumentStoreTest, NonexistentDocumentFilterDataNotFound) { std::unique_ptr<DocumentStore> doc_store = std::move(create_result.document_store); - EXPECT_FALSE(doc_store->GetAliveDocumentFilterData(/*document_id=*/0)); + EXPECT_FALSE(doc_store->GetAliveDocumentFilterData( + /*document_id=*/0, fake_clock_.GetSystemTimeMilliseconds())); } TEST_F(DocumentStoreTest, DeleteClearsFilterCache) { @@ -1920,15 +1950,18 @@ TEST_F(DocumentStoreTest, DeleteClearsFilterCache) { ICING_ASSERT_HAS_VALUE_AND_ASSIGN( DocumentFilterData doc_filter_data, - doc_store->GetAliveDocumentFilterData(document_id)); + doc_store->GetAliveDocumentFilterData( + document_id, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(doc_filter_data, Eq(DocumentFilterData( /*namespace_id=*/0, /*schema_type_id=*/0, document1_expiration_timestamp_))); - ICING_ASSERT_OK(doc_store->Delete("icing", "email/1")); + ICING_ASSERT_OK(doc_store->Delete("icing", "email/1", + fake_clock_.GetSystemTimeMilliseconds())); // Associated entry of the deleted document is removed. - EXPECT_FALSE(doc_store->GetAliveDocumentFilterData(document_id)); + EXPECT_FALSE(doc_store->GetAliveDocumentFilterData( + document_id, fake_clock_.GetSystemTimeMilliseconds())); } TEST_F(DocumentStoreTest, DeleteClearsScoreCache) { @@ -1949,10 +1982,15 @@ TEST_F(DocumentStoreTest, DeleteClearsScoreCache) { /*creation_timestamp_ms=*/document1_creation_timestamp_, /*length_in_tokens=*/4))); - ICING_ASSERT_OK(doc_store->Delete("icing", "email/1")); + ICING_ASSERT_OK(doc_store->Delete("icing", "email/1", + fake_clock_.GetSystemTimeMilliseconds())); // Associated entry of the deleted document is removed. - EXPECT_THAT(doc_store->GetDocumentAssociatedScoreData(document_id), - StatusIs(libtextclassifier3::StatusCode::NOT_FOUND)); + EXPECT_THAT( + doc_store->GetDocumentAssociatedScoreData(document_id), + IsOkAndHolds(DocumentAssociatedScoreData(kInvalidCorpusId, + /*document_score=*/-1, + /*creation_timestamp_ms=*/-1, + /*length_in_tokens=*/0))); } TEST_F(DocumentStoreTest, DeleteShouldPreventUsageScores) { @@ -1974,12 +2012,15 @@ TEST_F(DocumentStoreTest, DeleteShouldPreventUsageScores) { UsageStore::UsageScores expected_scores; expected_scores.usage_type1_count = 1; - ICING_ASSERT_HAS_VALUE_AND_ASSIGN(UsageStore::UsageScores actual_scores, - doc_store->GetUsageScores(document_id)); + ICING_ASSERT_HAS_VALUE_AND_ASSIGN( + UsageStore::UsageScores actual_scores, + doc_store->GetUsageScores(document_id, + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(actual_scores, Eq(expected_scores)); // Delete the document. - ICING_ASSERT_OK(doc_store->Delete("icing", "email/1")); + ICING_ASSERT_OK(doc_store->Delete("icing", "email/1", + fake_clock_.GetSystemTimeMilliseconds())); // Can't report or get usage scores on the deleted document ASSERT_THAT( @@ -1987,7 +2028,8 @@ TEST_F(DocumentStoreTest, DeleteShouldPreventUsageScores) { StatusIs(libtextclassifier3::StatusCode::NOT_FOUND, HasSubstr("Couldn't report usage on a nonexistent document"))); - EXPECT_FALSE(doc_store->GetUsageScores(document_id)); + EXPECT_FALSE(doc_store->GetUsageScores( + document_id, fake_clock_.GetSystemTimeMilliseconds())); } TEST_F(DocumentStoreTest, ExpirationShouldPreventUsageScores) { @@ -2021,8 +2063,10 @@ TEST_F(DocumentStoreTest, ExpirationShouldPreventUsageScores) { UsageStore::UsageScores expected_scores; expected_scores.usage_type1_count = 1; - ICING_ASSERT_HAS_VALUE_AND_ASSIGN(UsageStore::UsageScores actual_scores, - doc_store->GetUsageScores(document_id)); + ICING_ASSERT_HAS_VALUE_AND_ASSIGN( + UsageStore::UsageScores actual_scores, + doc_store->GetUsageScores(document_id, + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(actual_scores, Eq(expected_scores)); // Some arbitrary time past the document's creation time (10) + ttl (100) @@ -2034,7 +2078,8 @@ TEST_F(DocumentStoreTest, ExpirationShouldPreventUsageScores) { StatusIs(libtextclassifier3::StatusCode::NOT_FOUND, HasSubstr("Couldn't report usage on a nonexistent document"))); - EXPECT_FALSE(doc_store->GetUsageScores(document_id)); + EXPECT_FALSE(doc_store->GetUsageScores( + document_id, fake_clock_.GetSystemTimeMilliseconds())); } TEST_F(DocumentStoreTest, @@ -2056,7 +2101,8 @@ TEST_F(DocumentStoreTest, ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id, doc_store->Put(document)); ICING_ASSERT_HAS_VALUE_AND_ASSIGN( DocumentFilterData doc_filter_data, - doc_store->GetAliveDocumentFilterData(document_id)); + doc_store->GetAliveDocumentFilterData( + document_id, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(doc_filter_data, Eq(DocumentFilterData( /*namespace_id=*/0, /*schema_type_id=*/0, @@ -2082,7 +2128,8 @@ TEST_F(DocumentStoreTest, ExpirationTimestampIsInt64MaxIfTtlIsZero) { ICING_ASSERT_HAS_VALUE_AND_ASSIGN( DocumentFilterData doc_filter_data, - doc_store->GetAliveDocumentFilterData(document_id)); + doc_store->GetAliveDocumentFilterData( + document_id, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT( doc_filter_data, @@ -2112,7 +2159,8 @@ TEST_F(DocumentStoreTest, ExpirationTimestampIsInt64MaxOnOverflow) { ICING_ASSERT_HAS_VALUE_AND_ASSIGN( DocumentFilterData doc_filter_data, - doc_store->GetAliveDocumentFilterData(document_id)); + doc_store->GetAliveDocumentFilterData( + document_id, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT( doc_filter_data, @@ -2318,7 +2366,8 @@ TEST_F(DocumentStoreTest, RegenerateDerivedFilesSkipsUnknownSchemaTypeIds) { IsOkAndHolds(EqualsProto(email_document))); ICING_ASSERT_HAS_VALUE_AND_ASSIGN( DocumentFilterData email_data, - document_store->GetAliveDocumentFilterData(email_document_id)); + document_store->GetAliveDocumentFilterData( + email_document_id, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(email_data.schema_type_id(), Eq(email_schema_type_id)); email_namespace_id = email_data.namespace_id(); email_expiration_timestamp = email_data.expiration_timestamp_ms(); @@ -2331,7 +2380,8 @@ TEST_F(DocumentStoreTest, RegenerateDerivedFilesSkipsUnknownSchemaTypeIds) { IsOkAndHolds(EqualsProto(message_document))); ICING_ASSERT_HAS_VALUE_AND_ASSIGN( DocumentFilterData message_data, - document_store->GetAliveDocumentFilterData(message_document_id)); + document_store->GetAliveDocumentFilterData( + message_document_id, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(message_data.schema_type_id(), Eq(message_schema_type_id)); message_namespace_id = message_data.namespace_id(); message_expiration_timestamp = message_data.expiration_timestamp_ms(); @@ -2373,7 +2423,8 @@ TEST_F(DocumentStoreTest, RegenerateDerivedFilesSkipsUnknownSchemaTypeIds) { IsOkAndHolds(EqualsProto(email_document))); ICING_ASSERT_HAS_VALUE_AND_ASSIGN( DocumentFilterData email_data, - document_store->GetAliveDocumentFilterData(email_document_id)); + document_store->GetAliveDocumentFilterData( + email_document_id, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(email_data.schema_type_id(), Eq(email_schema_type_id)); // Make sure that all the other fields are stll valid/the same EXPECT_THAT(email_data.namespace_id(), Eq(email_namespace_id)); @@ -2385,7 +2436,8 @@ TEST_F(DocumentStoreTest, RegenerateDerivedFilesSkipsUnknownSchemaTypeIds) { IsOkAndHolds(EqualsProto(message_document))); ICING_ASSERT_HAS_VALUE_AND_ASSIGN( DocumentFilterData message_data, - document_store->GetAliveDocumentFilterData(message_document_id)); + document_store->GetAliveDocumentFilterData( + message_document_id, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(message_data.schema_type_id(), Eq(-1)); // Make sure that all the other fields are stll valid/the same EXPECT_THAT(message_data.namespace_id(), Eq(message_namespace_id)); @@ -2441,14 +2493,16 @@ TEST_F(DocumentStoreTest, UpdateSchemaStoreUpdatesSchemaTypeIds) { document_store->Put(email_document)); ICING_ASSERT_HAS_VALUE_AND_ASSIGN( DocumentFilterData email_data, - document_store->GetAliveDocumentFilterData(email_document_id)); + document_store->GetAliveDocumentFilterData( + email_document_id, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(email_data.schema_type_id(), Eq(old_email_schema_type_id)); ICING_ASSERT_OK_AND_ASSIGN(DocumentId message_document_id, document_store->Put(message_document)); ICING_ASSERT_HAS_VALUE_AND_ASSIGN( DocumentFilterData message_data, - document_store->GetAliveDocumentFilterData(message_document_id)); + document_store->GetAliveDocumentFilterData( + message_document_id, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(message_data.schema_type_id(), Eq(old_message_schema_type_id)); // Rearrange the schema types. Since SchemaTypeId is assigned based on order, @@ -2476,12 +2530,14 @@ TEST_F(DocumentStoreTest, UpdateSchemaStoreUpdatesSchemaTypeIds) { // Check that the FilterCache holds the new SchemaTypeIds ICING_ASSERT_HAS_VALUE_AND_ASSIGN( email_data, - document_store->GetAliveDocumentFilterData(email_document_id)); + document_store->GetAliveDocumentFilterData( + email_document_id, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(email_data.schema_type_id(), Eq(new_email_schema_type_id)); ICING_ASSERT_HAS_VALUE_AND_ASSIGN( message_data, - document_store->GetAliveDocumentFilterData(message_document_id)); + document_store->GetAliveDocumentFilterData( + message_document_id, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(message_data.schema_type_id(), Eq(new_message_schema_type_id)); } @@ -2683,14 +2739,16 @@ TEST_F(DocumentStoreTest, OptimizedUpdateSchemaStoreUpdatesSchemaTypeIds) { document_store->Put(email_document)); ICING_ASSERT_HAS_VALUE_AND_ASSIGN( DocumentFilterData email_data, - document_store->GetAliveDocumentFilterData(email_document_id)); + document_store->GetAliveDocumentFilterData( + email_document_id, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(email_data.schema_type_id(), Eq(old_email_schema_type_id)); ICING_ASSERT_OK_AND_ASSIGN(DocumentId message_document_id, document_store->Put(message_document)); ICING_ASSERT_HAS_VALUE_AND_ASSIGN( DocumentFilterData message_data, - document_store->GetAliveDocumentFilterData(message_document_id)); + document_store->GetAliveDocumentFilterData( + message_document_id, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(message_data.schema_type_id(), Eq(old_message_schema_type_id)); // Rearrange the schema types. Since SchemaTypeId is assigned based on order, @@ -2721,12 +2779,14 @@ TEST_F(DocumentStoreTest, OptimizedUpdateSchemaStoreUpdatesSchemaTypeIds) { // Check that the FilterCache holds the new SchemaTypeIds ICING_ASSERT_HAS_VALUE_AND_ASSIGN( email_data, - document_store->GetAliveDocumentFilterData(email_document_id)); + document_store->GetAliveDocumentFilterData( + email_document_id, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(email_data.schema_type_id(), Eq(new_email_schema_type_id)); ICING_ASSERT_HAS_VALUE_AND_ASSIGN( message_data, - document_store->GetAliveDocumentFilterData(message_document_id)); + document_store->GetAliveDocumentFilterData( + message_document_id, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(message_data.schema_type_id(), Eq(new_message_schema_type_id)); } @@ -2909,8 +2969,9 @@ TEST_F(DocumentStoreTest, GetOptimizeInfo) { EXPECT_THAT(optimize_info.estimated_optimizable_bytes, Eq(0)); // Delete a document. Now something is optimizable - ICING_EXPECT_OK(document_store->Delete(test_document1_.namespace_(), - test_document1_.uri())); + ICING_EXPECT_OK(document_store->Delete( + test_document1_.namespace_(), test_document1_.uri(), + fake_clock_.GetSystemTimeMilliseconds())); ICING_ASSERT_OK_AND_ASSIGN(optimize_info, document_store->GetOptimizeInfo()); EXPECT_THAT(optimize_info.total_docs, Eq(1)); EXPECT_THAT(optimize_info.optimizable_docs, Eq(1)); @@ -2990,13 +3051,15 @@ TEST_F(DocumentStoreTest, GetAllNamespaces) { // After deleting namespace2_uri1, there's still namespace2_uri2, so // "namespace2" still shows up in results - ICING_EXPECT_OK(document_store->Delete("namespace2", "uri1")); + ICING_EXPECT_OK(document_store->Delete( + "namespace2", "uri1", fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(document_store->GetAllNamespaces(), UnorderedElementsAre("namespace1", "namespace2", "namespace3")); // After deleting namespace2_uri2, there's no more documents in "namespace2" - ICING_EXPECT_OK(document_store->Delete("namespace2", "uri2")); + ICING_EXPECT_OK(document_store->Delete( + "namespace2", "uri2", fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(document_store->GetAllNamespaces(), UnorderedElementsAre("namespace1", "namespace3")); @@ -3030,7 +3093,8 @@ TEST_F(DocumentStoreTest, ReportUsageWithDifferentTimestampsAndGetUsageScores) { ++expected_scores.usage_type1_count; ICING_ASSERT_HAS_VALUE_AND_ASSIGN( UsageStore::UsageScores actual_scores, - document_store->GetUsageScores(document_id)); + document_store->GetUsageScores(document_id, + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(actual_scores, Eq(expected_scores)); // Report usage with type 1 and time 5, time should be updated. @@ -3042,7 +3106,8 @@ TEST_F(DocumentStoreTest, ReportUsageWithDifferentTimestampsAndGetUsageScores) { expected_scores.usage_type1_last_used_timestamp_s = 5; ++expected_scores.usage_type1_count; ICING_ASSERT_HAS_VALUE_AND_ASSIGN( - actual_scores, document_store->GetUsageScores(document_id)); + actual_scores, document_store->GetUsageScores( + document_id, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(actual_scores, Eq(expected_scores)); // Report usage with type 2 and time 1. @@ -3054,7 +3119,8 @@ TEST_F(DocumentStoreTest, ReportUsageWithDifferentTimestampsAndGetUsageScores) { expected_scores.usage_type2_last_used_timestamp_s = 1; ++expected_scores.usage_type2_count; ICING_ASSERT_HAS_VALUE_AND_ASSIGN( - actual_scores, document_store->GetUsageScores(document_id)); + actual_scores, document_store->GetUsageScores( + document_id, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(actual_scores, Eq(expected_scores)); // Report usage with type 2 and time 5. @@ -3066,7 +3132,8 @@ TEST_F(DocumentStoreTest, ReportUsageWithDifferentTimestampsAndGetUsageScores) { expected_scores.usage_type2_last_used_timestamp_s = 5; ++expected_scores.usage_type2_count; ICING_ASSERT_HAS_VALUE_AND_ASSIGN( - actual_scores, document_store->GetUsageScores(document_id)); + actual_scores, document_store->GetUsageScores( + document_id, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(actual_scores, Eq(expected_scores)); // Report usage with type 3 and time 1. @@ -3078,7 +3145,8 @@ TEST_F(DocumentStoreTest, ReportUsageWithDifferentTimestampsAndGetUsageScores) { expected_scores.usage_type3_last_used_timestamp_s = 1; ++expected_scores.usage_type3_count; ICING_ASSERT_HAS_VALUE_AND_ASSIGN( - actual_scores, document_store->GetUsageScores(document_id)); + actual_scores, document_store->GetUsageScores( + document_id, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(actual_scores, Eq(expected_scores)); // Report usage with type 3 and time 5. @@ -3090,7 +3158,8 @@ TEST_F(DocumentStoreTest, ReportUsageWithDifferentTimestampsAndGetUsageScores) { expected_scores.usage_type3_last_used_timestamp_s = 5; ++expected_scores.usage_type3_count; ICING_ASSERT_HAS_VALUE_AND_ASSIGN( - actual_scores, document_store->GetUsageScores(document_id)); + actual_scores, document_store->GetUsageScores( + document_id, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(actual_scores, Eq(expected_scores)); } @@ -3115,7 +3184,8 @@ TEST_F(DocumentStoreTest, ReportUsageWithDifferentTypesAndGetUsageScores) { ++expected_scores.usage_type1_count; ICING_ASSERT_HAS_VALUE_AND_ASSIGN( UsageStore::UsageScores actual_scores, - document_store->GetUsageScores(document_id)); + document_store->GetUsageScores(document_id, + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(actual_scores, Eq(expected_scores)); // Report usage with type 2. @@ -3126,7 +3196,8 @@ TEST_F(DocumentStoreTest, ReportUsageWithDifferentTypesAndGetUsageScores) { ++expected_scores.usage_type2_count; ICING_ASSERT_HAS_VALUE_AND_ASSIGN( - actual_scores, document_store->GetUsageScores(document_id)); + actual_scores, document_store->GetUsageScores( + document_id, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(actual_scores, Eq(expected_scores)); // Report usage with type 3. @@ -3137,7 +3208,8 @@ TEST_F(DocumentStoreTest, ReportUsageWithDifferentTypesAndGetUsageScores) { ++expected_scores.usage_type3_count; ICING_ASSERT_HAS_VALUE_AND_ASSIGN( - actual_scores, document_store->GetUsageScores(document_id)); + actual_scores, document_store->GetUsageScores( + document_id, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(actual_scores, Eq(expected_scores)); } @@ -3164,7 +3236,8 @@ TEST_F(DocumentStoreTest, UsageScoresShouldNotBeClearedOnChecksumMismatch) { ++expected_scores.usage_type1_count; ICING_ASSERT_HAS_VALUE_AND_ASSIGN( UsageStore::UsageScores actual_scores, - document_store->GetUsageScores(document_id)); + document_store->GetUsageScores( + document_id, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(actual_scores, Eq(expected_scores)); } @@ -3180,7 +3253,8 @@ TEST_F(DocumentStoreTest, UsageScoresShouldNotBeClearedOnChecksumMismatch) { // Usage scores should be the same. ICING_ASSERT_HAS_VALUE_AND_ASSIGN( UsageStore::UsageScores actual_scores, - document_store->GetUsageScores(document_id)); + document_store->GetUsageScores(document_id, + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(actual_scores, Eq(expected_scores)); } @@ -3207,7 +3281,8 @@ TEST_F(DocumentStoreTest, UsageScoresShouldBeAvailableAfterDataLoss) { ++expected_scores.usage_type1_count; ICING_ASSERT_HAS_VALUE_AND_ASSIGN( UsageStore::UsageScores actual_scores, - document_store->GetUsageScores(document_id)); + document_store->GetUsageScores( + document_id, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(actual_scores, Eq(expected_scores)); } @@ -3234,7 +3309,8 @@ TEST_F(DocumentStoreTest, UsageScoresShouldBeAvailableAfterDataLoss) { // Usage scores should still be available. ICING_ASSERT_HAS_VALUE_AND_ASSIGN( UsageStore::UsageScores actual_scores, - document_store->GetUsageScores(document_id)); + document_store->GetUsageScores(document_id, + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(actual_scores, Eq(expected_scores)); } @@ -3260,7 +3336,8 @@ TEST_F(DocumentStoreTest, UsageScoresShouldBeCopiedOverToUpdatedDocument) { ++expected_scores.usage_type1_count; ICING_ASSERT_HAS_VALUE_AND_ASSIGN( UsageStore::UsageScores actual_scores, - document_store->GetUsageScores(document_id)); + document_store->GetUsageScores(document_id, + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(actual_scores, Eq(expected_scores)); // Update the document. @@ -3272,7 +3349,9 @@ TEST_F(DocumentStoreTest, UsageScoresShouldBeCopiedOverToUpdatedDocument) { // Usage scores should be the same. ICING_ASSERT_HAS_VALUE_AND_ASSIGN( - actual_scores, document_store->GetUsageScores(updated_document_id)); + actual_scores, + document_store->GetUsageScores(updated_document_id, + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(actual_scores, Eq(expected_scores)); } @@ -3290,7 +3369,8 @@ TEST_F(DocumentStoreTest, UsageScoresShouldPersistOnOptimize) { ICING_ASSERT_OK_AND_ASSIGN( DocumentId document_id2, document_store->Put(DocumentProto(test_document2_))); - ICING_ASSERT_OK(document_store->Delete(document_id1)); + ICING_ASSERT_OK(document_store->Delete( + document_id1, fake_clock_.GetSystemTimeMilliseconds())); // Report usage of document 2. UsageReport usage_report = CreateUsageReport( @@ -3302,7 +3382,8 @@ TEST_F(DocumentStoreTest, UsageScoresShouldPersistOnOptimize) { ++expected_scores.usage_type1_count; ICING_ASSERT_HAS_VALUE_AND_ASSIGN( UsageStore::UsageScores actual_scores, - document_store->GetUsageScores(document_id2)); + document_store->GetUsageScores(document_id2, + fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(actual_scores, Eq(expected_scores)); // Run optimize @@ -3323,7 +3404,8 @@ TEST_F(DocumentStoreTest, UsageScoresShouldPersistOnOptimize) { // The original document_id2 should have become document_id2 - 1. ICING_ASSERT_HAS_VALUE_AND_ASSIGN( actual_scores, - optimized_document_store->GetUsageScores(document_id2 - 1)); + optimized_document_store->GetUsageScores( + document_id2 - 1, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(actual_scores, Eq(expected_scores)); } @@ -3542,7 +3624,8 @@ TEST_F(DocumentStoreTest, DocumentStoreStorageInfo) { ICING_ASSERT_OK(doc_store->ReportUsage(usage_report_type1)); // Delete the first doc. - ICING_ASSERT_OK(doc_store->Delete(document1.namespace_(), document1.uri())); + ICING_ASSERT_OK(doc_store->Delete(document1.namespace_(), document1.uri(), + fake_clock_.GetSystemTimeMilliseconds())); // Expire the second doc. fake_clock_.SetSystemTimeMilliseconds(document2.creation_timestamp_ms() + @@ -3649,7 +3732,8 @@ TEST_F(DocumentStoreTest, InitializeForceRecoveryUpdatesTypeIds) { ICING_ASSERT_OK_AND_ASSIGN(docid, doc_store->Put(doc)); ICING_ASSERT_HAS_VALUE_AND_ASSIGN( DocumentFilterData filter_data, - doc_store->GetAliveDocumentFilterData(docid)); + doc_store->GetAliveDocumentFilterData( + docid, fake_clock_.GetSystemTimeMilliseconds())); ASSERT_THAT(filter_data.schema_type_id(), Eq(0)); } @@ -3697,7 +3781,8 @@ TEST_F(DocumentStoreTest, InitializeForceRecoveryUpdatesTypeIds) { // Ensure that the type id of the email document has been correctly updated. ICING_ASSERT_HAS_VALUE_AND_ASSIGN( DocumentFilterData filter_data, - doc_store->GetAliveDocumentFilterData(docid)); + doc_store->GetAliveDocumentFilterData( + docid, fake_clock_.GetSystemTimeMilliseconds())); EXPECT_THAT(filter_data.schema_type_id(), Eq(1)); EXPECT_THAT(initialize_stats.document_store_recovery_cause(), Eq(InitializeStatsProto::SCHEMA_CHANGES_OUT_OF_SYNC)); @@ -3758,7 +3843,8 @@ TEST_F(DocumentStoreTest, InitializeDontForceRecoveryDoesntUpdateTypeIds) { ICING_ASSERT_OK_AND_ASSIGN(docid, doc_store->Put(doc)); ICING_ASSERT_HAS_VALUE_AND_ASSIGN( DocumentFilterData filter_data, - doc_store->GetAliveDocumentFilterData(docid)); + doc_store->GetAliveDocumentFilterData( + docid, fake_clock_.GetSystemTimeMilliseconds())); ASSERT_THAT(filter_data.schema_type_id(), Eq(0)); } @@ -3800,7 +3886,8 @@ TEST_F(DocumentStoreTest, InitializeDontForceRecoveryDoesntUpdateTypeIds) { // Check that the type id of the email document has not been updated. ICING_ASSERT_HAS_VALUE_AND_ASSIGN( DocumentFilterData filter_data, - doc_store->GetAliveDocumentFilterData(docid)); + doc_store->GetAliveDocumentFilterData( + docid, fake_clock_.GetSystemTimeMilliseconds())); ASSERT_THAT(filter_data.schema_type_id(), Eq(0)); } } @@ -4256,7 +4343,8 @@ TEST_F(DocumentStoreTest, GetDebugInfo) { EqualsProto(info3))); // Delete document3. - ICING_ASSERT_OK(document_store->Delete("namespace2", "email/3")); + ICING_ASSERT_OK(document_store->Delete( + "namespace2", "email/3", fake_clock_.GetSystemTimeMilliseconds())); ICING_ASSERT_OK_AND_ASSIGN( DocumentDebugInfoProto out2, document_store->GetDebugInfo(DebugInfoVerbosity::DETAILED)); diff --git a/icing/store/suggestion-result-checker-impl.h b/icing/store/suggestion-result-checker-impl.h index f6789e8..4e01f81 100644 --- a/icing/store/suggestion-result-checker-impl.h +++ b/icing/store/suggestion-result-checker-impl.h @@ -33,7 +33,8 @@ class SuggestionResultCheckerImpl : public SuggestionResultChecker { document_id_filter_map, std::unordered_set<SchemaTypeId> target_schema_type_ids, std::unordered_map<SchemaTypeId, SectionIdMask> property_filter_map, - std::string target_section, std::unordered_set<DocumentId> search_base) + std::string target_section, std::unordered_set<DocumentId> search_base, + int64_t current_time_ms) : document_store_(*document_store), schema_store_(*schema_store), target_namespace_ids_(std::move(target_namespace_ids)), @@ -41,7 +42,8 @@ class SuggestionResultCheckerImpl : public SuggestionResultChecker { target_schema_type_ids_(std::move(target_schema_type_ids)), property_filter_map_(std::move(property_filter_map)), target_section_(std::move(target_section)), - search_base_(std::move(search_base)) {} + search_base_(std::move(search_base)), + current_time_ms_(current_time_ms) {} bool MatchesTargetNamespace(NamespaceId namespace_id) const { return target_namespace_ids_.empty() || @@ -102,7 +104,8 @@ class SuggestionResultCheckerImpl : public SuggestionResultChecker { SectionId section_id) const override { // Get the document filter data first. auto document_filter_data_optional_ = - document_store_.GetAliveDocumentFilterData(document_id); + document_store_.GetAliveDocumentFilterData(document_id, + current_time_ms_); if (!document_filter_data_optional_) { // The document doesn't exist. return false; @@ -142,6 +145,7 @@ class SuggestionResultCheckerImpl : public SuggestionResultChecker { std::unordered_map<SchemaTypeId, SectionIdMask> property_filter_map_; std::string target_section_; std::unordered_set<DocumentId> search_base_; + int64_t current_time_ms_; }; } // namespace lib diff --git a/synced_AOSP_CL_number.txt b/synced_AOSP_CL_number.txt index e53b3d1..afb1234 100644 --- a/synced_AOSP_CL_number.txt +++ b/synced_AOSP_CL_number.txt @@ -1 +1 @@ -set(synced_AOSP_CL_number=533597029) +set(synced_AOSP_CL_number=537223436) |