Merge branch 'upstream-master' into androidx-master-dev
* upstream-master:
Update Icing from upstream.
Change-Id: Iac054539d5d151f52ddb316f351487b2c4e77a4e
diff --git a/icing/file/file-backed-proto-log.h b/icing/file/file-backed-proto-log.h
index aa5a031..763c93b 100644
--- a/icing/file/file-backed-proto-log.h
+++ b/icing/file/file-backed-proto-log.h
@@ -72,6 +72,7 @@
#include "icing/legacy/core/icing-string-util.h"
#include "icing/portable/zlib.h"
#include "icing/util/crc32.h"
+#include "icing/util/data-loss.h"
#include "icing/util/logging.h"
#include "icing/util/status-macros.h"
@@ -172,10 +173,10 @@
// happen if the file is corrupted or some previously added data was
// unpersisted. This may be used to signal that any derived data off of the
// proto log may need to be regenerated.
- enum DataStatus { NO_DATA_LOSS, PARTIAL_LOSS, COMPLETE_LOSS } data_status;
+ DataLoss data_loss;
bool has_data_loss() {
- return data_status == PARTIAL_LOSS || data_status == COMPLETE_LOSS;
+ return data_loss == DataLoss::PARTIAL || data_loss == DataLoss::COMPLETE;
}
};
@@ -186,11 +187,11 @@
// added data was unpersisted, the log will rewind to the last-good state. The
// log saves these checkpointed "good" states when PersistToDisk() is called
// or the log is safely destructed. If the log rewinds successfully to the
- // last-good state, then the returned CreateResult.data_status indicates
+ // last-good state, then the returned CreateResult.data_loss indicates
// whether it has a data loss and what kind of data loss it is (partial or
// complete) so that any derived data may know that it needs to be updated. If
// the log re-initializes successfully without any data loss,
- // CreateResult.data_status will be NO_DATA_LOSS.
+ // CreateResult.data_loss will be NONE.
//
// Params:
// filesystem: Handles system level calls
@@ -370,7 +371,7 @@
// Initializes a new proto log.
//
// Returns:
- // std::unique_ptr<FileBackedProtoLog> that can be used immediately
+ // std::unique_ptr<CreateResult> on success
// INTERNAL_ERROR on IO error
static libtextclassifier3::StatusOr<CreateResult> InitializeNewFile(
const Filesystem* filesystem, const std::string& file_path,
@@ -381,7 +382,7 @@
// content will be lost.
//
// Returns:
- // std::unique_ptr<FileBackedProtoLog> that can be used immediately
+ // std::unique_ptr<CreateResult> on success
// INTERNAL_ERROR on IO error or internal inconsistencies in the file
// INVALID_ARGUMENT_ERROR if options aren't consistent with previous
// instances
@@ -516,7 +517,7 @@
std::unique_ptr<FileBackedProtoLog<ProtoT>>(
new FileBackedProtoLog<ProtoT>(filesystem, file_path,
std::move(header))),
- /*data_status=*/CreateResult::NO_DATA_LOSS};
+ /*data_loss=*/DataLoss::NONE};
return create_result;
}
@@ -566,7 +567,7 @@
}
header->max_proto_size = options.max_proto_size;
- typename CreateResult::DataStatus data_status = CreateResult::NO_DATA_LOSS;
+ DataLoss data_loss = DataLoss::NONE;
ICING_ASSIGN_OR_RETURN(Crc32 calculated_log_checksum,
ComputeChecksum(filesystem, file_path, Crc32(),
sizeof(Header), file_size));
@@ -589,12 +590,12 @@
// Check if it matches our last rewind state. If so, this becomes our last
// good state and we can safely truncate and recover from here.
last_known_good = header->rewind_offset;
- data_status = CreateResult::PARTIAL_LOSS;
+ data_loss = DataLoss::PARTIAL;
} else {
// Otherwise, we're going to truncate the entire log and this resets the
// checksum to an empty log state.
header->log_checksum = 0;
- data_status = CreateResult::COMPLETE_LOSS;
+ data_loss = DataLoss::COMPLETE;
}
if (!filesystem->Truncate(file_path.c_str(), last_known_good)) {
@@ -610,7 +611,7 @@
std::unique_ptr<FileBackedProtoLog<ProtoT>>(
new FileBackedProtoLog<ProtoT>(filesystem, file_path,
std::move(header))),
- data_status};
+ data_loss};
return create_result;
}
diff --git a/icing/file/file-backed-proto-log_test.cc b/icing/file/file-backed-proto-log_test.cc
index 7410d2b..d429277 100644
--- a/icing/file/file-backed-proto-log_test.cc
+++ b/icing/file/file-backed-proto-log_test.cc
@@ -339,6 +339,7 @@
max_proto_size_)));
auto proto_log = std::move(create_result.proto_log);
ASSERT_TRUE(create_result.has_data_loss());
+ ASSERT_THAT(create_result.data_loss, Eq(DataLoss::COMPLETE));
// Lost everything in the log since the rewind position doesn't help if
// there's been data corruption within the persisted region
@@ -408,6 +409,7 @@
max_proto_size_)));
auto proto_log = std::move(create_result.proto_log);
ASSERT_TRUE(create_result.has_data_loss());
+ ASSERT_THAT(create_result.data_loss, Eq(DataLoss::PARTIAL));
// Check that everything was persisted across instances
ASSERT_THAT(proto_log->ReadProto(document1_offset),
diff --git a/icing/file/file-backed-proto.h b/icing/file/file-backed-proto.h
index aede8de..15a1953 100644
--- a/icing/file/file-backed-proto.h
+++ b/icing/file/file-backed-proto.h
@@ -83,7 +83,7 @@
//
// TODO(cassiewang) The implementation today loses old data if Write() fails.
// We should write to a tmp file first and rename the file to fix this.
- // TODO(samzheng) Change to Write(ProtoT&& proto)
+ // TODO(cassiewang) Change to Write(ProtoT&& proto)
libtextclassifier3::Status Write(std::unique_ptr<ProtoT> proto)
ICING_LOCKS_EXCLUDED(mutex_);
diff --git a/icing/helpers/icu/icu-data-file-helper.cc b/icing/helpers/icu/icu-data-file-helper.cc
index 5cf6a1d..6607c40 100644
--- a/icing/helpers/icu/icu-data-file-helper.cc
+++ b/icing/helpers/icu/icu-data-file-helper.cc
@@ -49,8 +49,6 @@
return absl_ports::InternalError("Unable to open file at provided path");
}
- // TODO(samzheng): figure out why icing::MemoryMappedFile causes
- // segmentation fault here.
const void* data =
mmap(nullptr, file_size, PROT_READ, MAP_PRIVATE, fd.get(), 0);
diff --git a/icing/icing-search-engine.cc b/icing/icing-search-engine.cc
index 08ceafd..c40bac9 100644
--- a/icing/icing-search-engine.cc
+++ b/icing/icing-search-engine.cc
@@ -60,7 +60,6 @@
#include "icing/util/crc32.h"
#include "icing/util/logging.h"
#include "icing/util/status-macros.h"
-#include "icing/util/timer.h"
#include "unicode/uloc.h"
namespace icing {
@@ -264,7 +263,7 @@
<< options_.base_dir();
// Measure the latency of the initialization process.
- Timer initialize_timer;
+ std::unique_ptr<Timer> initialize_timer = clock_->GetNewTimer();
InitializeResultProto result_proto;
StatusProto* result_status = result_proto.mutable_status();
@@ -273,7 +272,8 @@
if (initialized_) {
// Already initialized.
result_status->set_code(StatusProto::OK);
- initialize_stats->set_latency_ms(initialize_timer.GetElapsedMilliseconds());
+ initialize_stats->set_latency_ms(
+ initialize_timer->GetElapsedMilliseconds());
initialize_stats->set_num_documents(document_store_->num_documents());
return result_proto;
}
@@ -284,7 +284,8 @@
libtextclassifier3::Status status = InitializeMembers(initialize_stats);
if (!status.ok()) {
TransformStatus(status, result_status);
- initialize_stats->set_latency_ms(initialize_timer.GetElapsedMilliseconds());
+ initialize_stats->set_latency_ms(
+ initialize_timer->GetElapsedMilliseconds());
return result_proto;
}
@@ -336,10 +337,10 @@
// index.
initialize_stats->set_index_restoration_cause(
NativeInitializeStats::INCONSISTENT_WITH_GROUND_TRUTH);
- Timer index_restore_timer;
+ std::unique_ptr<Timer> index_restore_timer = clock_->GetNewTimer();
status = RestoreIndexIfNeeded();
initialize_stats->set_index_restoration_latency_ms(
- index_restore_timer.GetElapsedMilliseconds());
+ index_restore_timer->GetElapsedMilliseconds());
}
}
}
@@ -348,7 +349,7 @@
initialized_ = true;
}
TransformStatus(status, result_status);
- initialize_stats->set_latency_ms(initialize_timer.GetElapsedMilliseconds());
+ initialize_stats->set_latency_ms(initialize_timer->GetElapsedMilliseconds());
return result_proto;
}
@@ -398,7 +399,7 @@
}
ICING_ASSIGN_OR_RETURN(
schema_store_, SchemaStore::Create(filesystem_.get(), schema_store_dir,
- initialize_stats));
+ clock_.get(), initialize_stats));
return libtextclassifier3::Status::OK;
}
@@ -415,9 +416,10 @@
absl_ports::StrCat("Could not create directory: ", document_dir));
}
ICING_ASSIGN_OR_RETURN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(filesystem_.get(), document_dir, clock_.get(),
schema_store_.get(), initialize_stats));
+ document_store_ = std::move(create_result.document_store);
return libtextclassifier3::Status::OK;
}
@@ -451,10 +453,10 @@
Index::Create(index_options, filesystem_.get(),
icing_filesystem_.get()));
- Timer restore_timer;
+ std::unique_ptr<Timer> restore_timer = clock_->GetNewTimer();
ICING_RETURN_IF_ERROR(RestoreIndexIfNeeded());
initialize_stats->set_index_restoration_latency_ms(
- restore_timer.GetElapsedMilliseconds());
+ restore_timer->GetElapsedMilliseconds());
} else {
// Index was created fine.
index_ = std::move(index_or).ValueOrDie();
@@ -497,20 +499,20 @@
NativeInitializeStats* initialize_stats, bool log_document_store_stats) {
// Measure the latency of the data recovery. The cause of the recovery should
// be logged by the caller.
- Timer timer;
+ std::unique_ptr<Timer> timer = clock_->GetNewTimer();
ICING_RETURN_IF_ERROR(
document_store_->UpdateSchemaStore(schema_store_.get()));
if (initialize_stats != nullptr && log_document_store_stats) {
initialize_stats->set_document_store_recovery_latency_ms(
- timer.GetElapsedMilliseconds());
+ timer->GetElapsedMilliseconds());
}
// Restart timer.
- timer = Timer();
+ timer = clock_->GetNewTimer();
ICING_RETURN_IF_ERROR(index_->Reset());
ICING_RETURN_IF_ERROR(RestoreIndexIfNeeded());
if (initialize_stats != nullptr) {
initialize_stats->set_index_restoration_latency_ms(
- timer.GetElapsedMilliseconds());
+ timer->GetElapsedMilliseconds());
}
const std::string header_file =
@@ -673,7 +675,7 @@
PutResultProto IcingSearchEngine::Put(DocumentProto&& document) {
ICING_VLOG(1) << "Writing document to document store";
- Timer put_timer;
+ std::unique_ptr<Timer> put_timer = clock_->GetNewTimer();
PutResultProto result_proto;
StatusProto* result_status = result_proto.mutable_status();
@@ -687,24 +689,24 @@
if (!initialized_) {
result_status->set_code(StatusProto::FAILED_PRECONDITION);
result_status->set_message("IcingSearchEngine has not been initialized!");
- put_document_stats->set_latency_ms(put_timer.GetElapsedMilliseconds());
+ put_document_stats->set_latency_ms(put_timer->GetElapsedMilliseconds());
return result_proto;
}
auto document_id_or = document_store_->Put(document, put_document_stats);
if (!document_id_or.ok()) {
TransformStatus(document_id_or.status(), result_status);
- put_document_stats->set_latency_ms(put_timer.GetElapsedMilliseconds());
+ put_document_stats->set_latency_ms(put_timer->GetElapsedMilliseconds());
return result_proto;
}
DocumentId document_id = document_id_or.ValueOrDie();
auto index_processor_or = IndexProcessor::Create(
schema_store_.get(), language_segmenter_.get(), normalizer_.get(),
- index_.get(), CreateIndexProcessorOptions(options_));
+ index_.get(), CreateIndexProcessorOptions(options_), clock_.get());
if (!index_processor_or.ok()) {
TransformStatus(index_processor_or.status(), result_status);
- put_document_stats->set_latency_ms(put_timer.GetElapsedMilliseconds());
+ put_document_stats->set_latency_ms(put_timer->GetElapsedMilliseconds());
return result_proto;
}
std::unique_ptr<IndexProcessor> index_processor =
@@ -714,7 +716,7 @@
index_processor->IndexDocument(document, document_id, put_document_stats);
TransformStatus(status, result_status);
- put_document_stats->set_latency_ms(put_timer.GetElapsedMilliseconds());
+ put_document_stats->set_latency_ms(put_timer->GetElapsedMilliseconds());
return result_proto;
}
@@ -1357,21 +1359,21 @@
// Tries to rebuild document store if swapping fails, to avoid leaving the
// system in the broken state for future operations.
- auto document_store_or =
+ auto create_result_or =
DocumentStore::Create(filesystem_.get(), current_document_dir,
clock_.get(), schema_store_.get());
// TODO(b/144458732): Implement a more robust version of
// TC_ASSIGN_OR_RETURN that can support error logging.
- if (!document_store_or.ok()) {
+ if (!create_result_or.ok()) {
// Unable to create DocumentStore from the old file. Mark as uninitialized
// and return INTERNAL.
initialized_ = false;
ICING_LOG(ERROR) << "Failed to create document store instance";
return absl_ports::Annotate(
absl_ports::InternalError("Failed to create document store instance"),
- document_store_or.status().error_message());
+ create_result_or.status().error_message());
}
- document_store_ = std::move(document_store_or).ValueOrDie();
+ document_store_ = std::move(create_result_or.ValueOrDie().document_store);
// Potential data loss
// TODO(b/147373249): Find a way to detect true data loss error
@@ -1380,10 +1382,10 @@
}
// Recreates the doc store instance
- auto document_store_or =
+ auto create_result_or =
DocumentStore::Create(filesystem_.get(), current_document_dir,
clock_.get(), schema_store_.get());
- if (!document_store_or.ok()) {
+ if (!create_result_or.ok()) {
// Unable to create DocumentStore from the new file. Mark as uninitialized
// and return INTERNAL.
initialized_ = false;
@@ -1391,7 +1393,7 @@
"Document store has been optimized, but a valid document store "
"instance can't be created");
}
- document_store_ = std::move(document_store_or).ValueOrDie();
+ document_store_ = std::move(create_result_or.ValueOrDie().document_store);
// Deletes tmp directory
if (!filesystem_->DeleteDirectoryRecursively(
@@ -1432,9 +1434,9 @@
ICING_ASSIGN_OR_RETURN(
std::unique_ptr<IndexProcessor> index_processor,
- IndexProcessor::Create(schema_store_.get(), language_segmenter_.get(),
- normalizer_.get(), index_.get(),
- CreateIndexProcessorOptions(options_)));
+ IndexProcessor::Create(
+ schema_store_.get(), language_segmenter_.get(), normalizer_.get(),
+ index_.get(), CreateIndexProcessorOptions(options_), clock_.get()));
ICING_VLOG(1) << "Restoring index by replaying documents from document id "
<< first_document_to_reindex << " to document id "
diff --git a/icing/icing-search-engine_test.cc b/icing/icing-search-engine_test.cc
index b642a94..ab05646 100644
--- a/icing/icing-search-engine_test.cc
+++ b/icing/icing-search-engine_test.cc
@@ -41,6 +41,7 @@
#include "icing/testing/common-matchers.h"
#include "icing/testing/fake-clock.h"
#include "icing/testing/jni-test-helpers.h"
+#include "icing/testing/platform.h"
#include "icing/testing/random-string.h"
#include "icing/testing/snippet-helpers.h"
#include "icing/testing/test-data.h"
@@ -99,17 +100,19 @@
class IcingSearchEngineTest : public testing::Test {
protected:
void SetUp() override {
-#ifndef ICING_REVERSE_JNI_SEGMENTATION
- // If we've specified using the reverse-JNI method for segmentation (i.e.
- // not ICU), then we won't have the ICU data file included to set up.
- // Technically, we could choose to use reverse-JNI for segmentation AND
- // include an ICU data file, but that seems unlikely and our current BUILD
- // setup doesn't do this.
- // File generated via icu_data_file rule in //icing/BUILD.
- std::string icu_data_file_path =
- GetTestFilePath("icing/icu.dat");
- ICING_ASSERT_OK(icu_data_file_helper::SetUpICUDataFile(icu_data_file_path));
-#endif // ICING_REVERSE_JNI_SEGMENTATION
+ if (!IsCfStringTokenization() && !IsReverseJniTokenization()) {
+ // If we've specified using the reverse-JNI method for segmentation (i.e.
+ // not ICU), then we won't have the ICU data file included to set up.
+ // Technically, we could choose to use reverse-JNI for segmentation AND
+ // include an ICU data file, but that seems unlikely and our current BUILD
+ // setup doesn't do this.
+ // File generated via icu_data_file rule in //icing/BUILD.
+ std::string icu_data_file_path =
+ GetTestFilePath("icing/icu.dat");
+ ICING_ASSERT_OK(
+ icu_data_file_helper::SetUpICUDataFile(icu_data_file_path));
+ }
+
filesystem_.CreateDirectoryRecursively(GetTestBaseDir().c_str());
}
@@ -2930,9 +2933,10 @@
property->mutable_string_indexing_config()->set_tokenizer_type(
StringIndexingConfig::TokenizerType::PLAIN);
+ FakeClock fake_clock;
ICING_ASSERT_OK_AND_ASSIGN(
std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(filesystem(), GetSchemaDir()));
+ SchemaStore::Create(filesystem(), GetSchemaDir(), &fake_clock));
ICING_EXPECT_OK(schema_store->SetSchema(new_schema));
} // Will persist new schema
@@ -2989,17 +2993,20 @@
} // This should shut down IcingSearchEngine and persist anything it needs to
{
+ FakeClock fake_clock;
ICING_ASSERT_OK_AND_ASSIGN(
std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(filesystem(), GetSchemaDir()));
+ SchemaStore::Create(filesystem(), GetSchemaDir(), &fake_clock));
ICING_EXPECT_OK(schema_store->SetSchema(CreateMessageSchema()));
// Puts a second document into DocumentStore but doesn't index it.
- FakeClock fake_clock;
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(filesystem(), GetDocumentDir(), &fake_clock,
schema_store.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
+
ICING_EXPECT_OK(document_store->Put(document2));
}
@@ -4524,11 +4531,16 @@
}
TEST_F(IcingSearchEngineTest, InitializeShouldLogFunctionLatency) {
- IcingSearchEngine icing(GetDefaultIcingOptions(), GetTestJniCache());
+ auto fake_clock = std::make_unique<FakeClock>();
+ fake_clock->SetTimerElapsedMilliseconds(10);
+ TestIcingSearchEngine icing(GetDefaultIcingOptions(),
+ std::make_unique<Filesystem>(),
+ std::make_unique<IcingFilesystem>(),
+ std::move(fake_clock), GetTestJniCache());
InitializeResultProto initialize_result_proto = icing.Initialize();
EXPECT_THAT(initialize_result_proto.status(), ProtoIsOk());
EXPECT_THAT(initialize_result_proto.native_initialize_stats().latency_ms(),
- Gt(0));
+ Eq(10));
}
TEST_F(IcingSearchEngineTest, InitializeShouldLogNumberOfDocuments) {
@@ -4580,7 +4592,14 @@
TEST_F(IcingSearchEngineTest,
InitializeShouldNotLogRecoveryCauseForFirstTimeInitialize) {
- IcingSearchEngine icing(GetDefaultIcingOptions(), GetTestJniCache());
+ // Even though the fake timer will return 10, all the latency numbers related
+ // to recovery / restoration should be 0 during the first-time initialization.
+ auto fake_clock = std::make_unique<FakeClock>();
+ fake_clock->SetTimerElapsedMilliseconds(10);
+ TestIcingSearchEngine icing(GetDefaultIcingOptions(),
+ std::make_unique<Filesystem>(),
+ std::make_unique<IcingFilesystem>(),
+ std::move(fake_clock), GetTestJniCache());
InitializeResultProto initialize_result_proto = icing.Initialize();
EXPECT_THAT(initialize_result_proto.status(), ProtoIsOk());
EXPECT_THAT(initialize_result_proto.native_initialize_stats()
@@ -4637,7 +4656,12 @@
{
// Document store will rewind to previous checkpoint. The cause should be
// DATA_LOSS and the data status should be PARTIAL_LOSS.
- IcingSearchEngine icing(GetDefaultIcingOptions(), GetTestJniCache());
+ auto fake_clock = std::make_unique<FakeClock>();
+ fake_clock->SetTimerElapsedMilliseconds(10);
+ TestIcingSearchEngine icing(GetDefaultIcingOptions(),
+ std::make_unique<Filesystem>(),
+ std::make_unique<IcingFilesystem>(),
+ std::move(fake_clock), GetTestJniCache());
InitializeResultProto initialize_result_proto = icing.Initialize();
EXPECT_THAT(initialize_result_proto.status(), ProtoIsOk());
EXPECT_THAT(initialize_result_proto.native_initialize_stats()
@@ -4645,7 +4669,7 @@
Eq(NativeInitializeStats::DATA_LOSS));
EXPECT_THAT(initialize_result_proto.native_initialize_stats()
.document_store_recovery_latency_ms(),
- Gt(0));
+ Eq(10));
EXPECT_THAT(initialize_result_proto.native_initialize_stats()
.document_store_data_status(),
Eq(NativeInitializeStats::PARTIAL_LOSS));
@@ -4669,21 +4693,14 @@
DocumentProto document1 = DocumentBuilder()
.SetKey("icing", "fake_type/1")
.SetSchema("Message")
- .AddStringProperty("body", kIpsumText)
+ .AddStringProperty("body", "message body")
.Build();
- DocumentProto document2 = DocumentBuilder()
- .SetKey("icing", "fake_type/2")
- .SetSchema("Message")
- .AddStringProperty("body", kIpsumText)
- .Build();
-
{
// Initialize and put a document.
IcingSearchEngine icing(GetDefaultIcingOptions(), GetTestJniCache());
ASSERT_THAT(icing.Initialize().status(), ProtoIsOk());
ASSERT_THAT(icing.SetSchema(CreateMessageSchema()).status(), ProtoIsOk());
EXPECT_THAT(icing.Put(document1).status(), ProtoIsOk());
- EXPECT_THAT(icing.Put(document2).status(), ProtoIsOk());
}
{
@@ -4708,7 +4725,12 @@
{
// Document store will completely rewind. The cause should be DATA_LOSS and
// the data status should be COMPLETE_LOSS.
- IcingSearchEngine icing(GetDefaultIcingOptions(), GetTestJniCache());
+ auto fake_clock = std::make_unique<FakeClock>();
+ fake_clock->SetTimerElapsedMilliseconds(10);
+ TestIcingSearchEngine icing(GetDefaultIcingOptions(),
+ std::make_unique<Filesystem>(),
+ std::make_unique<IcingFilesystem>(),
+ std::move(fake_clock), GetTestJniCache());
InitializeResultProto initialize_result_proto = icing.Initialize();
EXPECT_THAT(initialize_result_proto.status(), ProtoIsOk());
EXPECT_THAT(initialize_result_proto.native_initialize_stats()
@@ -4716,7 +4738,7 @@
Eq(NativeInitializeStats::DATA_LOSS));
EXPECT_THAT(initialize_result_proto.native_initialize_stats()
.document_store_recovery_latency_ms(),
- Gt(0));
+ Eq(10));
EXPECT_THAT(initialize_result_proto.native_initialize_stats()
.document_store_data_status(),
Eq(NativeInitializeStats::COMPLETE_LOSS));
@@ -4725,9 +4747,9 @@
EXPECT_THAT(initialize_result_proto.native_initialize_stats()
.index_restoration_cause(),
Eq(NativeInitializeStats::TOTAL_CHECKSUM_MISMATCH));
- // Here we don't check index_restoration_latency_ms because the index
- // restoration is super fast when document store is emtpy. We won't get a
- // latency that is greater than 1 ms.
+ EXPECT_THAT(initialize_result_proto.native_initialize_stats()
+ .index_restoration_latency_ms(),
+ Eq(10));
EXPECT_THAT(initialize_result_proto.native_initialize_stats()
.schema_store_recovery_cause(),
Eq(NativeInitializeStats::NONE));
@@ -4761,7 +4783,12 @@
{
// Index is empty but ground truth is not. Index should be restored due to
// the inconsistency.
- IcingSearchEngine icing(GetDefaultIcingOptions(), GetTestJniCache());
+ auto fake_clock = std::make_unique<FakeClock>();
+ fake_clock->SetTimerElapsedMilliseconds(10);
+ TestIcingSearchEngine icing(GetDefaultIcingOptions(),
+ std::make_unique<Filesystem>(),
+ std::make_unique<IcingFilesystem>(),
+ std::move(fake_clock), GetTestJniCache());
InitializeResultProto initialize_result_proto = icing.Initialize();
EXPECT_THAT(initialize_result_proto.status(), ProtoIsOk());
EXPECT_THAT(initialize_result_proto.native_initialize_stats()
@@ -4769,7 +4796,7 @@
Eq(NativeInitializeStats::INCONSISTENT_WITH_GROUND_TRUTH));
EXPECT_THAT(initialize_result_proto.native_initialize_stats()
.index_restoration_latency_ms(),
- Gt(0));
+ Eq(10));
EXPECT_THAT(initialize_result_proto.native_initialize_stats()
.document_store_recovery_cause(),
Eq(NativeInitializeStats::NONE));
@@ -4790,23 +4817,17 @@
TEST_F(IcingSearchEngineTest,
InitializeShouldLogRecoveryCauseTotalChecksumMismatch) {
+ DocumentProto document = DocumentBuilder()
+ .SetKey("icing", "fake_type/0")
+ .SetSchema("Message")
+ .AddStringProperty("body", "message body")
+ .Build();
{
- // Initialize and index some documents.
+ // Initialize and put one document.
IcingSearchEngine icing(GetDefaultIcingOptions(), GetTestJniCache());
ASSERT_THAT(icing.Initialize().status(), ProtoIsOk());
ASSERT_THAT(icing.SetSchema(CreateMessageSchema()).status(), ProtoIsOk());
-
- // We need to index enough documents to make
- // DocumentStore::UpdateSchemaStore() run longer than 1 ms.
- for (int i = 0; i < 50; ++i) {
- DocumentProto document =
- DocumentBuilder()
- .SetKey("icing", "fake_type/" + std::to_string(i))
- .SetSchema("Message")
- .AddStringProperty("body", "message body")
- .Build();
- ASSERT_THAT(icing.Put(document).status(), ProtoIsOk());
- }
+ ASSERT_THAT(icing.Put(document).status(), ProtoIsOk());
}
{
@@ -4819,7 +4840,12 @@
{
// Both document store and index should be recovered from checksum mismatch.
- IcingSearchEngine icing(GetDefaultIcingOptions(), GetTestJniCache());
+ auto fake_clock = std::make_unique<FakeClock>();
+ fake_clock->SetTimerElapsedMilliseconds(10);
+ TestIcingSearchEngine icing(GetDefaultIcingOptions(),
+ std::make_unique<Filesystem>(),
+ std::make_unique<IcingFilesystem>(),
+ std::move(fake_clock), GetTestJniCache());
InitializeResultProto initialize_result_proto = icing.Initialize();
EXPECT_THAT(initialize_result_proto.status(), ProtoIsOk());
EXPECT_THAT(initialize_result_proto.native_initialize_stats()
@@ -4827,13 +4853,13 @@
Eq(NativeInitializeStats::TOTAL_CHECKSUM_MISMATCH));
EXPECT_THAT(initialize_result_proto.native_initialize_stats()
.index_restoration_latency_ms(),
- Gt(0));
+ Eq(10));
EXPECT_THAT(initialize_result_proto.native_initialize_stats()
.document_store_recovery_cause(),
Eq(NativeInitializeStats::TOTAL_CHECKSUM_MISMATCH));
EXPECT_THAT(initialize_result_proto.native_initialize_stats()
.document_store_recovery_latency_ms(),
- Gt(0));
+ Eq(10));
EXPECT_THAT(initialize_result_proto.native_initialize_stats()
.document_store_data_status(),
Eq(NativeInitializeStats::NO_DATA_LOSS));
@@ -4847,23 +4873,17 @@
}
TEST_F(IcingSearchEngineTest, InitializeShouldLogRecoveryCauseIndexIOError) {
+ DocumentProto document = DocumentBuilder()
+ .SetKey("icing", "fake_type/0")
+ .SetSchema("Message")
+ .AddStringProperty("body", "message body")
+ .Build();
{
- // Initialize and index some documents.
+ // Initialize and put one document.
IcingSearchEngine icing(GetDefaultIcingOptions(), GetTestJniCache());
ASSERT_THAT(icing.Initialize().status(), ProtoIsOk());
ASSERT_THAT(icing.SetSchema(CreateMessageSchema()).status(), ProtoIsOk());
-
- // We need to index enough documents to make RestoreIndexIfNeeded() run
- // longer than 1 ms.
- for (int i = 0; i < 50; ++i) {
- DocumentProto document =
- DocumentBuilder()
- .SetKey("icing", "fake_type/" + std::to_string(i))
- .SetSchema("Message")
- .AddStringProperty("body", "message body")
- .Build();
- ASSERT_THAT(icing.Put(document).status(), ProtoIsOk());
- }
+ ASSERT_THAT(icing.Put(document).status(), ProtoIsOk());
}
// lambda to fail OpenForWrite on lite index hit buffer once.
@@ -4884,10 +4904,12 @@
ON_CALL(*mock_icing_filesystem, OpenForWrite)
.WillByDefault(open_write_lambda);
+ auto fake_clock = std::make_unique<FakeClock>();
+ fake_clock->SetTimerElapsedMilliseconds(10);
TestIcingSearchEngine icing(GetDefaultIcingOptions(),
std::make_unique<Filesystem>(),
std::move(mock_icing_filesystem),
- std::make_unique<FakeClock>(), GetTestJniCache());
+ std::move(fake_clock), GetTestJniCache());
InitializeResultProto initialize_result_proto = icing.Initialize();
EXPECT_THAT(initialize_result_proto.status(), ProtoIsOk());
@@ -4896,7 +4918,7 @@
Eq(NativeInitializeStats::IO_ERROR));
EXPECT_THAT(initialize_result_proto.native_initialize_stats()
.index_restoration_latency_ms(),
- Gt(0));
+ Eq(10));
EXPECT_THAT(initialize_result_proto.native_initialize_stats()
.document_store_recovery_cause(),
Eq(NativeInitializeStats::NONE));
@@ -4915,23 +4937,17 @@
}
TEST_F(IcingSearchEngineTest, InitializeShouldLogRecoveryCauseDocStoreIOError) {
+ DocumentProto document = DocumentBuilder()
+ .SetKey("icing", "fake_type/0")
+ .SetSchema("Message")
+ .AddStringProperty("body", "message body")
+ .Build();
{
- // Initialize and index some documents.
+ // Initialize and put one document.
IcingSearchEngine icing(GetDefaultIcingOptions(), GetTestJniCache());
ASSERT_THAT(icing.Initialize().status(), ProtoIsOk());
ASSERT_THAT(icing.SetSchema(CreateMessageSchema()).status(), ProtoIsOk());
-
- // We need to index enough documents to make RestoreIndexIfNeeded() run
- // longer than 1 ms.
- for (int i = 0; i < 50; ++i) {
- DocumentProto document =
- DocumentBuilder()
- .SetKey("icing", "fake_type/" + std::to_string(i))
- .SetSchema("Message")
- .AddStringProperty("body", "message body")
- .Build();
- ASSERT_THAT(icing.Put(document).status(), ProtoIsOk());
- }
+ ASSERT_THAT(icing.Put(document).status(), ProtoIsOk());
}
// lambda to fail Read on document store header once.
@@ -4954,10 +4970,12 @@
ON_CALL(*mock_filesystem, Read(A<const char*>(), _, _))
.WillByDefault(read_lambda);
+ auto fake_clock = std::make_unique<FakeClock>();
+ fake_clock->SetTimerElapsedMilliseconds(10);
TestIcingSearchEngine icing(GetDefaultIcingOptions(),
std::move(mock_filesystem),
std::make_unique<IcingFilesystem>(),
- std::make_unique<FakeClock>(), GetTestJniCache());
+ std::move(fake_clock), GetTestJniCache());
InitializeResultProto initialize_result_proto = icing.Initialize();
EXPECT_THAT(initialize_result_proto.status(), ProtoIsOk());
@@ -4966,7 +4984,7 @@
Eq(NativeInitializeStats::IO_ERROR));
EXPECT_THAT(initialize_result_proto.native_initialize_stats()
.document_store_recovery_latency_ms(),
- Gt(0));
+ Eq(10));
EXPECT_THAT(initialize_result_proto.native_initialize_stats()
.document_store_data_status(),
Eq(NativeInitializeStats::NO_DATA_LOSS));
@@ -5000,7 +5018,12 @@
}
{
- IcingSearchEngine icing(GetDefaultIcingOptions(), GetTestJniCache());
+ auto fake_clock = std::make_unique<FakeClock>();
+ fake_clock->SetTimerElapsedMilliseconds(10);
+ TestIcingSearchEngine icing(GetDefaultIcingOptions(),
+ std::make_unique<Filesystem>(),
+ std::make_unique<IcingFilesystem>(),
+ std::move(fake_clock), GetTestJniCache());
InitializeResultProto initialize_result_proto = icing.Initialize();
EXPECT_THAT(initialize_result_proto.status(), ProtoIsOk());
EXPECT_THAT(initialize_result_proto.native_initialize_stats()
@@ -5008,7 +5031,7 @@
Eq(NativeInitializeStats::IO_ERROR));
EXPECT_THAT(initialize_result_proto.native_initialize_stats()
.schema_store_recovery_latency_ms(),
- Gt(0));
+ Eq(10));
EXPECT_THAT(initialize_result_proto.native_initialize_stats()
.document_store_recovery_cause(),
Eq(NativeInitializeStats::NONE));
@@ -5085,28 +5108,34 @@
.AddStringProperty("body", "message body")
.Build();
- IcingSearchEngine icing(GetDefaultIcingOptions(), GetTestJniCache());
+ auto fake_clock = std::make_unique<FakeClock>();
+ fake_clock->SetTimerElapsedMilliseconds(10);
+ TestIcingSearchEngine icing(GetDefaultIcingOptions(),
+ std::make_unique<Filesystem>(),
+ std::make_unique<IcingFilesystem>(),
+ std::move(fake_clock), GetTestJniCache());
ASSERT_THAT(icing.Initialize().status(), ProtoIsOk());
ASSERT_THAT(icing.SetSchema(CreateMessageSchema()).status(), ProtoIsOk());
PutResultProto put_result_proto = icing.Put(document);
EXPECT_THAT(put_result_proto.status(), ProtoIsOk());
- EXPECT_THAT(put_result_proto.native_put_document_stats().latency_ms(), Gt(0));
+ EXPECT_THAT(put_result_proto.native_put_document_stats().latency_ms(),
+ Eq(10));
}
TEST_F(IcingSearchEngineTest, PutDocumentShouldLogDocumentStoreStats) {
- // Create a large enough document so that document_store_latency_ms can be
- // longer than 1 ms.
- std::default_random_engine random;
- std::string random_string_10000 =
- RandomString(kAlNumAlphabet, /*len=*/10000, &random);
DocumentProto document = DocumentBuilder()
.SetKey("icing", "fake_type/0")
.SetSchema("Message")
- .AddStringProperty("body", random_string_10000)
+ .AddStringProperty("body", "message body")
.Build();
- IcingSearchEngine icing(GetDefaultIcingOptions(), GetTestJniCache());
+ auto fake_clock = std::make_unique<FakeClock>();
+ fake_clock->SetTimerElapsedMilliseconds(10);
+ TestIcingSearchEngine icing(GetDefaultIcingOptions(),
+ std::make_unique<Filesystem>(),
+ std::make_unique<IcingFilesystem>(),
+ std::move(fake_clock), GetTestJniCache());
ASSERT_THAT(icing.Initialize().status(), ProtoIsOk());
ASSERT_THAT(icing.SetSchema(CreateMessageSchema()).status(), ProtoIsOk());
@@ -5114,28 +5143,31 @@
EXPECT_THAT(put_result_proto.status(), ProtoIsOk());
EXPECT_THAT(
put_result_proto.native_put_document_stats().document_store_latency_ms(),
- Gt(0));
+ Eq(10));
EXPECT_THAT(put_result_proto.native_put_document_stats().document_size(),
Eq(document.ByteSizeLong()));
}
TEST_F(IcingSearchEngineTest, PutDocumentShouldLogIndexingStats) {
- // Create a large enough document so that index_latency_ms can be longer than
- // 1 ms.
DocumentProto document = DocumentBuilder()
.SetKey("icing", "fake_type/0")
.SetSchema("Message")
- .AddStringProperty("body", kIpsumText)
+ .AddStringProperty("body", "message body")
.Build();
- IcingSearchEngine icing(GetDefaultIcingOptions(), GetTestJniCache());
+ auto fake_clock = std::make_unique<FakeClock>();
+ fake_clock->SetTimerElapsedMilliseconds(10);
+ TestIcingSearchEngine icing(GetDefaultIcingOptions(),
+ std::make_unique<Filesystem>(),
+ std::make_unique<IcingFilesystem>(),
+ std::move(fake_clock), GetTestJniCache());
ASSERT_THAT(icing.Initialize().status(), ProtoIsOk());
ASSERT_THAT(icing.SetSchema(CreateMessageSchema()).status(), ProtoIsOk());
PutResultProto put_result_proto = icing.Put(document);
EXPECT_THAT(put_result_proto.status(), ProtoIsOk());
EXPECT_THAT(put_result_proto.native_put_document_stats().index_latency_ms(),
- Gt(0));
+ Eq(10));
// No merge should happen.
EXPECT_THAT(
put_result_proto.native_put_document_stats().index_merge_latency_ms(),
@@ -5144,11 +5176,11 @@
EXPECT_FALSE(put_result_proto.native_put_document_stats()
.tokenization_stats()
.exceeded_max_token_num());
- // kIpsumText has 137 tokens.
+ // The input document has 2 tokens.
EXPECT_THAT(put_result_proto.native_put_document_stats()
.tokenization_stats()
.num_tokens_indexed(),
- Eq(137));
+ Eq(2));
}
TEST_F(IcingSearchEngineTest, PutDocumentShouldLogWhetherNumTokensExceeds) {
@@ -5179,8 +5211,6 @@
}
TEST_F(IcingSearchEngineTest, PutDocumentShouldLogIndexMergeLatency) {
- // Create 2 large enough documents so that index_merge_latency_ms can be
- // longer than 1 ms.
DocumentProto document1 = DocumentBuilder()
.SetKey("icing", "fake_type/1")
.SetSchema("Message")
@@ -5195,7 +5225,12 @@
// Create an icing instance with index_merge_size = document1's size.
IcingSearchEngineOptions icing_options = GetDefaultIcingOptions();
icing_options.set_index_merge_size(document1.ByteSizeLong());
- IcingSearchEngine icing(icing_options, GetTestJniCache());
+
+ auto fake_clock = std::make_unique<FakeClock>();
+ fake_clock->SetTimerElapsedMilliseconds(10);
+ TestIcingSearchEngine icing(icing_options, std::make_unique<Filesystem>(),
+ std::make_unique<IcingFilesystem>(),
+ std::move(fake_clock), GetTestJniCache());
ASSERT_THAT(icing.Initialize().status(), ProtoIsOk());
ASSERT_THAT(icing.SetSchema(CreateMessageSchema()).status(), ProtoIsOk());
EXPECT_THAT(icing.Put(document1).status(), ProtoIsOk());
@@ -5205,7 +5240,7 @@
EXPECT_THAT(put_result_proto.status(), ProtoIsOk());
EXPECT_THAT(
put_result_proto.native_put_document_stats().index_merge_latency_ms(),
- Gt(0));
+ Eq(10));
}
} // namespace
diff --git a/icing/index/index-processor.cc b/icing/index/index-processor.cc
index 9e57993..9df9b87 100644
--- a/icing/index/index-processor.cc
+++ b/icing/index/index-processor.cc
@@ -37,7 +37,6 @@
#include "icing/tokenization/tokenizer.h"
#include "icing/transform/normalizer.h"
#include "icing/util/status-macros.h"
-#include "icing/util/timer.h"
namespace icing {
namespace lib {
@@ -46,20 +45,22 @@
IndexProcessor::Create(const SchemaStore* schema_store,
const LanguageSegmenter* lang_segmenter,
const Normalizer* normalizer, Index* index,
- const IndexProcessor::Options& options) {
+ const IndexProcessor::Options& options,
+ const Clock* clock) {
ICING_RETURN_ERROR_IF_NULL(schema_store);
ICING_RETURN_ERROR_IF_NULL(lang_segmenter);
ICING_RETURN_ERROR_IF_NULL(normalizer);
ICING_RETURN_ERROR_IF_NULL(index);
+ ICING_RETURN_ERROR_IF_NULL(clock);
return std::unique_ptr<IndexProcessor>(new IndexProcessor(
- schema_store, lang_segmenter, normalizer, index, options));
+ schema_store, lang_segmenter, normalizer, index, options, clock));
}
libtextclassifier3::Status IndexProcessor::IndexDocument(
const DocumentProto& document, DocumentId document_id,
NativePutDocumentStats* put_document_stats) {
- Timer index_timer;
+ std::unique_ptr<Timer> index_timer = clock_.GetNewTimer();
if (index_->last_added_document_id() != kInvalidDocumentId &&
document_id <= index_->last_added_document_id()) {
@@ -118,7 +119,7 @@
if (put_document_stats != nullptr) {
put_document_stats->set_index_latency_ms(
- index_timer.GetElapsedMilliseconds());
+ index_timer->GetElapsedMilliseconds());
put_document_stats->mutable_tokenization_stats()->set_num_tokens_indexed(
num_tokens);
}
@@ -127,7 +128,7 @@
if (overall_status.ok() && index_->WantsMerge()) {
ICING_VLOG(1) << "Merging the index at docid " << document_id << ".";
- Timer merge_timer;
+ std::unique_ptr<Timer> merge_timer = clock_.GetNewTimer();
libtextclassifier3::Status merge_status = index_->Merge();
if (!merge_status.ok()) {
@@ -146,7 +147,7 @@
if (put_document_stats != nullptr) {
put_document_stats->set_index_merge_latency_ms(
- merge_timer.GetElapsedMilliseconds());
+ merge_timer->GetElapsedMilliseconds());
}
}
diff --git a/icing/index/index-processor.h b/icing/index/index-processor.h
index 91719d0..2eb4ad8 100644
--- a/icing/index/index-processor.h
+++ b/icing/index/index-processor.h
@@ -59,7 +59,8 @@
// FAILED_PRECONDITION if any of the pointers is null.
static libtextclassifier3::StatusOr<std::unique_ptr<IndexProcessor>> Create(
const SchemaStore* schema_store, const LanguageSegmenter* lang_segmenter,
- const Normalizer* normalizer, Index* index, const Options& options);
+ const Normalizer* normalizer, Index* index, const Options& options,
+ const Clock* clock);
// Add document to the index, associated with document_id. If the number of
// tokens in the document exceeds max_tokens_per_document, then only the first
@@ -88,12 +89,13 @@
IndexProcessor(const SchemaStore* schema_store,
const LanguageSegmenter* lang_segmenter,
const Normalizer* normalizer, Index* index,
- const Options& options)
+ const Options& options, const Clock* clock)
: schema_store_(*schema_store),
lang_segmenter_(*lang_segmenter),
normalizer_(*normalizer),
index_(index),
- options_(options) {}
+ options_(options),
+ clock_(*clock) {}
std::string NormalizeToken(const Token& token);
@@ -102,6 +104,7 @@
const Normalizer& normalizer_;
Index* const index_;
const Options options_;
+ const Clock& clock_;
};
} // namespace lib
diff --git a/icing/index/index-processor_benchmark.cc b/icing/index/index-processor_benchmark.cc
index 584cb9b..96a390b 100644
--- a/icing/index/index-processor_benchmark.cc
+++ b/icing/index/index-processor_benchmark.cc
@@ -147,10 +147,10 @@
.ValueOrDie();
}
-std::unique_ptr<SchemaStore> CreateSchemaStore() {
+std::unique_ptr<SchemaStore> CreateSchemaStore(const Clock* clock) {
Filesystem filesystem;
std::unique_ptr<SchemaStore> schema_store =
- SchemaStore::Create(&filesystem, GetTestTempDir()).ValueOrDie();
+ SchemaStore::Create(&filesystem, GetTestTempDir(), clock).ValueOrDie();
SchemaProto schema;
CreateFakeTypeConfig(schema.add_types());
@@ -170,14 +170,14 @@
std::unique_ptr<IndexProcessor> CreateIndexProcessor(
const SchemaStore* schema_store,
const LanguageSegmenter* language_segmenter, const Normalizer* normalizer,
- Index* index) {
+ Index* index, const Clock* clock) {
IndexProcessor::Options processor_options{};
processor_options.max_tokens_per_document = 1024 * 1024 * 10;
processor_options.token_limit_behavior =
IndexProcessor::Options::TokenLimitBehavior::kReturnError;
return IndexProcessor::Create(schema_store, language_segmenter, normalizer,
- index, processor_options)
+ index, processor_options, clock)
.ValueOrDie();
}
@@ -200,10 +200,11 @@
std::unique_ptr<LanguageSegmenter> language_segmenter =
language_segmenter_factory::Create(std::move(options)).ValueOrDie();
std::unique_ptr<Normalizer> normalizer = CreateNormalizer();
- std::unique_ptr<SchemaStore> schema_store = CreateSchemaStore();
+ Clock clock;
+ std::unique_ptr<SchemaStore> schema_store = CreateSchemaStore(&clock);
std::unique_ptr<IndexProcessor> index_processor =
CreateIndexProcessor(schema_store.get(), language_segmenter.get(),
- normalizer.get(), index.get());
+ normalizer.get(), index.get(), &clock);
DocumentProto input_document = CreateDocumentWithOneProperty(state.range(0));
@@ -250,10 +251,11 @@
std::unique_ptr<LanguageSegmenter> language_segmenter =
language_segmenter_factory::Create(std::move(options)).ValueOrDie();
std::unique_ptr<Normalizer> normalizer = CreateNormalizer();
- std::unique_ptr<SchemaStore> schema_store = CreateSchemaStore();
+ Clock clock;
+ std::unique_ptr<SchemaStore> schema_store = CreateSchemaStore(&clock);
std::unique_ptr<IndexProcessor> index_processor =
CreateIndexProcessor(schema_store.get(), language_segmenter.get(),
- normalizer.get(), index.get());
+ normalizer.get(), index.get(), &clock);
DocumentProto input_document =
CreateDocumentWithTenProperties(state.range(0));
@@ -301,10 +303,11 @@
std::unique_ptr<LanguageSegmenter> language_segmenter =
language_segmenter_factory::Create(std::move(options)).ValueOrDie();
std::unique_ptr<Normalizer> normalizer = CreateNormalizer();
- std::unique_ptr<SchemaStore> schema_store = CreateSchemaStore();
+ Clock clock;
+ std::unique_ptr<SchemaStore> schema_store = CreateSchemaStore(&clock);
std::unique_ptr<IndexProcessor> index_processor =
CreateIndexProcessor(schema_store.get(), language_segmenter.get(),
- normalizer.get(), index.get());
+ normalizer.get(), index.get(), &clock);
DocumentProto input_document =
CreateDocumentWithDiacriticLetters(state.range(0));
@@ -352,10 +355,11 @@
std::unique_ptr<LanguageSegmenter> language_segmenter =
language_segmenter_factory::Create(std::move(options)).ValueOrDie();
std::unique_ptr<Normalizer> normalizer = CreateNormalizer();
- std::unique_ptr<SchemaStore> schema_store = CreateSchemaStore();
+ Clock clock;
+ std::unique_ptr<SchemaStore> schema_store = CreateSchemaStore(&clock);
std::unique_ptr<IndexProcessor> index_processor =
CreateIndexProcessor(schema_store.get(), language_segmenter.get(),
- normalizer.get(), index.get());
+ normalizer.get(), index.get(), &clock);
DocumentProto input_document = CreateDocumentWithHiragana(state.range(0));
diff --git a/icing/index/index-processor_test.cc b/icing/index/index-processor_test.cc
index e193842..ff11e60 100644
--- a/icing/index/index-processor_test.cc
+++ b/icing/index/index-processor_test.cc
@@ -44,6 +44,8 @@
#include "icing/schema/section.h"
#include "icing/store/document-id.h"
#include "icing/testing/common-matchers.h"
+#include "icing/testing/fake-clock.h"
+#include "icing/testing/platform.h"
#include "icing/testing/test-data.h"
#include "icing/testing/tmp-directory.h"
#include "icing/tokenization/language-segmenter-factory.h"
@@ -102,10 +104,12 @@
class IndexProcessorTest : public Test {
protected:
void SetUp() override {
- ICING_ASSERT_OK(
- // File generated via icu_data_file rule in //icing/BUILD.
- icu_data_file_helper::SetUpICUDataFile(
- GetTestFilePath("icing/icu.dat")));
+ if (!IsCfStringTokenization() && !IsReverseJniTokenization()) {
+ ICING_ASSERT_OK(
+ // File generated via icu_data_file rule in //icing/BUILD.
+ icu_data_file_helper::SetUpICUDataFile(
+ GetTestFilePath("icing/icu.dat")));
+ }
index_dir_ = GetTestTempDir() + "/index_test";
Index::Options options(index_dir_, /*index_merge_size=*/1024 * 1024);
@@ -120,11 +124,11 @@
ICING_ASSERT_OK_AND_ASSIGN(
normalizer_,
normalizer_factory::Create(
-
/*max_term_byte_size=*/std::numeric_limits<int32_t>::max()));
ICING_ASSERT_OK_AND_ASSIGN(
- schema_store_, SchemaStore::Create(&filesystem_, GetTestTempDir()));
+ schema_store_,
+ SchemaStore::Create(&filesystem_, GetTestTempDir(), &fake_clock_));
SchemaProto schema = CreateFakeSchema();
ICING_ASSERT_OK(schema_store_->SetSchema(schema));
@@ -137,7 +141,7 @@
index_processor_,
IndexProcessor::Create(schema_store_.get(), lang_segmenter_.get(),
normalizer_.get(), index_.get(),
- processor_options));
+ processor_options, &fake_clock_));
mock_icing_filesystem_ = std::make_unique<IcingMockFilesystem>();
}
@@ -149,6 +153,7 @@
Filesystem filesystem_;
IcingFilesystem icing_filesystem_;
+ FakeClock fake_clock_;
std::string index_dir_;
std::unique_ptr<LanguageSegmenter> lang_segmenter_;
@@ -238,24 +243,26 @@
processor_options.token_limit_behavior =
IndexProcessor::Options::TokenLimitBehavior::kReturnError;
- EXPECT_THAT(IndexProcessor::Create(/*schema_store=*/nullptr,
- lang_segmenter_.get(), normalizer_.get(),
- index_.get(), processor_options),
- StatusIs(libtextclassifier3::StatusCode::FAILED_PRECONDITION));
+ EXPECT_THAT(
+ IndexProcessor::Create(/*schema_store=*/nullptr, lang_segmenter_.get(),
+ normalizer_.get(), index_.get(), processor_options,
+ &fake_clock_),
+ StatusIs(libtextclassifier3::StatusCode::FAILED_PRECONDITION));
- EXPECT_THAT(IndexProcessor::Create(
- schema_store_.get(), /*lang_segmenter=*/nullptr,
- normalizer_.get(), index_.get(), processor_options),
- StatusIs(libtextclassifier3::StatusCode::FAILED_PRECONDITION));
+ EXPECT_THAT(
+ IndexProcessor::Create(schema_store_.get(), /*lang_segmenter=*/nullptr,
+ normalizer_.get(), index_.get(), processor_options,
+ &fake_clock_),
+ StatusIs(libtextclassifier3::StatusCode::FAILED_PRECONDITION));
EXPECT_THAT(IndexProcessor::Create(schema_store_.get(), lang_segmenter_.get(),
/*normalizer=*/nullptr, index_.get(),
- processor_options),
+ processor_options, &fake_clock_),
StatusIs(libtextclassifier3::StatusCode::FAILED_PRECONDITION));
EXPECT_THAT(IndexProcessor::Create(schema_store_.get(), lang_segmenter_.get(),
normalizer_.get(), /*index=*/nullptr,
- processor_options),
+ processor_options, &fake_clock_),
StatusIs(libtextclassifier3::StatusCode::FAILED_PRECONDITION));
}
@@ -389,7 +396,8 @@
ICING_ASSERT_OK_AND_ASSIGN(
index_processor_,
IndexProcessor::Create(schema_store_.get(), lang_segmenter_.get(),
- normalizer_.get(), index_.get(), options));
+ normalizer_.get(), index_.get(), options,
+ &fake_clock_));
DocumentProto document =
DocumentBuilder()
@@ -428,7 +436,8 @@
ICING_ASSERT_OK_AND_ASSIGN(
index_processor_,
IndexProcessor::Create(schema_store_.get(), lang_segmenter_.get(),
- normalizer_.get(), index_.get(), options));
+ normalizer_.get(), index_.get(), options,
+ &fake_clock_));
DocumentProto document =
DocumentBuilder()
@@ -468,7 +477,8 @@
ICING_ASSERT_OK_AND_ASSIGN(
index_processor_,
IndexProcessor::Create(schema_store_.get(), lang_segmenter_.get(),
- normalizer.get(), index_.get(), options));
+ normalizer.get(), index_.get(), options,
+ &fake_clock_));
DocumentProto document =
DocumentBuilder()
@@ -590,6 +600,23 @@
}
TEST_F(IndexProcessorTest, NonAsciiIndexing) {
+ language_segmenter_factory::SegmenterOptions segmenter_options(
+ ULOC_SIMPLIFIED_CHINESE);
+ ICING_ASSERT_OK_AND_ASSIGN(
+ lang_segmenter_,
+ language_segmenter_factory::Create(std::move(segmenter_options)));
+
+ IndexProcessor::Options processor_options;
+ processor_options.max_tokens_per_document = 1000;
+ processor_options.token_limit_behavior =
+ IndexProcessor::Options::TokenLimitBehavior::kReturnError;
+
+ ICING_ASSERT_OK_AND_ASSIGN(
+ index_processor_,
+ IndexProcessor::Create(schema_store_.get(), lang_segmenter_.get(),
+ normalizer_.get(), index_.get(),
+ processor_options, &fake_clock_));
+
DocumentProto document =
DocumentBuilder()
.SetKey("icing", "fake_type/1")
@@ -618,8 +645,8 @@
ICING_ASSERT_OK_AND_ASSIGN(
index_processor_,
IndexProcessor::Create(schema_store_.get(), lang_segmenter_.get(),
- normalizer_.get(), index_.get(),
- processor_options));
+ normalizer_.get(), index_.get(), processor_options,
+ &fake_clock_));
// This is the maximum token length that an empty lexicon constructed for a
// lite index with merge size of 1MiB can support.
@@ -679,8 +706,8 @@
ICING_ASSERT_OK_AND_ASSIGN(
index_processor_,
IndexProcessor::Create(schema_store_.get(), lang_segmenter_.get(),
- normalizer_.get(), index_.get(),
- processor_options));
+ normalizer_.get(), index_.get(), processor_options,
+ &fake_clock_));
DocumentId doc_id = 0;
// Have determined experimentally that indexing 3373 documents with this text
// will cause the LiteIndex to fill up. Further indexing will fail unless the
@@ -736,8 +763,8 @@
ICING_ASSERT_OK_AND_ASSIGN(
index_processor_,
IndexProcessor::Create(schema_store_.get(), lang_segmenter_.get(),
- normalizer_.get(), index_.get(),
- processor_options));
+ normalizer_.get(), index_.get(), processor_options,
+ &fake_clock_));
// 3. Index one document. This should fit in the LiteIndex without requiring a
// merge.
diff --git a/icing/index/index.cc b/icing/index/index.cc
index 1fb0dc0..1b808f8 100644
--- a/icing/index/index.cc
+++ b/icing/index/index.cc
@@ -71,7 +71,7 @@
}
// Helper function to check if a term is in the given namespaces.
-// TODO(samzheng): Implement a method PropertyReadersAll.HasAnyProperty().
+// TODO(tjbarron): Implement a method PropertyReadersAll.HasAnyProperty().
bool IsTermInNamespaces(
const IcingDynamicTrie::PropertyReadersAll& property_reader,
uint32_t value_index, const std::vector<NamespaceId>& namespace_ids) {
diff --git a/icing/index/iterator/doc-hit-info-iterator-and.cc b/icing/index/iterator/doc-hit-info-iterator-and.cc
index f224583..66f87bd 100644
--- a/icing/index/iterator/doc-hit-info-iterator-and.cc
+++ b/icing/index/iterator/doc-hit-info-iterator-and.cc
@@ -38,8 +38,6 @@
// When combining ANDed iterators, n-ary operator has better performance when
// number of operands > 3 according to benchmark cl/243720660
-// TODO (samzheng): Tune this number when it's necessary, e.g. implementation
-// changes.
inline constexpr int kBinaryAndIteratorPerformanceThreshold = 3;
// The minimum number of iterators needed to construct a And iterator. The And
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 9eb147a..e0a8cd0 100644
--- a/icing/index/iterator/doc-hit-info-iterator-filter_test.cc
+++ b/icing/index/iterator/doc-hit-info-iterator-filter_test.cc
@@ -63,14 +63,16 @@
auto type_config = schema.add_types();
type_config->set_schema_type("email");
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ICING_ASSERT_OK(schema_store_->SetSchema(schema));
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, test_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
}
void TearDown() override {
@@ -228,14 +230,16 @@
auto type_config = schema.add_types();
type_config->set_schema_type("email");
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ICING_ASSERT_OK(schema_store_->SetSchema(schema));
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, test_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
}
void TearDown() override {
@@ -383,14 +387,16 @@
type_config = schema.add_types();
type_config->set_schema_type(schema3_);
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ICING_ASSERT_OK(schema_store_->SetSchema(schema));
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, test_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
}
void TearDown() override {
@@ -521,14 +527,16 @@
auto type_config = schema.add_types();
type_config->set_schema_type(email_schema_);
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ICING_ASSERT_OK(schema_store_->SetSchema(schema));
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, test_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
}
void TearDown() override {
@@ -711,14 +719,16 @@
type_config = schema.add_types();
type_config->set_schema_type(schema2_);
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ICING_ASSERT_OK(schema_store_->SetSchema(schema));
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, test_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
}
void TearDown() override {
diff --git a/icing/index/iterator/doc-hit-info-iterator-or.cc b/icing/index/iterator/doc-hit-info-iterator-or.cc
index 9d18753..8f00f88 100644
--- a/icing/index/iterator/doc-hit-info-iterator-or.cc
+++ b/icing/index/iterator/doc-hit-info-iterator-or.cc
@@ -29,8 +29,6 @@
// When combining Or iterators, n-ary operator has better performance when
// number of operands > 2 according to benchmark cl/243321264
-// TODO (samzheng): Tune this number when it's necessary, e.g. implementation
-// changes.
constexpr int kBinaryOrIteratorPerformanceThreshold = 2;
} // namespace
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 b29217c..91e0cbe 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
@@ -72,14 +72,16 @@
// First and only indexed property, so it gets the first id of 0
indexed_section_id_ = 0;
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ICING_ASSERT_OK(schema_store_->SetSchema(schema_));
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, test_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
}
void TearDown() override {
diff --git a/icing/index/main/main-index.cc b/icing/index/main/main-index.cc
index 2a5ba83..ff1c47a 100644
--- a/icing/index/main/main-index.cc
+++ b/icing/index/main/main-index.cc
@@ -173,11 +173,12 @@
ICING_ASSIGN_OR_RETURN(PostingListAccessor pl_accessor,
PostingListAccessor::CreateFromExisting(
flash_index_storage_.get(), posting_list_id));
- GetPrefixAccessorResult result = {std::make_unique<PostingListAccessor>(std::move(pl_accessor)), exact};
+ GetPrefixAccessorResult result = {
+ std::make_unique<PostingListAccessor>(std::move(pl_accessor)), exact};
return result;
}
-// TODO(samzheng): Implement a method PropertyReadersAll.HasAnyProperty().
+// TODO(tjbarron): Implement a method PropertyReadersAll.HasAnyProperty().
bool IsTermInNamespaces(
const IcingDynamicTrie::PropertyReadersAll& property_reader,
uint32_t value_index, const std::vector<NamespaceId>& namespace_ids) {
diff --git a/icing/jni/icing-search-engine-jni.cc b/icing/jni/icing-search-engine-jni.cc
index 71752dd..1e20340 100644
--- a/icing/jni/icing-search-engine-jni.cc
+++ b/icing/jni/icing-search-engine-jni.cc
@@ -27,6 +27,7 @@
#include "icing/proto/schema.pb.h"
#include "icing/proto/scoring.pb.h"
#include "icing/proto/search.pb.h"
+#include "icing/proto/usage.pb.h"
#include "icing/util/status-macros.h"
namespace {
@@ -96,6 +97,14 @@
return reinterpret_cast<jlong>(icing);
}
+JNIEXPORT void JNICALL
+Java_com_google_android_icing_IcingSearchEngine_nativeDestroy(
+ JNIEnv* env, jclass clazz, jlong native_pointer) {
+ icing::lib::IcingSearchEngine* icing =
+ GetIcingSearchEnginePointer(native_pointer);
+ delete icing;
+}
+
JNIEXPORT jbyteArray JNICALL
Java_com_google_android_icing_IcingSearchEngine_nativeInitialize(
JNIEnv* env, jclass clazz, jlong native_pointer) {
@@ -188,6 +197,25 @@
}
JNIEXPORT jbyteArray JNICALL
+Java_com_google_android_icing_IcingSearchEngine_nativeReportUsage(
+ JNIEnv* env, jclass clazz, jlong native_pointer,
+ jbyteArray usage_report_bytes) {
+ icing::lib::IcingSearchEngine* icing =
+ GetIcingSearchEnginePointer(native_pointer);
+
+ icing::lib::UsageReport usage_report;
+ if (!ParseProtoFromJniByteArray(env, usage_report_bytes, &usage_report)) {
+ ICING_LOG(ERROR) << "Failed to parse UsageReport in nativeReportUsage";
+ return nullptr;
+ }
+
+ icing::lib::ReportUsageResultProto report_usage_result_proto =
+ icing->ReportUsage(usage_report);
+
+ return SerializeProtoToJniByteArray(env, report_usage_result_proto);
+}
+
+JNIEXPORT jbyteArray JNICALL
Java_com_google_android_icing_IcingSearchEngine_nativeGetAllNamespaces(
JNIEnv* env, jclass clazz, jlong native_pointer) {
icing::lib::IcingSearchEngine* icing =
@@ -201,8 +229,7 @@
JNIEXPORT jbyteArray JNICALL
Java_com_google_android_icing_IcingSearchEngine_nativeGetNextPage(
- JNIEnv* env, jclass clazz, jlong native_pointer,
- jlong next_page_token) {
+ JNIEnv* env, jclass clazz, jlong native_pointer, jlong next_page_token) {
icing::lib::IcingSearchEngine* icing =
GetIcingSearchEnginePointer(native_pointer);
@@ -214,8 +241,7 @@
JNIEXPORT void JNICALL
Java_com_google_android_icing_IcingSearchEngine_nativeInvalidateNextPageToken(
- JNIEnv* env, jclass clazz, jlong native_pointer,
- jlong next_page_token) {
+ JNIEnv* env, jclass clazz, jlong native_pointer, jlong next_page_token) {
icing::lib::IcingSearchEngine* icing =
GetIcingSearchEnginePointer(native_pointer);
diff --git a/icing/query/query-processor_benchmark.cc b/icing/query/query-processor_benchmark.cc
index 900cce5..9dc5c07 100644
--- a/icing/query/query-processor_benchmark.cc
+++ b/icing/query/query-processor_benchmark.cc
@@ -24,11 +24,11 @@
#include "icing/schema/section.h"
#include "icing/store/document-id.h"
#include "icing/testing/common-matchers.h"
-#include "icing/testing/fake-clock.h"
#include "icing/testing/test-data.h"
#include "icing/testing/tmp-directory.h"
#include "icing/tokenization/language-segmenter-factory.h"
#include "icing/transform/normalizer-factory.h"
+#include "icing/util/clock.h"
#include "icing/util/logging.h"
#include "unicode/uloc.h"
@@ -114,19 +114,22 @@
std::unique_ptr<LanguageSegmenter> language_segmenter =
language_segmenter_factory::Create(std::move(options)).ValueOrDie();
std::unique_ptr<Normalizer> normalizer = CreateNormalizer();
- FakeClock fake_clock;
SchemaProto schema;
auto type_config = schema.add_types();
type_config->set_schema_type("type1");
- ICING_ASSERT_OK_AND_ASSIGN(std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem, schema_dir));
+ Clock clock;
+ ICING_ASSERT_OK_AND_ASSIGN(
+ std::unique_ptr<SchemaStore> schema_store,
+ SchemaStore::Create(&filesystem, schema_dir, &clock));
ICING_ASSERT_OK(schema_store->SetSchema(schema));
- std::unique_ptr<DocumentStore> document_store =
- DocumentStore::Create(&filesystem, doc_store_dir, &fake_clock,
+ DocumentStore::CreateResult create_result =
+ DocumentStore::Create(&filesystem, doc_store_dir, &clock,
schema_store.get())
.ValueOrDie();
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
DocumentId document_id = document_store
->Put(DocumentBuilder()
@@ -143,7 +146,7 @@
std::unique_ptr<QueryProcessor> query_processor,
QueryProcessor::Create(index.get(), language_segmenter.get(),
normalizer.get(), document_store.get(),
- schema_store.get(), &fake_clock));
+ schema_store.get(), &clock));
SearchSpecProto search_spec;
search_spec.set_query(input_string);
@@ -228,19 +231,22 @@
std::unique_ptr<LanguageSegmenter> language_segmenter =
language_segmenter_factory::Create(std::move(options)).ValueOrDie();
std::unique_ptr<Normalizer> normalizer = CreateNormalizer();
- FakeClock fake_clock;
SchemaProto schema;
auto type_config = schema.add_types();
type_config->set_schema_type("type1");
- ICING_ASSERT_OK_AND_ASSIGN(std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem, schema_dir));
+ Clock clock;
+ ICING_ASSERT_OK_AND_ASSIGN(
+ std::unique_ptr<SchemaStore> schema_store,
+ SchemaStore::Create(&filesystem, schema_dir, &clock));
ICING_ASSERT_OK(schema_store->SetSchema(schema));
- std::unique_ptr<DocumentStore> document_store =
- DocumentStore::Create(&filesystem, doc_store_dir, &fake_clock,
+ DocumentStore::CreateResult create_result =
+ DocumentStore::Create(&filesystem, doc_store_dir, &clock,
schema_store.get())
.ValueOrDie();
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
DocumentId document_id = document_store
->Put(DocumentBuilder()
@@ -271,7 +277,7 @@
std::unique_ptr<QueryProcessor> query_processor,
QueryProcessor::Create(index.get(), language_segmenter.get(),
normalizer.get(), document_store.get(),
- schema_store.get(), &fake_clock));
+ schema_store.get(), &clock));
const std::string query_string = absl_ports::StrCat(
input_string_a, " ", input_string_b, " ", input_string_c, " ",
@@ -360,19 +366,22 @@
std::unique_ptr<LanguageSegmenter> language_segmenter =
language_segmenter_factory::Create(std::move(options)).ValueOrDie();
std::unique_ptr<Normalizer> normalizer = CreateNormalizer();
- FakeClock fake_clock;
SchemaProto schema;
auto type_config = schema.add_types();
type_config->set_schema_type("type1");
- ICING_ASSERT_OK_AND_ASSIGN(std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem, schema_dir));
+ Clock clock;
+ ICING_ASSERT_OK_AND_ASSIGN(
+ std::unique_ptr<SchemaStore> schema_store,
+ SchemaStore::Create(&filesystem, schema_dir, &clock));
ICING_ASSERT_OK(schema_store->SetSchema(schema));
- std::unique_ptr<DocumentStore> document_store =
- DocumentStore::Create(&filesystem, doc_store_dir, &fake_clock,
+ DocumentStore::CreateResult create_result =
+ DocumentStore::Create(&filesystem, doc_store_dir, &clock,
schema_store.get())
.ValueOrDie();
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
DocumentId document_id = document_store
->Put(DocumentBuilder()
@@ -392,7 +401,7 @@
std::unique_ptr<QueryProcessor> query_processor,
QueryProcessor::Create(index.get(), language_segmenter.get(),
normalizer.get(), document_store.get(),
- schema_store.get(), &fake_clock));
+ schema_store.get(), &clock));
SearchSpecProto search_spec;
search_spec.set_query(input_string);
@@ -477,19 +486,22 @@
std::unique_ptr<LanguageSegmenter> language_segmenter =
language_segmenter_factory::Create(std::move(options)).ValueOrDie();
std::unique_ptr<Normalizer> normalizer = CreateNormalizer();
- FakeClock fake_clock;
SchemaProto schema;
auto type_config = schema.add_types();
type_config->set_schema_type("type1");
- ICING_ASSERT_OK_AND_ASSIGN(std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem, schema_dir));
+ Clock clock;
+ ICING_ASSERT_OK_AND_ASSIGN(
+ std::unique_ptr<SchemaStore> schema_store,
+ SchemaStore::Create(&filesystem, schema_dir, &clock));
ICING_ASSERT_OK(schema_store->SetSchema(schema));
- std::unique_ptr<DocumentStore> document_store =
- DocumentStore::Create(&filesystem, doc_store_dir, &fake_clock,
+ DocumentStore::CreateResult create_result =
+ DocumentStore::Create(&filesystem, doc_store_dir, &clock,
schema_store.get())
.ValueOrDie();
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
DocumentId document_id = document_store
->Put(DocumentBuilder()
@@ -509,7 +521,7 @@
std::unique_ptr<QueryProcessor> query_processor,
QueryProcessor::Create(index.get(), language_segmenter.get(),
normalizer.get(), document_store.get(),
- schema_store.get(), &fake_clock));
+ schema_store.get(), &clock));
SearchSpecProto search_spec;
search_spec.set_query(input_string);
diff --git a/icing/query/query-processor_test.cc b/icing/query/query-processor_test.cc
index 16bd120..8c46736 100644
--- a/icing/query/query-processor_test.cc
+++ b/icing/query/query-processor_test.cc
@@ -39,6 +39,7 @@
#include "icing/testing/common-matchers.h"
#include "icing/testing/fake-clock.h"
#include "icing/testing/jni-test-helpers.h"
+#include "icing/testing/platform.h"
#include "icing/testing/test-data.h"
#include "icing/testing/tmp-directory.h"
#include "icing/tokenization/language-segmenter-factory.h"
@@ -95,17 +96,17 @@
filesystem_.CreateDirectoryRecursively(index_dir_.c_str());
filesystem_.CreateDirectoryRecursively(store_dir_.c_str());
-#ifndef ICING_REVERSE_JNI_SEGMENTATION
- // If we've specified using the reverse-JNI method for segmentation (i.e.
- // not ICU), then we won't have the ICU data file included to set up.
- // Technically, we could choose to use reverse-JNI for segmentation AND
- // include an ICU data file, but that seems unlikely and our current BUILD
- // setup doesn't do this.
- ICING_ASSERT_OK(
- // File generated via icu_data_file rule in //icing/BUILD.
- icu_data_file_helper::SetUpICUDataFile(
- GetTestFilePath("icing/icu.dat")));
-#endif // ICING_REVERSE_JNI_SEGMENTATION
+ if (!IsCfStringTokenization() && !IsReverseJniTokenization()) {
+ // If we've specified using the reverse-JNI method for segmentation (i.e.
+ // not ICU), then we won't have the ICU data file included to set up.
+ // Technically, we could choose to use reverse-JNI for segmentation AND
+ // include an ICU data file, but that seems unlikely and our current BUILD
+ // setup doesn't do this.
+ ICING_ASSERT_OK(
+ // File generated via icu_data_file rule in //icing/BUILD.
+ icu_data_file_helper::SetUpICUDataFile(
+ GetTestFilePath("icing/icu.dat")));
+ }
Index::Options options(index_dir_,
/*index_merge_size=*/1024 * 1024);
@@ -188,14 +189,16 @@
SchemaProto schema;
AddSchemaType(&schema, "email");
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ASSERT_THAT(schema_store_->SetSchema(schema), IsOk());
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, store_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id1,
document_store_->Put(DocumentBuilder()
@@ -235,14 +238,16 @@
SchemaProto schema;
AddSchemaType(&schema, "email");
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ASSERT_THAT(schema_store_->SetSchema(schema), IsOk());
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, store_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id1,
document_store_->Put(DocumentBuilder()
@@ -282,14 +287,16 @@
SchemaProto schema;
AddSchemaType(&schema, "email");
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ASSERT_THAT(schema_store_->SetSchema(schema), IsOk());
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, store_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
// These documents don't actually match to the tokens in the index. We're
// inserting the documents to get the appropriate number of documents and
@@ -338,14 +345,16 @@
SchemaProto schema;
AddSchemaType(&schema, "email");
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ASSERT_THAT(schema_store_->SetSchema(schema), IsOk());
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, store_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
// These documents don't actually match to the tokens in the index. We're
// inserting the documents to get the appropriate number of documents and
@@ -391,14 +400,16 @@
SchemaProto schema;
AddSchemaType(&schema, "email");
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ASSERT_THAT(schema_store_->SetSchema(schema), IsOk());
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, store_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
// These documents don't actually match to the tokens in the index. We're
// inserting the documents to get the appropriate number of documents and
@@ -444,18 +455,20 @@
SchemaProto schema;
AddSchemaType(&schema, "email");
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ASSERT_THAT(schema_store_->SetSchema(schema), IsOk());
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, store_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
- // These documents don't actually match to the tokens in the index. We're just
- // inserting the documents so that the DocHitInfoIterators will see that the
- // document exists and not filter out the DocumentId as deleted.
+ // These documents don't actually match to the tokens in the index. We're
+ // just inserting the documents so that the DocHitInfoIterators will see
+ // that the document exists and not filter out the DocumentId as deleted.
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id,
document_store_->Put(DocumentBuilder()
.SetKey("namespace", "1")
@@ -500,18 +513,20 @@
SchemaProto schema;
AddSchemaType(&schema, "email");
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ASSERT_THAT(schema_store_->SetSchema(schema), IsOk());
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, store_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
- // These documents don't actually match to the tokens in the index. We're just
- // inserting the documents so that the DocHitInfoIterators will see that the
- // document exists and not filter out the DocumentId as deleted.
+ // These documents don't actually match to the tokens in the index. We're
+ // just inserting the documents so that the DocHitInfoIterators will see
+ // that the document exists and not filter out the DocumentId as deleted.
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id,
document_store_->Put(DocumentBuilder()
.SetKey("namespace", "1")
@@ -556,18 +571,20 @@
SchemaProto schema;
AddSchemaType(&schema, "email");
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ASSERT_THAT(schema_store_->SetSchema(schema), IsOk());
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, store_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
- // These documents don't actually match to the tokens in the index. We're just
- // inserting the documents so that the DocHitInfoIterators will see that the
- // document exists and not filter out the DocumentId as deleted.
+ // These documents don't actually match to the tokens in the index. We're
+ // just inserting the documents so that the DocHitInfoIterators will see
+ // that the document exists and not filter out the DocumentId as deleted.
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id,
document_store_->Put(DocumentBuilder()
.SetKey("namespace", "1")
@@ -612,18 +629,20 @@
SchemaProto schema;
AddSchemaType(&schema, "email");
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ASSERT_THAT(schema_store_->SetSchema(schema), IsOk());
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, store_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
- // These documents don't actually match to the tokens in the index. We're just
- // inserting the documents so that the DocHitInfoIterators will see that the
- // document exists and not filter out the DocumentId as deleted.
+ // These documents don't actually match to the tokens in the index. We're
+ // just inserting the documents so that the DocHitInfoIterators will see
+ // that the document exists and not filter out the DocumentId as deleted.
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id1,
document_store_->Put(DocumentBuilder()
.SetKey("namespace", "1")
@@ -674,18 +693,20 @@
SchemaProto schema;
AddSchemaType(&schema, "email");
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ASSERT_THAT(schema_store_->SetSchema(schema), IsOk());
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, store_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
- // These documents don't actually match to the tokens in the index. We're just
- // inserting the documents so that the DocHitInfoIterators will see that the
- // document exists and not filter out the DocumentId as deleted.
+ // These documents don't actually match to the tokens in the index. We're
+ // just inserting the documents so that the DocHitInfoIterators will see
+ // that the document exists and not filter out the DocumentId as deleted.
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id1,
document_store_->Put(DocumentBuilder()
.SetKey("namespace", "1")
@@ -736,18 +757,20 @@
SchemaProto schema;
AddSchemaType(&schema, "email");
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ASSERT_THAT(schema_store_->SetSchema(schema), IsOk());
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, store_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
- // These documents don't actually match to the tokens in the index. We're just
- // inserting the documents so that the DocHitInfoIterators will see that the
- // document exists and not filter out the DocumentId as deleted.
+ // These documents don't actually match to the tokens in the index. We're
+ // just inserting the documents so that the DocHitInfoIterators will see
+ // that the document exists and not filter out the DocumentId as deleted.
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id1,
document_store_->Put(DocumentBuilder()
.SetKey("namespace", "1")
@@ -797,18 +820,20 @@
SchemaProto schema;
AddSchemaType(&schema, "email");
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ASSERT_THAT(schema_store_->SetSchema(schema), IsOk());
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, store_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
- // These documents don't actually match to the tokens in the index. We're just
- // inserting the documents so that the DocHitInfoIterators will see that the
- // document exists and not filter out the DocumentId as deleted.
+ // These documents don't actually match to the tokens in the index. We're
+ // just inserting the documents so that the DocHitInfoIterators will see
+ // that the document exists and not filter out the DocumentId as deleted.
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id1,
document_store_->Put(DocumentBuilder()
.SetKey("namespace", "1")
@@ -891,8 +916,8 @@
}
{
- // OR gets precedence over AND, this is parsed as (kitten AND ((foo OR bar)
- // OR cat))
+ // OR gets precedence over AND, this is parsed as (kitten AND ((foo OR
+ // bar) OR cat))
SearchSpecProto search_spec;
search_spec.set_query("kitten foo OR bar OR cat");
search_spec.set_term_match_type(term_match_type);
@@ -914,18 +939,20 @@
SchemaProto schema;
AddSchemaType(&schema, "email");
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ASSERT_THAT(schema_store_->SetSchema(schema), IsOk());
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, store_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
- // These documents don't actually match to the tokens in the index. We're just
- // inserting the documents so that the DocHitInfoIterators will see that the
- // document exists and not filter out the DocumentId as deleted.
+ // These documents don't actually match to the tokens in the index. We're
+ // just inserting the documents so that the DocHitInfoIterators will see
+ // that the document exists and not filter out the DocumentId as deleted.
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id1,
document_store_->Put(DocumentBuilder()
.SetKey("namespace", "1")
@@ -985,18 +1012,20 @@
SchemaProto schema;
AddSchemaType(&schema, "email");
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ASSERT_THAT(schema_store_->SetSchema(schema), IsOk());
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, store_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
- // These documents don't actually match to the tokens in the index. We're just
- // inserting the documents so that the DocHitInfoIterators will see that the
- // document exists and not filter out the DocumentId as deleted.
+ // These documents don't actually match to the tokens in the index. We're
+ // just inserting the documents so that the DocHitInfoIterators will see
+ // that the document exists and not filter out the DocumentId as deleted.
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id1,
document_store_->Put(DocumentBuilder()
.SetKey("namespace", "1")
@@ -1057,18 +1086,20 @@
SchemaProto schema;
AddSchemaType(&schema, "email");
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ASSERT_THAT(schema_store_->SetSchema(schema), IsOk());
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, store_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
- // These documents don't actually match to the tokens in the index. We're just
- // inserting the documents so that the DocHitInfoIterators will see that the
- // document exists and not filter out the DocumentId as deleted.
+ // These documents don't actually match to the tokens in the index. We're
+ // just inserting the documents so that the DocHitInfoIterators will see
+ // that the document exists and not filter out the DocumentId as deleted.
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id1,
document_store_->Put(DocumentBuilder()
.SetKey("namespace", "1")
@@ -1128,18 +1159,20 @@
SchemaProto schema;
AddSchemaType(&schema, "email");
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ASSERT_THAT(schema_store_->SetSchema(schema), IsOk());
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, store_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
- // These documents don't actually match to the tokens in the index. We're just
- // inserting the documents so that the DocHitInfoIterators will see that the
- // document exists and not filter out the DocumentId as deleted.
+ // These documents don't actually match to the tokens in the index. We're
+ // just inserting the documents so that the DocHitInfoIterators will see
+ // that the document exists and not filter out the DocumentId as deleted.
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id1,
document_store_->Put(DocumentBuilder()
.SetKey("namespace", "1")
@@ -1199,18 +1232,20 @@
SchemaProto schema;
AddSchemaType(&schema, "email");
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ASSERT_THAT(schema_store_->SetSchema(schema), IsOk());
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, store_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
- // These documents don't actually match to the tokens in the index. We're just
- // inserting the documents so that they'll bump the last_added_document_id,
- // which will give us the proper exclusion results
+ // These documents don't actually match to the tokens in the index. We're
+ // just inserting the documents so that they'll bump the
+ // last_added_document_id, which will give us the proper exclusion results
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id1,
document_store_->Put(DocumentBuilder()
.SetKey("namespace", "1")
@@ -1247,9 +1282,9 @@
ICING_ASSERT_OK_AND_ASSIGN(QueryProcessor::QueryResults results,
query_processor->ParseSearch(search_spec));
- // 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 care. It
- // just wanted documents that didn't have "hello"
+ // 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
+ // care. It just wanted documents that didn't have "hello"
EXPECT_THAT(GetDocHitInfos(results.root_iterator.get()),
ElementsAre(DocHitInfo(document_id2, kSectionIdMaskNone)));
EXPECT_THAT(results.query_terms, IsEmpty());
@@ -1260,18 +1295,20 @@
SchemaProto schema;
AddSchemaType(&schema, "email");
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ASSERT_THAT(schema_store_->SetSchema(schema), IsOk());
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, store_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
- // These documents don't actually match to the tokens in the index. We're just
- // inserting the documents so that they'll bump the last_added_document_id,
- // which will give us the proper exclusion results
+ // These documents don't actually match to the tokens in the index. We're
+ // just inserting the documents so that they'll bump the
+ // last_added_document_id, which will give us the proper exclusion results
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id1,
document_store_->Put(DocumentBuilder()
.SetKey("namespace", "1")
@@ -1319,18 +1356,20 @@
SchemaProto schema;
AddSchemaType(&schema, "email");
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ASSERT_THAT(schema_store_->SetSchema(schema), IsOk());
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, store_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
- // These documents don't actually match to the tokens in the index. We're just
- // inserting the documents so that they'll bump the last_added_document_id,
- // which will give us the proper exclusion results
+ // These documents don't actually match to the tokens in the index. We're
+ // just inserting the documents so that they'll bump the
+ // last_added_document_id, which will give us the proper exclusion results
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id1,
document_store_->Put(DocumentBuilder()
.SetKey("namespace", "1")
@@ -1375,8 +1414,8 @@
ICING_ASSERT_OK_AND_ASSIGN(QueryProcessor::QueryResults results,
query_processor->ParseSearch(search_spec));
- // The query is interpreted as "exclude all documents that have animal, and
- // exclude all documents that have cat". Since both documents contain
+ // The query is interpreted as "exclude all documents that have animal,
+ // and exclude all documents that have cat". Since both documents contain
// animal, there are no results.
EXPECT_THAT(GetDocHitInfos(results.root_iterator.get()), IsEmpty());
EXPECT_THAT(results.query_terms, IsEmpty());
@@ -1390,8 +1429,8 @@
ICING_ASSERT_OK_AND_ASSIGN(QueryProcessor::QueryResults results,
query_processor->ParseSearch(search_spec));
- // The query is interpreted as "exclude all documents that have animal, and
- // include all documents that have cat". Since both documents contain
+ // The query is interpreted as "exclude all documents that have animal,
+ // and include all documents that have cat". Since both documents contain
// animal, there are no results.
EXPECT_THAT(GetDocHitInfos(results.root_iterator.get()), IsEmpty());
EXPECT_THAT(results.query_terms, SizeIs(1));
@@ -1404,18 +1443,20 @@
SchemaProto schema;
AddSchemaType(&schema, "email");
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ASSERT_THAT(schema_store_->SetSchema(schema), IsOk());
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, store_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
- // These documents don't actually match to the tokens in the index. We're just
- // inserting the documents so that they'll bump the last_added_document_id,
- // which will give us the proper exclusion results
+ // These documents don't actually match to the tokens in the index. We're
+ // just inserting the documents so that they'll bump the
+ // last_added_document_id, which will give us the proper exclusion results
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id1,
document_store_->Put(DocumentBuilder()
.SetKey("namespace", "1")
@@ -1491,14 +1532,16 @@
SchemaProto schema;
AddSchemaType(&schema, "email");
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ASSERT_THAT(schema_store_->SetSchema(schema), IsOk());
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, store_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
// These documents don't actually match to the tokens in the index. We're
// inserting the documents to get the appropriate number of documents and
@@ -1560,14 +1603,16 @@
SchemaProto schema;
AddSchemaType(&schema, "email");
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ASSERT_THAT(schema_store_->SetSchema(schema), IsOk());
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, store_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
// These documents don't actually match to the tokens in the index. We're
// inserting the documents to get the appropriate number of documents and
@@ -1630,14 +1675,16 @@
AddSchemaType(&schema, "email");
AddSchemaType(&schema, "message");
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ASSERT_THAT(schema_store_->SetSchema(schema), IsOk());
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, store_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
// These documents don't actually match to the tokens in the index. We're
// inserting the documents to get the appropriate number of documents and
@@ -1699,14 +1746,16 @@
AddIndexedProperty(email_type, "subject");
int subject_section_id = 0;
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ASSERT_THAT(schema_store_->SetSchema(schema), IsOk());
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, store_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
// These documents don't actually match to the tokens in the index. We're
// inserting the documents to get the appropriate number of documents and
@@ -1752,24 +1801,28 @@
// Create the schema and document store
SchemaProto schema;
SchemaTypeConfigProto* email_type = AddSchemaType(&schema, "email");
- // SectionIds are assigned in ascending order per schema type, alphabetically.
+ // SectionIds are assigned in ascending order per schema type,
+ // alphabetically.
AddIndexedProperty(email_type, "a"); // Section "a" would get sectionId 0
AddIndexedProperty(email_type, "foo");
int email_foo_section_id = 1;
SchemaTypeConfigProto* message_type = AddSchemaType(&schema, "message");
- // SectionIds are assigned in ascending order per schema type, alphabetically.
+ // SectionIds are assigned in ascending order per schema type,
+ // alphabetically.
AddIndexedProperty(message_type, "foo");
int message_foo_section_id = 0;
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ASSERT_THAT(schema_store_->SetSchema(schema), IsOk());
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, store_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
// These documents don't actually match to the tokens in the index. We're
// inserting the documents to get the appropriate number of documents and
@@ -1829,23 +1882,27 @@
// Create the schema and document store
SchemaProto schema;
SchemaTypeConfigProto* email_type = AddSchemaType(&schema, "email");
- // SectionIds are assigned in ascending order per schema type, alphabetically.
+ // SectionIds are assigned in ascending order per schema type,
+ // alphabetically.
AddIndexedProperty(email_type, "foo");
int email_foo_section_id = 0;
SchemaTypeConfigProto* message_type = AddSchemaType(&schema, "message");
- // SectionIds are assigned in ascending order per schema type, alphabetically.
+ // SectionIds are assigned in ascending order per schema type,
+ // alphabetically.
AddIndexedProperty(message_type, "foo");
int message_foo_section_id = 0;
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ASSERT_THAT(schema_store_->SetSchema(schema), IsOk());
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, store_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
// These documents don't actually match to the tokens in the index. We're
// inserting the documents to get the appropriate number of documents and
@@ -1883,8 +1940,8 @@
schema_store_.get(), &fake_clock_));
SearchSpecProto search_spec;
- // Create a section filter '<section name>:<query term>', but only look within
- // documents of email schema
+ // Create a section filter '<section name>:<query term>', but only look
+ // within documents of email schema
search_spec.set_query("foo:animal");
search_spec.add_schema_type_filters("email");
search_spec.set_term_match_type(term_match_type);
@@ -1905,23 +1962,27 @@
// Create the schema and document store
SchemaProto schema;
SchemaTypeConfigProto* email_type = AddSchemaType(&schema, "email");
- // SectionIds are assigned in ascending order per schema type, alphabetically.
+ // SectionIds are assigned in ascending order per schema type,
+ // alphabetically.
AddIndexedProperty(email_type, "foo");
int email_foo_section_id = 0;
SchemaTypeConfigProto* message_type = AddSchemaType(&schema, "message");
- // SectionIds are assigned in ascending order per schema type, alphabetically.
+ // SectionIds are assigned in ascending order per schema type,
+ // alphabetically.
AddIndexedProperty(message_type, "bar");
int message_foo_section_id = 0;
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ASSERT_THAT(schema_store_->SetSchema(schema), IsOk());
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, store_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
// These documents don't actually match to the tokens in the index. We're
// inserting the documents to get the appropriate number of documents and
@@ -1946,9 +2007,9 @@
term_match_type, "animal"),
IsOk());
- // Message document has content "animal", but put in in the same section id as
- // the indexed email section id, the same id as indexed property "foo" in the
- // message type
+ // Message document has content "animal", but put in in the same section id
+ // as the indexed email section id, the same id as indexed property "foo" in
+ // the message type
ASSERT_THAT(AddTokenToIndex(message_document_id, message_foo_section_id,
term_match_type, "animal"),
IsOk());
@@ -1961,8 +2022,8 @@
schema_store_.get(), &fake_clock_));
SearchSpecProto search_spec;
- // Create a section filter '<section name>:<query term>', but only look within
- // documents of email schema
+ // Create a section filter '<section name>:<query term>', but only look
+ // within documents of email schema
search_spec.set_query("foo:animal");
search_spec.set_term_match_type(term_match_type);
@@ -1983,14 +2044,16 @@
SchemaProto schema;
AddSchemaType(&schema, "email");
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ASSERT_THAT(schema_store_->SetSchema(schema), IsOk());
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, store_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
// These documents don't actually match to the tokens in the index. We're
// inserting the documents to get the appropriate number of documents and
@@ -2017,8 +2080,8 @@
schema_store_.get(), &fake_clock_));
SearchSpecProto search_spec;
- // Create a section filter '<section name>:<query term>', but only look within
- // documents of email schema
+ // Create a section filter '<section name>:<query term>', but only look
+ // within documents of email schema
search_spec.set_query("nonexistent:animal");
search_spec.set_term_match_type(term_match_type);
@@ -2039,14 +2102,16 @@
SchemaTypeConfigProto* email_type = AddSchemaType(&schema, "email");
AddUnindexedProperty(email_type, "foo");
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ASSERT_THAT(schema_store_->SetSchema(schema), IsOk());
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, store_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
// These documents don't actually match to the tokens in the index. We're
// inserting the documents to get the appropriate number of documents and
@@ -2073,8 +2138,8 @@
schema_store_.get(), &fake_clock_));
SearchSpecProto search_spec;
- // Create a section filter '<section name>:<query term>', but only look within
- // documents of email schema
+ // Create a section filter '<section name>:<query term>', but only look
+ // within documents of email schema
search_spec.set_query("foo:animal");
search_spec.set_term_match_type(term_match_type);
@@ -2092,23 +2157,27 @@
// Create the schema and document store
SchemaProto schema;
SchemaTypeConfigProto* email_type = AddSchemaType(&schema, "email");
- // SectionIds are assigned in ascending order per schema type, alphabetically.
+ // SectionIds are assigned in ascending order per schema type,
+ // alphabetically.
AddIndexedProperty(email_type, "foo");
int email_foo_section_id = 0;
SchemaTypeConfigProto* message_type = AddSchemaType(&schema, "message");
- // SectionIds are assigned in ascending order per schema type, alphabetically.
+ // SectionIds are assigned in ascending order per schema type,
+ // alphabetically.
AddIndexedProperty(message_type, "foo");
int message_foo_section_id = 0;
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ASSERT_THAT(schema_store_->SetSchema(schema), IsOk());
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, store_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
// These documents don't actually match to the tokens in the index. We're
// inserting the documents to get the appropriate number of documents and
@@ -2172,14 +2241,16 @@
SchemaProto schema;
AddSchemaType(&schema, "email");
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ASSERT_THAT(schema_store_->SetSchema(schema), IsOk());
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, store_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id,
document_store_->Put(DocumentBuilder()
@@ -2226,14 +2297,16 @@
SchemaProto schema;
AddSchemaType(&schema, "email");
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ASSERT_THAT(schema_store_->SetSchema(schema), IsOk());
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, store_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id,
document_store_->Put(DocumentBuilder()
diff --git a/icing/result/result-retriever_test.cc b/icing/result/result-retriever_test.cc
index 1d1f824..1078c5a 100644
--- a/icing/result/result-retriever_test.cc
+++ b/icing/result/result-retriever_test.cc
@@ -30,6 +30,7 @@
#include "icing/store/document-id.h"
#include "icing/testing/common-matchers.h"
#include "icing/testing/fake-clock.h"
+#include "icing/testing/platform.h"
#include "icing/testing/snippet-helpers.h"
#include "icing/testing/test-data.h"
#include "icing/testing/tmp-directory.h"
@@ -56,17 +57,20 @@
}
void SetUp() override {
- ICING_ASSERT_OK(
- // File generated via icu_data_file rule in //icing/BUILD.
- icu_data_file_helper::SetUpICUDataFile(
- GetTestFilePath("icing/icu.dat")));
+ if (!IsCfStringTokenization() && !IsReverseJniTokenization()) {
+ ICING_ASSERT_OK(
+ // File generated via icu_data_file rule in //icing/BUILD.
+ icu_data_file_helper::SetUpICUDataFile(
+ GetTestFilePath("icing/icu.dat")));
+ }
language_segmenter_factory::SegmenterOptions options(ULOC_US);
ICING_ASSERT_OK_AND_ASSIGN(
language_segmenter_,
language_segmenter_factory::Create(std::move(options)));
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ICING_ASSERT_OK_AND_ASSIGN(normalizer_, normalizer_factory::Create(
/*max_term_byte_size=*/10000));
@@ -129,9 +133,11 @@
StatusIs(libtextclassifier3::StatusCode::FAILED_PRECONDITION));
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, test_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
EXPECT_THAT(
ResultRetriever::Create(doc_store.get(), /*schema_store=*/nullptr,
@@ -149,9 +155,12 @@
TEST_F(ResultRetrieverTest, ShouldRetrieveSimpleResults) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, test_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
+
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id1,
doc_store->Put(CreateDocument(/*id=*/1)));
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id2,
@@ -190,9 +199,12 @@
TEST_F(ResultRetrieverTest, IgnoreErrors) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, test_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
+
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id1,
doc_store->Put(CreateDocument(/*id=*/1)));
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id2,
@@ -228,9 +240,12 @@
TEST_F(ResultRetrieverTest, NotIgnoreErrors) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, test_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
+
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id1,
doc_store->Put(CreateDocument(/*id=*/1)));
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id2,
@@ -272,9 +287,12 @@
ON_CALL(mock_filesystem, OpenForRead(_)).WillByDefault(Return(false));
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&mock_filesystem, test_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
+
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id1,
doc_store->Put(CreateDocument(/*id=*/1)));
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id2,
@@ -303,9 +321,12 @@
TEST_F(ResultRetrieverTest, DefaultSnippetSpecShouldDisableSnippeting) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, test_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
+
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id1,
doc_store->Put(CreateDocument(/*id=*/1)));
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id2,
@@ -343,9 +364,12 @@
TEST_F(ResultRetrieverTest, SimpleSnippeted) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, test_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
+
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id1,
doc_store->Put(CreateDocument(/*id=*/1)));
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id2,
@@ -408,9 +432,12 @@
TEST_F(ResultRetrieverTest, OnlyOneDocumentSnippeted) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, test_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
+
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id1,
doc_store->Put(CreateDocument(/*id=*/1)));
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id2,
@@ -461,9 +488,12 @@
TEST_F(ResultRetrieverTest, ShouldSnippetAllResults) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, test_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
+
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id1,
doc_store->Put(CreateDocument(/*id=*/1)));
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id2,
@@ -503,9 +533,12 @@
TEST_F(ResultRetrieverTest, ShouldSnippetSomeResults) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, test_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
+
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id1,
doc_store->Put(CreateDocument(/*id=*/1)));
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id2,
@@ -544,9 +577,12 @@
TEST_F(ResultRetrieverTest, ShouldNotSnippetAnyResults) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, test_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
+
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id1,
doc_store->Put(CreateDocument(/*id=*/1)));
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id2,
diff --git a/icing/result/snippet-retriever_test.cc b/icing/result/snippet-retriever_test.cc
index e552cf2..ecda400 100644
--- a/icing/result/snippet-retriever_test.cc
+++ b/icing/result/snippet-retriever_test.cc
@@ -33,6 +33,8 @@
#include "icing/store/document-id.h"
#include "icing/store/key-mapper.h"
#include "icing/testing/common-matchers.h"
+#include "icing/testing/fake-clock.h"
+#include "icing/testing/platform.h"
#include "icing/testing/snippet-helpers.h"
#include "icing/testing/test-data.h"
#include "icing/testing/tmp-directory.h"
@@ -57,18 +59,22 @@
test_dir_ = GetTestTempDir() + "/icing";
filesystem_.CreateDirectoryRecursively(test_dir_.c_str());
- ICING_ASSERT_OK(
- // File generated via icu_data_file rule in //icing/BUILD.
- icu_data_file_helper::SetUpICUDataFile(
- GetTestFilePath("icing/icu.dat")));
+ if (!IsCfStringTokenization() && !IsReverseJniTokenization()) {
+ ICING_ASSERT_OK(
+ // File generated via icu_data_file rule in //icing/BUILD.
+ icu_data_file_helper::SetUpICUDataFile(
+ GetTestFilePath("icing/icu.dat")));
+ }
+
language_segmenter_factory::SegmenterOptions options(ULOC_US);
ICING_ASSERT_OK_AND_ASSIGN(
language_segmenter_,
language_segmenter_factory::Create(std::move(options)));
// Setup the schema
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
SchemaProto schema;
SchemaTypeConfigProto* type_config = schema.add_types();
type_config->set_schema_type("email");
@@ -110,6 +116,7 @@
}
Filesystem filesystem_;
+ FakeClock fake_clock_;
std::unique_ptr<SchemaStore> schema_store_;
std::unique_ptr<LanguageSegmenter> language_segmenter_;
std::unique_ptr<SnippetRetriever> snippet_retriever_;
diff --git a/icing/schema/schema-store.cc b/icing/schema/schema-store.cc
index 9173031..e54cc0c 100644
--- a/icing/schema/schema-store.cc
+++ b/icing/schema/schema-store.cc
@@ -39,7 +39,6 @@
#include "icing/util/crc32.h"
#include "icing/util/logging.h"
#include "icing/util/status-macros.h"
-#include "icing/util/timer.h"
namespace icing {
namespace lib {
@@ -105,18 +104,21 @@
libtextclassifier3::StatusOr<std::unique_ptr<SchemaStore>> SchemaStore::Create(
const Filesystem* filesystem, const std::string& base_dir,
- NativeInitializeStats* initialize_stats) {
+ const Clock* clock, NativeInitializeStats* initialize_stats) {
ICING_RETURN_ERROR_IF_NULL(filesystem);
+ ICING_RETURN_ERROR_IF_NULL(clock);
- std::unique_ptr<SchemaStore> schema_store =
- std::unique_ptr<SchemaStore>(new SchemaStore(filesystem, base_dir));
+ std::unique_ptr<SchemaStore> schema_store = std::unique_ptr<SchemaStore>(
+ new SchemaStore(filesystem, base_dir, clock));
ICING_RETURN_IF_ERROR(schema_store->Initialize(initialize_stats));
return schema_store;
}
-SchemaStore::SchemaStore(const Filesystem* filesystem, std::string base_dir)
+SchemaStore::SchemaStore(const Filesystem* filesystem, std::string base_dir,
+ const Clock* clock)
: filesystem_(*filesystem),
base_dir_(std::move(base_dir)),
+ clock_(*clock),
schema_file_(*filesystem, MakeSchemaFilename(base_dir_)) {}
SchemaStore::~SchemaStore() {
@@ -142,7 +144,7 @@
ICING_VLOG(3)
<< "Couldn't find derived files or failed to initialize them, "
"regenerating derived files for SchemaStore.";
- Timer regenerate_timer;
+ std::unique_ptr<Timer> regenerate_timer = clock_.GetNewTimer();
if (initialize_stats != nullptr) {
initialize_stats->set_schema_store_recovery_cause(
NativeInitializeStats::IO_ERROR);
@@ -150,7 +152,7 @@
ICING_RETURN_IF_ERROR(RegenerateDerivedFiles());
if (initialize_stats != nullptr) {
initialize_stats->set_schema_store_recovery_latency_ms(
- regenerate_timer.GetElapsedMilliseconds());
+ regenerate_timer->GetElapsedMilliseconds());
}
}
diff --git a/icing/schema/schema-store.h b/icing/schema/schema-store.h
index 76f36b4..cff7abd 100644
--- a/icing/schema/schema-store.h
+++ b/icing/schema/schema-store.h
@@ -34,6 +34,7 @@
#include "icing/schema/section.h"
#include "icing/store/document-filter-data.h"
#include "icing/store/key-mapper.h"
+#include "icing/util/clock.h"
#include "icing/util/crc32.h"
namespace icing {
@@ -114,7 +115,7 @@
// INTERNAL_ERROR on any IO errors
static libtextclassifier3::StatusOr<std::unique_ptr<SchemaStore>> Create(
const Filesystem* filesystem, const std::string& base_dir,
- NativeInitializeStats* initialize_stats = nullptr);
+ const Clock* clock, NativeInitializeStats* initialize_stats = nullptr);
// Not copyable
SchemaStore(const SchemaStore&) = delete;
@@ -227,7 +228,8 @@
private:
// Use SchemaStore::Create instead.
- explicit SchemaStore(const Filesystem* filesystem, std::string base_dir);
+ explicit SchemaStore(const Filesystem* filesystem, std::string base_dir,
+ const Clock* clock);
// Handles initializing the SchemaStore and regenerating any data if needed.
//
@@ -273,6 +275,7 @@
const Filesystem& filesystem_;
const std::string base_dir_;
+ const Clock& clock_;
// Used internally to indicate whether the class has been initialized. This is
// to guard against cases where the object has been created, but Initialize
diff --git a/icing/schema/schema-store_test.cc b/icing/schema/schema-store_test.cc
index 4a458b2..7df3dd9 100644
--- a/icing/schema/schema-store_test.cc
+++ b/icing/schema/schema-store_test.cc
@@ -31,6 +31,7 @@
#include "icing/store/document-filter-data.h"
#include "icing/testing/common-matchers.h"
#include "icing/testing/tmp-directory.h"
+#include "icing/testing/fake-clock.h"
namespace icing {
namespace lib {
@@ -69,17 +70,19 @@
const Filesystem filesystem_;
const std::string test_dir_;
SchemaProto schema_;
+ const FakeClock fake_clock_;
};
TEST_F(SchemaStoreTest, CreationWithNullPointerShouldFail) {
- EXPECT_THAT(SchemaStore::Create(/*filesystem=*/nullptr, test_dir_),
+ EXPECT_THAT(SchemaStore::Create(/*filesystem=*/nullptr, test_dir_, &fake_clock_),
StatusIs(libtextclassifier3::StatusCode::FAILED_PRECONDITION));
}
TEST_F(SchemaStoreTest, CorruptSchemaError) {
{
- ICING_ASSERT_OK_AND_ASSIGN(std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ std::unique_ptr<SchemaStore> schema_store,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
// Set it for the first time
SchemaStore::SetSchemaResult result;
@@ -105,14 +108,15 @@
serialized_schema.size());
// If ground truth was corrupted, we won't know what to do
- EXPECT_THAT(SchemaStore::Create(&filesystem_, test_dir_),
+ EXPECT_THAT(SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_),
StatusIs(libtextclassifier3::StatusCode::INTERNAL));
}
TEST_F(SchemaStoreTest, RecoverCorruptDerivedFileOk) {
{
- ICING_ASSERT_OK_AND_ASSIGN(std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ std::unique_ptr<SchemaStore> schema_store,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
// Set it for the first time
SchemaStore::SetSchemaResult result;
@@ -134,8 +138,9 @@
absl_ports::StrCat(test_dir_, "/schema_type_mapper");
filesystem_.DeleteDirectoryRecursively(schema_type_mapper_dir.c_str());
- ICING_ASSERT_OK_AND_ASSIGN(std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ std::unique_ptr<SchemaStore> schema_store,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
// Everything looks fine, ground truth and derived data
ICING_ASSERT_OK_AND_ASSIGN(const SchemaProto* actual_schema,
@@ -146,8 +151,9 @@
TEST_F(SchemaStoreTest, RecoverBadChecksumOk) {
{
- ICING_ASSERT_OK_AND_ASSIGN(std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ std::unique_ptr<SchemaStore> schema_store,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
// Set it for the first time
SchemaStore::SetSchemaResult result;
@@ -172,8 +178,9 @@
filesystem_.DeleteFile(header_file.c_str());
filesystem_.Write(header_file.c_str(), &header, sizeof(header));
- ICING_ASSERT_OK_AND_ASSIGN(std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ std::unique_ptr<SchemaStore> schema_store,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
// Everything looks fine, ground truth and derived data
ICING_ASSERT_OK_AND_ASSIGN(const SchemaProto* actual_schema,
@@ -183,12 +190,13 @@
}
TEST_F(SchemaStoreTest, CreateNoPreviousSchemaOk) {
- EXPECT_THAT(SchemaStore::Create(&filesystem_, test_dir_), IsOk());
+ EXPECT_THAT(SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_), IsOk());
}
TEST_F(SchemaStoreTest, CreateWithPreviousSchemaOk) {
- ICING_ASSERT_OK_AND_ASSIGN(std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ std::unique_ptr<SchemaStore> schema_store,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
SchemaStore::SetSchemaResult result;
result.success = true;
@@ -196,7 +204,7 @@
IsOkAndHolds(EqualsSetSchemaResult(result)));
schema_store.reset();
- EXPECT_THAT(SchemaStore::Create(&filesystem_, test_dir_), IsOk());
+ EXPECT_THAT(SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_), IsOk());
}
TEST_F(SchemaStoreTest, MultipleCreateOk) {
@@ -206,8 +214,9 @@
properties->set_name("subject");
properties->add_string_values("subject_content");
- ICING_ASSERT_OK_AND_ASSIGN(std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ std::unique_ptr<SchemaStore> schema_store,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
SchemaStore::SetSchemaResult result;
result.success = true;
@@ -225,8 +234,8 @@
EXPECT_THAT(schema_store->GetSchemaTypeId("email"), IsOkAndHolds(0));
schema_store.reset();
- ICING_ASSERT_OK_AND_ASSIGN(schema_store,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store, SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
// Verify that our in-memory structures are ok
EXPECT_THAT(schema_store->GetSchemaTypeConfig("email"),
@@ -240,8 +249,9 @@
}
TEST_F(SchemaStoreTest, SetNewSchemaOk) {
- ICING_ASSERT_OK_AND_ASSIGN(std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ std::unique_ptr<SchemaStore> schema_store,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
// Set it for the first time
SchemaStore::SetSchemaResult result;
@@ -254,8 +264,9 @@
}
TEST_F(SchemaStoreTest, SetSameSchemaOk) {
- ICING_ASSERT_OK_AND_ASSIGN(std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ std::unique_ptr<SchemaStore> schema_store,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
// Set it for the first time
SchemaStore::SetSchemaResult result;
@@ -274,8 +285,9 @@
}
TEST_F(SchemaStoreTest, SetIncompatibleSchemaOk) {
- ICING_ASSERT_OK_AND_ASSIGN(std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ std::unique_ptr<SchemaStore> schema_store,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
// Set it for the first time
SchemaStore::SetSchemaResult result;
@@ -298,8 +310,9 @@
}
TEST_F(SchemaStoreTest, SetSchemaWithAddedTypeOk) {
- ICING_ASSERT_OK_AND_ASSIGN(std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ std::unique_ptr<SchemaStore> schema_store,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
SchemaProto schema;
auto type = schema.add_types();
@@ -326,8 +339,9 @@
}
TEST_F(SchemaStoreTest, SetSchemaWithDeletedTypeOk) {
- ICING_ASSERT_OK_AND_ASSIGN(std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ std::unique_ptr<SchemaStore> schema_store,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
SchemaProto schema;
auto type = schema.add_types();
@@ -381,8 +395,9 @@
}
TEST_F(SchemaStoreTest, SetSchemaWithReorderedTypesOk) {
- ICING_ASSERT_OK_AND_ASSIGN(std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ std::unique_ptr<SchemaStore> schema_store,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
SchemaProto schema;
auto type = schema.add_types();
@@ -420,8 +435,9 @@
}
TEST_F(SchemaStoreTest, SetSchemaThatRequiresReindexingOk) {
- ICING_ASSERT_OK_AND_ASSIGN(std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ std::unique_ptr<SchemaStore> schema_store,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
SchemaProto schema;
auto type = schema.add_types();
@@ -460,8 +476,9 @@
}
TEST_F(SchemaStoreTest, SetSchemaWithIncompatibleTypesOk) {
- ICING_ASSERT_OK_AND_ASSIGN(std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ std::unique_ptr<SchemaStore> schema_store,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
SchemaProto schema;
auto type = schema.add_types();
@@ -514,8 +531,9 @@
}
TEST_F(SchemaStoreTest, GetSchemaTypeId) {
- ICING_ASSERT_OK_AND_ASSIGN(std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ std::unique_ptr<SchemaStore> schema_store,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
schema_.clear_types();
@@ -539,16 +557,18 @@
}
TEST_F(SchemaStoreTest, ComputeChecksumDefaultOnEmptySchemaStore) {
- ICING_ASSERT_OK_AND_ASSIGN(std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ std::unique_ptr<SchemaStore> schema_store,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
Crc32 default_checksum;
EXPECT_THAT(schema_store->ComputeChecksum(), IsOkAndHolds(default_checksum));
}
TEST_F(SchemaStoreTest, ComputeChecksumSameBetweenCalls) {
- ICING_ASSERT_OK_AND_ASSIGN(std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ std::unique_ptr<SchemaStore> schema_store,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
SchemaProto foo_schema;
auto type_config = foo_schema.add_types();
@@ -563,8 +583,9 @@
}
TEST_F(SchemaStoreTest, ComputeChecksumSameAcrossInstances) {
- ICING_ASSERT_OK_AND_ASSIGN(std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ std::unique_ptr<SchemaStore> schema_store,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
SchemaProto foo_schema;
auto type_config = foo_schema.add_types();
@@ -577,14 +598,15 @@
// Destroy the previous instance and recreate SchemaStore
schema_store.reset();
- ICING_ASSERT_OK_AND_ASSIGN(schema_store,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store, SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
EXPECT_THAT(schema_store->ComputeChecksum(), IsOkAndHolds(checksum));
}
TEST_F(SchemaStoreTest, ComputeChecksumChangesOnModification) {
- ICING_ASSERT_OK_AND_ASSIGN(std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ std::unique_ptr<SchemaStore> schema_store,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
SchemaProto foo_schema;
auto type_config = foo_schema.add_types();
@@ -607,16 +629,18 @@
}
TEST_F(SchemaStoreTest, PersistToDiskFineForEmptySchemaStore) {
- ICING_ASSERT_OK_AND_ASSIGN(std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ std::unique_ptr<SchemaStore> schema_store,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
// Persisting is fine and shouldn't affect anything
ICING_EXPECT_OK(schema_store->PersistToDisk());
}
TEST_F(SchemaStoreTest, PersistToDiskPreservesAcrossInstances) {
- ICING_ASSERT_OK_AND_ASSIGN(std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ std::unique_ptr<SchemaStore> schema_store,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
SchemaProto schema;
auto type_config = schema.add_types();
@@ -640,8 +664,8 @@
schema_store.reset();
// And we get the same schema back on reinitialization
- ICING_ASSERT_OK_AND_ASSIGN(schema_store,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store, SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ICING_ASSERT_OK_AND_ASSIGN(actual_schema, schema_store->GetSchema());
EXPECT_THAT(*actual_schema, EqualsProto(schema));
}
diff --git a/icing/schema/schema-util.cc b/icing/schema/schema-util.cc
index a755e88..9626a0b 100644
--- a/icing/schema/schema-util.cc
+++ b/icing/schema/schema-util.cc
@@ -272,7 +272,7 @@
const SchemaTypeConfigProto& type_config) {
ParsedPropertyConfigs parsed_property_configs;
- // TODO(samzheng): consider caching property_config_map for some properties,
+ // TODO(cassiewang): consider caching property_config_map for some properties,
// e.g. using LRU cache. Or changing schema.proto to use go/protomap.
for (const PropertyConfigProto& property_config : type_config.properties()) {
parsed_property_configs.property_config_map.emplace(
diff --git a/icing/schema/section.h b/icing/schema/section.h
index 7669c97..058f261 100644
--- a/icing/schema/section.h
+++ b/icing/schema/section.h
@@ -45,7 +45,6 @@
kMaxSectionId < 8 * sizeof(SectionIdMask),
"SectionIdMask is not large enough to represent all section values!");
-// TODO(samzheng): add more metadata when needed, e.g. tokenizer type,
struct SectionMetadata {
// Dot-joined property names, representing the location of section inside an
// document. E.g. "property1.property2"
diff --git a/icing/scoring/score-and-rank_benchmark.cc b/icing/scoring/score-and-rank_benchmark.cc
index c3ed40a..e940e98 100644
--- a/icing/scoring/score-and-rank_benchmark.cc
+++ b/icing/scoring/score-and-rank_benchmark.cc
@@ -99,14 +99,17 @@
filesystem.CreateDirectoryRecursively(document_store_dir.c_str());
filesystem.CreateDirectoryRecursively(schema_store_dir.c_str());
- ICING_ASSERT_OK_AND_ASSIGN(std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem, base_dir));
-
Clock clock;
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ std::unique_ptr<SchemaStore> schema_store,
+ SchemaStore::Create(&filesystem, base_dir, &clock));
+
+ ICING_ASSERT_OK_AND_ASSIGN(
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem, document_store_dir, &clock,
schema_store.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
ICING_ASSERT_OK(schema_store->SetSchema(CreateSchemaWithEmailType()));
@@ -198,14 +201,17 @@
filesystem.CreateDirectoryRecursively(document_store_dir.c_str());
filesystem.CreateDirectoryRecursively(schema_store_dir.c_str());
- ICING_ASSERT_OK_AND_ASSIGN(std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem, base_dir));
-
Clock clock;
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ std::unique_ptr<SchemaStore> schema_store,
+ SchemaStore::Create(&filesystem, base_dir, &clock));
+
+ ICING_ASSERT_OK_AND_ASSIGN(
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem, document_store_dir, &clock,
schema_store.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
ICING_ASSERT_OK(schema_store->SetSchema(CreateSchemaWithEmailType()));
@@ -298,14 +304,17 @@
filesystem.CreateDirectoryRecursively(document_store_dir.c_str());
filesystem.CreateDirectoryRecursively(schema_store_dir.c_str());
- ICING_ASSERT_OK_AND_ASSIGN(std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem, base_dir));
-
Clock clock;
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ std::unique_ptr<SchemaStore> schema_store,
+ SchemaStore::Create(&filesystem, base_dir, &clock));
+
+ ICING_ASSERT_OK_AND_ASSIGN(
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem, document_store_dir, &clock,
schema_store.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
ICING_ASSERT_OK(schema_store->SetSchema(CreateSchemaWithEmailType()));
diff --git a/icing/scoring/scorer_test.cc b/icing/scoring/scorer_test.cc
index 06bf484..b669eb1 100644
--- a/icing/scoring/scorer_test.cc
+++ b/icing/scoring/scorer_test.cc
@@ -53,12 +53,14 @@
fake_clock2_.SetSystemTimeMilliseconds(1572200000000);
ICING_ASSERT_OK_AND_ASSIGN(
- schema_store_, SchemaStore::Create(&filesystem_, schema_store_dir_));
+ schema_store_,
+ SchemaStore::Create(&filesystem_, schema_store_dir_, &fake_clock1_));
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, doc_store_dir_, &fake_clock1_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
// Creates a simple email schema
SchemaProto test_email_schema;
diff --git a/icing/scoring/scoring-processor_test.cc b/icing/scoring/scoring-processor_test.cc
index 0da25f6..14b2a20 100644
--- a/icing/scoring/scoring-processor_test.cc
+++ b/icing/scoring/scoring-processor_test.cc
@@ -49,13 +49,15 @@
filesystem_.CreateDirectoryRecursively(doc_store_dir_.c_str());
filesystem_.CreateDirectoryRecursively(schema_store_dir_.c_str());
- ICING_ASSERT_OK_AND_ASSIGN(schema_store_,
- SchemaStore::Create(&filesystem_, test_dir_));
+ ICING_ASSERT_OK_AND_ASSIGN(
+ schema_store_,
+ SchemaStore::Create(&filesystem_, test_dir_, &fake_clock_));
ICING_ASSERT_OK_AND_ASSIGN(
- document_store_,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, doc_store_dir_, &fake_clock_,
schema_store_.get()));
+ document_store_ = std::move(create_result.document_store);
// Creates a simple email schema
SchemaProto test_email_schema;
diff --git a/icing/store/document-store.cc b/icing/store/document-store.cc
index 8ddde14..ce41715 100644
--- a/icing/store/document-store.cc
+++ b/icing/store/document-store.cc
@@ -44,9 +44,9 @@
#include "icing/store/namespace-id.h"
#include "icing/util/clock.h"
#include "icing/util/crc32.h"
+#include "icing/util/data-loss.h"
#include "icing/util/logging.h"
#include "icing/util/status-macros.h"
-#include "icing/util/timer.h"
namespace icing {
namespace lib {
@@ -200,21 +200,26 @@
}
}
-libtextclassifier3::StatusOr<std::unique_ptr<DocumentStore>>
-DocumentStore::Create(const Filesystem* filesystem, const std::string& base_dir,
- const Clock* clock, const SchemaStore* schema_store,
- NativeInitializeStats* initialize_stats) {
+libtextclassifier3::StatusOr<DocumentStore::CreateResult> DocumentStore::Create(
+ const Filesystem* filesystem, const std::string& base_dir,
+ const Clock* clock, const SchemaStore* schema_store,
+ NativeInitializeStats* initialize_stats) {
ICING_RETURN_ERROR_IF_NULL(filesystem);
ICING_RETURN_ERROR_IF_NULL(clock);
ICING_RETURN_ERROR_IF_NULL(schema_store);
auto document_store = std::unique_ptr<DocumentStore>(
new DocumentStore(filesystem, base_dir, clock, schema_store));
- ICING_RETURN_IF_ERROR(document_store->Initialize(initialize_stats));
- return document_store;
+ ICING_ASSIGN_OR_RETURN(DataLoss data_loss,
+ document_store->Initialize(initialize_stats));
+
+ CreateResult create_result;
+ create_result.document_store = std::move(document_store);
+ create_result.data_loss = data_loss;
+ return create_result;
}
-libtextclassifier3::Status DocumentStore::Initialize(
+libtextclassifier3::StatusOr<DataLoss> DocumentStore::Initialize(
NativeInitializeStats* initialize_stats) {
auto create_result_or = FileBackedProtoLog<DocumentWrapper>::Create(
filesystem_, MakeDocumentLogFilename(base_dir_),
@@ -238,8 +243,7 @@
initialize_stats->set_document_store_recovery_cause(
NativeInitializeStats::DATA_LOSS);
- if (create_result.data_status ==
- FileBackedProtoLog<DocumentWrapper>::CreateResult::PARTIAL_LOSS) {
+ if (create_result.data_loss == DataLoss::PARTIAL) {
// Ground truth is partially lost.
initialize_stats->set_document_store_data_status(
NativeInitializeStats::PARTIAL_LOSS);
@@ -249,11 +253,11 @@
NativeInitializeStats::COMPLETE_LOSS);
}
}
- Timer document_recovery_timer;
+ std::unique_ptr<Timer> document_recovery_timer = clock_.GetNewTimer();
libtextclassifier3::Status status = RegenerateDerivedFiles();
if (initialize_stats != nullptr) {
initialize_stats->set_document_store_recovery_latency_ms(
- document_recovery_timer.GetElapsedMilliseconds());
+ document_recovery_timer->GetElapsedMilliseconds());
}
if (!status.ok()) {
ICING_LOG(ERROR)
@@ -269,11 +273,11 @@
initialize_stats->set_document_store_recovery_cause(
NativeInitializeStats::IO_ERROR);
}
- Timer document_recovery_timer;
+ std::unique_ptr<Timer> document_recovery_timer = clock_.GetNewTimer();
libtextclassifier3::Status status = RegenerateDerivedFiles();
if (initialize_stats != nullptr) {
initialize_stats->set_document_store_recovery_latency_ms(
- document_recovery_timer.GetElapsedMilliseconds());
+ document_recovery_timer->GetElapsedMilliseconds());
}
if (!status.ok()) {
ICING_LOG(ERROR)
@@ -288,7 +292,7 @@
initialize_stats->set_num_documents(document_id_mapper_->num_elements());
}
- return libtextclassifier3::Status::OK;
+ return create_result.data_loss;
}
libtextclassifier3::Status DocumentStore::InitializeDerivedFiles() {
@@ -726,7 +730,7 @@
libtextclassifier3::StatusOr<DocumentId> DocumentStore::Put(
DocumentProto&& document, NativePutDocumentStats* put_document_stats) {
- Timer put_timer;
+ std::unique_ptr<Timer> put_timer = clock_.GetNewTimer();
ICING_RETURN_IF_ERROR(document_validator_.Validate(document));
if (put_document_stats != nullptr) {
@@ -808,7 +812,7 @@
if (put_document_stats != nullptr) {
put_document_stats->set_document_store_latency_ms(
- put_timer.GetElapsedMilliseconds());
+ put_timer->GetElapsedMilliseconds());
}
return new_document_id;
@@ -1406,9 +1410,11 @@
"New directory is the same as the current one.");
}
- ICING_ASSIGN_OR_RETURN(auto new_doc_store,
+ ICING_ASSIGN_OR_RETURN(auto doc_store_create_result,
DocumentStore::Create(filesystem_, new_directory,
&clock_, schema_store_));
+ std::unique_ptr<DocumentStore> new_doc_store =
+ std::move(doc_store_create_result.document_store);
// Writes all valid docs into new document store (new directory)
int size = document_id_mapper_->num_elements();
diff --git a/icing/store/document-store.h b/icing/store/document-store.h
index d6ffbaa..114fa13 100644
--- a/icing/store/document-store.h
+++ b/icing/store/document-store.h
@@ -38,6 +38,7 @@
#include "icing/store/usage-store.h"
#include "icing/util/clock.h"
#include "icing/util/crc32.h"
+#include "icing/util/data-loss.h"
#include "icing/util/document-validator.h"
namespace icing {
@@ -70,6 +71,17 @@
int32_t optimizable_docs = 0;
};
+ struct CreateResult {
+ // A successfully initialized document store.
+ std::unique_ptr<DocumentStore> document_store;
+
+ // The data status after initializing from a previous state. Data loss can
+ // happen if the file is corrupted or some previously added data was
+ // unpersisted. This may be used to signal that any derived data off of the
+ // document store may need to be regenerated.
+ DataLoss data_loss;
+ };
+
// Not copyable
DocumentStore(const DocumentStore&) = delete;
DocumentStore& operator=(const DocumentStore&) = delete;
@@ -92,10 +104,10 @@
// were regenerated. This may be helpful in logs.
//
// Returns:
- // A DocumentStore on success
+ // A DocumentStore::CreateResult on success
// FAILED_PRECONDITION on any null pointer input
// INTERNAL_ERROR on IO error
- static libtextclassifier3::StatusOr<std::unique_ptr<DocumentStore>> Create(
+ static libtextclassifier3::StatusOr<DocumentStore::CreateResult> Create(
const Filesystem* filesystem, const std::string& base_dir,
const Clock* clock, const SchemaStore* schema_store,
NativeInitializeStats* initialize_stats = nullptr);
@@ -306,7 +318,7 @@
// Disk usage on success
// INTERNAL_ERROR on IO error
//
- // TODO(samzheng): consider returning a struct which has the breakdown of each
+ // TODO(tjbarron): consider returning a struct which has the breakdown of each
// component.
libtextclassifier3::StatusOr<int64_t> GetDiskUsage() const;
@@ -438,7 +450,7 @@
// worry about this field.
bool initialized_ = false;
- libtextclassifier3::Status Initialize(
+ libtextclassifier3::StatusOr<DataLoss> Initialize(
NativeInitializeStats* initialize_stats);
// Creates sub-components and verifies the integrity of each sub-component.
diff --git a/icing/store/document-store_test.cc b/icing/store/document-store_test.cc
index d97ec46..4d8ac10 100644
--- a/icing/store/document-store_test.cc
+++ b/icing/store/document-store_test.cc
@@ -126,7 +126,8 @@
StringIndexingConfig::TokenizerType::PLAIN);
ICING_ASSERT_OK_AND_ASSIGN(
- schema_store_, SchemaStore::Create(&filesystem_, schema_store_dir_));
+ schema_store_,
+ SchemaStore::Create(&filesystem_, schema_store_dir_, &fake_clock_));
ASSERT_THAT(schema_store_->SetSchema(schema), IsOk());
}
@@ -182,9 +183,11 @@
TEST_F(DocumentStoreTest, PutAndGetInSameNamespaceOk) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
// Both documents have namespace of "icing"
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id1,
@@ -200,9 +203,11 @@
TEST_F(DocumentStoreTest, PutAndGetAcrossNamespacesOk) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
// Can handle different namespaces with same url
DocumentProto foo_document = DocumentBuilder()
@@ -231,9 +236,11 @@
// document and old doc ids are not getting reused.
TEST_F(DocumentStoreTest, PutSameKey) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
// Creates two documents with the same key (namespace + uri)
DocumentProto document1 = DocumentProto(test_document1_);
@@ -258,9 +265,12 @@
TEST_F(DocumentStoreTest, IsDocumentExisting) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
+
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id1,
doc_store->Put(DocumentProto(test_document1_)));
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id2,
@@ -287,9 +297,12 @@
TEST_F(DocumentStoreTest, GetSoftDeletedDocumentNotFound) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
+
ICING_EXPECT_OK(document_store->Put(DocumentProto(test_document1_)));
EXPECT_THAT(
document_store->Get(test_document1_.namespace_(), test_document1_.uri()),
@@ -305,9 +318,12 @@
TEST_F(DocumentStoreTest, GetHardDeletedDocumentNotFound) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
+
ICING_EXPECT_OK(document_store->Put(DocumentProto(test_document1_)));
EXPECT_THAT(
document_store->Get(test_document1_.namespace_(), test_document1_.uri()),
@@ -330,9 +346,12 @@
.Build();
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
+
ICING_EXPECT_OK(document_store->Put(document));
EXPECT_THAT(document_store->Get("namespace", "uri"),
IsOkAndHolds(EqualsProto(document)));
@@ -355,9 +374,12 @@
TEST_F(DocumentStoreTest, GetInvalidDocumentId) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
+
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id,
doc_store->Put(DocumentProto(test_document1_)));
@@ -379,9 +401,11 @@
TEST_F(DocumentStoreTest, DeleteNonexistentDocumentNotFound) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
// Validates that deleting something non-existing won't append anything to
// ground truth
@@ -399,9 +423,12 @@
TEST_F(DocumentStoreTest, DeleteAlreadyDeletedDocumentNotFound) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
+
ICING_EXPECT_OK(document_store->Put(test_document1_));
// First time is OK
@@ -416,9 +443,11 @@
TEST_F(DocumentStoreTest, SoftDeleteByNamespaceOk) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
DocumentProto document1 = test_document1_;
document1.set_namespace_("namespace.1");
@@ -456,9 +485,11 @@
TEST_F(DocumentStoreTest, HardDeleteByNamespaceOk) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
DocumentProto document1 = test_document1_;
document1.set_namespace_("namespace.1");
@@ -496,9 +527,11 @@
TEST_F(DocumentStoreTest, SoftDeleteByNamespaceNonexistentNamespaceNotFound) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
// Validates that deleting something non-existing won't append anything to
// ground truth
@@ -516,9 +549,11 @@
TEST_F(DocumentStoreTest, HardDeleteByNamespaceNonexistentNamespaceNotFound) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
// Validates that deleting something non-existing won't append anything to
// ground truth
@@ -536,9 +571,12 @@
TEST_F(DocumentStoreTest, SoftDeleteByNamespaceNoExistingDocumentsNotFound) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ 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()));
@@ -553,9 +591,12 @@
TEST_F(DocumentStoreTest, HardDeleteByNamespaceNoExistingDocumentsNotFound) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ 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()));
@@ -588,9 +629,12 @@
int64_t ground_truth_size_before;
{
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
+
ICING_ASSERT_OK(doc_store->Put(document1));
ICING_ASSERT_OK(doc_store->Put(document2));
ICING_ASSERT_OK(doc_store->Put(document3));
@@ -617,9 +661,11 @@
// Successfully recover from a corrupt derived file issue.
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
// Make sure we didn't add anything to the ground truth after we recovered.
int64_t ground_truth_size_after = filesystem_.GetFileSize(
@@ -650,14 +696,16 @@
filesystem_.CreateDirectoryRecursively(schema_store_dir.c_str());
ICING_ASSERT_OK_AND_ASSIGN(
std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem_, schema_store_dir));
+ SchemaStore::Create(&filesystem_, schema_store_dir, &fake_clock_));
ICING_ASSERT_OK(schema_store->SetSchema(schema));
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
DocumentProto email_document_1 = DocumentBuilder()
.SetKey("namespace1", "1")
@@ -731,14 +779,16 @@
filesystem_.CreateDirectoryRecursively(schema_store_dir.c_str());
ICING_ASSERT_OK_AND_ASSIGN(
std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem_, schema_store_dir));
+ SchemaStore::Create(&filesystem_, schema_store_dir, &fake_clock_));
ICING_ASSERT_OK(schema_store->SetSchema(schema));
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
DocumentProto email_document_1 = DocumentBuilder()
.SetKey("namespace1", "1")
@@ -800,9 +850,11 @@
TEST_F(DocumentStoreTest, SoftDeleteBySchemaTypeNonexistentSchemaTypeNotFound) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
// Validates that deleting something non-existing won't append anything to
// ground truth
@@ -821,9 +873,11 @@
TEST_F(DocumentStoreTest, HardDeleteBySchemaTypeNonexistentSchemaTypeNotFound) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
// Validates that deleting something non-existing won't append anything to
// ground truth
@@ -842,9 +896,12 @@
TEST_F(DocumentStoreTest, SoftDeleteBySchemaTypeNoExistingDocumentsNotFound) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ 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()));
@@ -856,9 +913,12 @@
TEST_F(DocumentStoreTest, HardDeleteBySchemaTypeNoExistingDocumentsNotFound) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ 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()));
@@ -880,7 +940,7 @@
filesystem_.CreateDirectoryRecursively(schema_store_dir.c_str());
ICING_ASSERT_OK_AND_ASSIGN(
std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem_, schema_store_dir));
+ SchemaStore::Create(&filesystem_, schema_store_dir, &fake_clock_));
ICING_ASSERT_OK(schema_store->SetSchema(schema));
@@ -901,9 +961,11 @@
int64_t ground_truth_size_before;
{
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
ICING_ASSERT_OK_AND_ASSIGN(email_document_id,
document_store->Put(email_document));
@@ -930,9 +992,11 @@
// Successfully recover from a corrupt derived file issue.
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
// Make sure we didn't add anything to the ground truth after we recovered.
int64_t ground_truth_size_after = filesystem_.GetFileSize(
@@ -957,7 +1021,7 @@
filesystem_.CreateDirectoryRecursively(schema_store_dir.c_str());
ICING_ASSERT_OK_AND_ASSIGN(
std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem_, schema_store_dir));
+ SchemaStore::Create(&filesystem_, schema_store_dir, &fake_clock_));
ICING_ASSERT_OK(schema_store->SetSchema(schema));
@@ -978,9 +1042,11 @@
int64_t ground_truth_size_before;
{
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
ICING_ASSERT_OK_AND_ASSIGN(email_document_id,
document_store->Put(email_document));
@@ -1019,9 +1085,11 @@
// Successfully recover from a corrupt derived file issue.
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
// Make sure we didn't add anything to the ground truth after we recovered.
int64_t ground_truth_size_after = filesystem_.GetFileSize(
@@ -1036,9 +1104,11 @@
TEST_F(DocumentStoreTest, OptimizeInto) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
DocumentProto document1 = DocumentBuilder()
.SetKey("namespace", "uri1")
@@ -1118,9 +1188,12 @@
{
// Can put and delete fine.
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
+
ICING_ASSERT_OK_AND_ASSIGN(document_id1,
doc_store->Put(DocumentProto(test_document1_)));
ICING_ASSERT_OK_AND_ASSIGN(document_id2,
@@ -1150,9 +1223,12 @@
// Successfully recover from a data loss issue.
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
+
EXPECT_THAT(doc_store->Get(document_id1),
StatusIs(libtextclassifier3::StatusCode::NOT_FOUND));
EXPECT_THAT(doc_store->Get(document_id2),
@@ -1174,9 +1250,12 @@
{
// Can put and delete fine.
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
+
ICING_ASSERT_OK_AND_ASSIGN(document_id1,
doc_store->Put(DocumentProto(test_document1_)));
ICING_ASSERT_OK_AND_ASSIGN(document_id2,
@@ -1209,9 +1288,12 @@
// Successfully recover from a corrupt derived file issue.
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
+
EXPECT_THAT(doc_store->Get(document_id1),
StatusIs(libtextclassifier3::StatusCode::NOT_FOUND));
EXPECT_THAT(doc_store->Get(document_id2),
@@ -1233,9 +1315,12 @@
{
// Can put and delete fine.
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
+
ICING_ASSERT_OK_AND_ASSIGN(document_id1,
doc_store->Put(DocumentProto(test_document1_)));
ICING_ASSERT_OK_AND_ASSIGN(document_id2,
@@ -1264,9 +1349,12 @@
// Successfully recover from a corrupt derived file issue.
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
+
EXPECT_THAT(doc_store->Get(document_id1),
StatusIs(libtextclassifier3::StatusCode::NOT_FOUND));
EXPECT_THAT(doc_store->Get(document_id2),
@@ -1285,9 +1373,12 @@
TEST_F(DocumentStoreTest, GetDiskUsage) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
+
ICING_ASSERT_OK_AND_ASSIGN(int64_t empty_doc_store_size,
doc_store->GetDiskUsage());
EXPECT_THAT(empty_doc_store_size, Gt(0));
@@ -1313,18 +1404,23 @@
ON_CALL(mock_filesystem, GetDiskUsage(A<const char*>()))
.WillByDefault(Return(Filesystem::kBadFileSize));
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store_with_mock_filesystem,
+ create_result,
DocumentStore::Create(&mock_filesystem, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store_with_mock_filesystem =
+ std::move(create_result.document_store);
+
EXPECT_THAT(doc_store_with_mock_filesystem->GetDiskUsage(),
StatusIs(libtextclassifier3::StatusCode::INTERNAL));
}
TEST_F(DocumentStoreTest, MaxDocumentId) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
// Since the DocumentStore is empty, we get an invalid DocumentId
EXPECT_THAT(doc_store->last_added_document_id(), Eq(kInvalidDocumentId));
@@ -1344,9 +1440,11 @@
TEST_F(DocumentStoreTest, GetNamespaceId) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
DocumentProto document_namespace1 =
DocumentBuilder().SetKey("namespace1", "1").SetSchema("email").Build();
@@ -1369,9 +1467,11 @@
TEST_F(DocumentStoreTest, GetDuplicateNamespaceId) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
DocumentProto document1 =
DocumentBuilder().SetKey("namespace", "1").SetSchema("email").Build();
@@ -1387,9 +1487,11 @@
TEST_F(DocumentStoreTest, NonexistentNamespaceNotFound) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
EXPECT_THAT(doc_store->GetNamespaceId("nonexistent_namespace"),
StatusIs(libtextclassifier3::StatusCode::NOT_FOUND));
@@ -1397,9 +1499,11 @@
TEST_F(DocumentStoreTest, SoftDeletionDoesNotClearFilterCache) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id,
doc_store->Put(test_document1_));
@@ -1418,9 +1522,11 @@
TEST_F(DocumentStoreTest, HardDeleteClearsFilterCache) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id,
doc_store->Put(test_document1_));
@@ -1440,9 +1546,11 @@
TEST_F(DocumentStoreTest, SoftDeletionDoesNotClearScoreCache) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id,
doc_store->Put(test_document1_));
@@ -1460,9 +1568,11 @@
TEST_F(DocumentStoreTest, HardDeleteClearsScoreCache) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id,
doc_store->Put(test_document1_));
@@ -1480,9 +1590,11 @@
TEST_F(DocumentStoreTest, SoftDeleteDoesNotClearUsageScores) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id,
doc_store->Put(test_document1_));
@@ -1508,9 +1620,11 @@
TEST_F(DocumentStoreTest, HardDeleteShouldClearUsageScores) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id,
doc_store->Put(test_document1_));
@@ -1545,9 +1659,11 @@
.Build();
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id, doc_store->Put(document));
@@ -1567,9 +1683,11 @@
.Build();
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id, doc_store->Put(document));
@@ -1591,9 +1709,11 @@
.Build();
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id, doc_store->Put(document));
@@ -1618,9 +1738,11 @@
int64_t fake_real_time = 100;
fake_clock_.SetSystemTimeMilliseconds(fake_real_time);
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
ICING_ASSERT_OK_AND_ASSIGN(
DocumentId document_id,
@@ -1649,9 +1771,11 @@
.Build();
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> doc_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id1,
doc_store->Put(document1));
@@ -1669,9 +1793,11 @@
TEST_F(DocumentStoreTest, ComputeChecksumSameBetweenCalls) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
ICING_EXPECT_OK(document_store->Put(test_document1_));
ICING_ASSERT_OK_AND_ASSIGN(Crc32 checksum, document_store->ComputeChecksum());
@@ -1682,9 +1808,11 @@
TEST_F(DocumentStoreTest, ComputeChecksumSameAcrossInstances) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
ICING_EXPECT_OK(document_store->Put(test_document1_));
ICING_ASSERT_OK_AND_ASSIGN(Crc32 checksum, document_store->ComputeChecksum());
@@ -1692,17 +1820,20 @@
// Destroy the previous instance and recreate DocumentStore
document_store.reset();
ICING_ASSERT_OK_AND_ASSIGN(
- document_store, DocumentStore::Create(&filesystem_, document_store_dir_,
- &fake_clock_, schema_store_.get()));
+ create_result, DocumentStore::Create(&filesystem_, document_store_dir_,
+ &fake_clock_, schema_store_.get()));
+ document_store = std::move(create_result.document_store);
EXPECT_THAT(document_store->ComputeChecksum(), IsOkAndHolds(checksum));
}
TEST_F(DocumentStoreTest, ComputeChecksumChangesOnModification) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
ICING_EXPECT_OK(document_store->Put(test_document1_));
ICING_ASSERT_OK_AND_ASSIGN(Crc32 checksum, document_store->ComputeChecksum());
@@ -1739,7 +1870,7 @@
filesystem_.CreateDirectoryRecursively(schema_store_dir.c_str());
ICING_ASSERT_OK_AND_ASSIGN(
std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem_, schema_store_dir));
+ SchemaStore::Create(&filesystem_, schema_store_dir, &fake_clock_));
SchemaProto schema;
auto type_config = schema.add_types();
type_config->set_schema_type("email");
@@ -1753,9 +1884,11 @@
schema_store->GetSchemaTypeId("message"));
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
// Insert and verify a "email "document
ICING_ASSERT_OK_AND_ASSIGN(
@@ -1802,7 +1935,7 @@
filesystem_.CreateDirectoryRecursively(schema_store_dir.c_str());
ICING_ASSERT_OK_AND_ASSIGN(
std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem_, schema_store_dir));
+ SchemaStore::Create(&filesystem_, schema_store_dir, &fake_clock_));
SchemaProto schema;
auto type_config = schema.add_types();
type_config->set_schema_type("email");
@@ -1814,9 +1947,11 @@
// Successfully recover from a corrupt derived file issue. We don't fail just
// because the "message" schema type is missing
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
// "email" document is fine
EXPECT_THAT(document_store->Get(email_document_id),
@@ -1857,7 +1992,7 @@
ICING_ASSERT_OK_AND_ASSIGN(
std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem_, schema_store_dir));
+ SchemaStore::Create(&filesystem_, schema_store_dir, &fake_clock_));
ICING_EXPECT_OK(schema_store->SetSchema(schema));
ICING_ASSERT_OK_AND_ASSIGN(SchemaTypeId old_email_schema_type_id,
@@ -1879,9 +2014,12 @@
// Add the documents and check SchemaTypeIds match
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
+
ICING_ASSERT_OK_AND_ASSIGN(DocumentId email_document_id,
document_store->Put(email_document));
ICING_ASSERT_OK_AND_ASSIGN(
@@ -1948,7 +2086,7 @@
ICING_ASSERT_OK_AND_ASSIGN(
std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem_, schema_store_dir));
+ SchemaStore::Create(&filesystem_, schema_store_dir, &fake_clock_));
ICING_EXPECT_OK(schema_store->SetSchema(schema));
// Add two documents, with and without a subject
@@ -1969,9 +2107,12 @@
// Insert documents and check they're ok
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
+
ICING_ASSERT_OK_AND_ASSIGN(DocumentId email_without_subject_document_id,
document_store->Put(email_without_subject));
EXPECT_THAT(document_store->Get(email_without_subject_document_id),
@@ -2016,7 +2157,7 @@
ICING_ASSERT_OK_AND_ASSIGN(
std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem_, schema_store_dir));
+ SchemaStore::Create(&filesystem_, schema_store_dir, &fake_clock_));
ICING_EXPECT_OK(schema_store->SetSchema(schema));
// Add a "email" and "message" document
@@ -2036,9 +2177,12 @@
// Insert documents and check they're ok
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
+
ICING_ASSERT_OK_AND_ASSIGN(DocumentId email_document_id,
document_store->Put(email_document));
EXPECT_THAT(document_store->Get(email_document_id),
@@ -2082,7 +2226,7 @@
ICING_ASSERT_OK_AND_ASSIGN(
std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem_, schema_store_dir));
+ SchemaStore::Create(&filesystem_, schema_store_dir, &fake_clock_));
ICING_EXPECT_OK(schema_store->SetSchema(schema));
ICING_ASSERT_OK_AND_ASSIGN(SchemaTypeId old_email_schema_type_id,
@@ -2104,9 +2248,12 @@
// Add the documents and check SchemaTypeIds match
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
+
ICING_ASSERT_OK_AND_ASSIGN(DocumentId email_document_id,
document_store->Put(email_document));
ICING_ASSERT_OK_AND_ASSIGN(
@@ -2175,7 +2322,7 @@
ICING_ASSERT_OK_AND_ASSIGN(
std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem_, schema_store_dir));
+ SchemaStore::Create(&filesystem_, schema_store_dir, &fake_clock_));
ICING_EXPECT_OK(schema_store->SetSchema(schema));
// Add two documents, with and without a subject
@@ -2196,9 +2343,12 @@
// Insert documents and check they're ok
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
+
ICING_ASSERT_OK_AND_ASSIGN(DocumentId email_without_subject_document_id,
document_store->Put(email_without_subject));
EXPECT_THAT(document_store->Get(email_without_subject_document_id),
@@ -2246,7 +2396,7 @@
ICING_ASSERT_OK_AND_ASSIGN(
std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem_, schema_store_dir));
+ SchemaStore::Create(&filesystem_, schema_store_dir, &fake_clock_));
ICING_EXPECT_OK(schema_store->SetSchema(schema));
// Add a "email" and "message" document
@@ -2266,9 +2416,12 @@
// Insert documents and check they're ok
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
+
ICING_ASSERT_OK_AND_ASSIGN(DocumentId email_document_id,
document_store->Put(email_document));
EXPECT_THAT(document_store->Get(email_document_id),
@@ -2302,9 +2455,11 @@
TEST_F(DocumentStoreTest, GetOptimizeInfo) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
// Nothing should be optimizable yet
ICING_ASSERT_OK_AND_ASSIGN(DocumentStore::OptimizeInfo optimize_info,
@@ -2337,9 +2492,10 @@
ICING_ASSERT_OK(document_store->OptimizeInto(optimized_dir));
document_store.reset();
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> optimized_document_store,
- DocumentStore::Create(&filesystem_, optimized_dir, &fake_clock_,
- schema_store_.get()));
+ create_result, DocumentStore::Create(&filesystem_, optimized_dir,
+ &fake_clock_, schema_store_.get()));
+ std::unique_ptr<DocumentStore> optimized_document_store =
+ std::move(create_result.document_store);
ICING_ASSERT_OK_AND_ASSIGN(optimize_info,
optimized_document_store->GetOptimizeInfo());
@@ -2350,9 +2506,11 @@
TEST_F(DocumentStoreTest, GetAllNamespaces) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
// Empty namespaces to start with
EXPECT_THAT(document_store->GetAllNamespaces(), IsEmpty());
@@ -2418,9 +2576,12 @@
TEST_F(DocumentStoreTest, ReportUsageWithDifferentTimestampsAndGetUsageScores) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
+
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id,
document_store->Put(test_document1_));
@@ -2494,9 +2655,12 @@
TEST_F(DocumentStoreTest, ReportUsageWithDifferentTypesAndGetUsageScores) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
+
ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id,
document_store->Put(test_document1_));
@@ -2537,9 +2701,12 @@
DocumentId document_id;
{
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
+
ICING_ASSERT_OK_AND_ASSIGN(document_id,
document_store->Put(test_document1_));
@@ -2567,9 +2734,11 @@
// Successfully recover from a corrupt derived file issue.
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
// Usage scores should be the same.
ASSERT_THAT(document_store->GetUsageScores(document_id),
@@ -2581,9 +2750,12 @@
DocumentId document_id;
{
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
+
ICING_ASSERT_OK_AND_ASSIGN(
document_id, document_store->Put(DocumentProto(test_document1_)));
@@ -2612,9 +2784,11 @@
// Successfully recover from a data loss issue.
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
// Usage scores should still be available.
ASSERT_THAT(document_store->GetUsageScores(document_id),
@@ -2623,9 +2797,12 @@
TEST_F(DocumentStoreTest, UsageScoresShouldBeCopiedOverToUpdatedDocument) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
+
ICING_ASSERT_OK_AND_ASSIGN(
DocumentId document_id,
document_store->Put(DocumentProto(test_document1_)));
@@ -2656,9 +2833,12 @@
TEST_F(DocumentStoreTest,
UsageScoresShouldNotBeCopiedOverFromOldSoftDeletedDocs) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
+
ICING_ASSERT_OK_AND_ASSIGN(
DocumentId document_id,
document_store->Put(DocumentProto(test_document1_)));
@@ -2691,9 +2871,12 @@
TEST_F(DocumentStoreTest, UsageScoresShouldPersistOnOptimize) {
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> document_store,
+ DocumentStore::CreateResult create_result,
DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
schema_store_.get()));
+ std::unique_ptr<DocumentStore> document_store =
+ std::move(create_result.document_store);
+
ICING_ASSERT_OK_AND_ASSIGN(
DocumentId document_id1,
document_store->Put(DocumentProto(test_document1_)));
@@ -2720,9 +2903,10 @@
// Get optimized document store
ICING_ASSERT_OK_AND_ASSIGN(
- std::unique_ptr<DocumentStore> optimized_document_store,
- DocumentStore::Create(&filesystem_, optimized_dir, &fake_clock_,
- schema_store_.get()));
+ create_result, DocumentStore::Create(&filesystem_, optimized_dir,
+ &fake_clock_, schema_store_.get()));
+ std::unique_ptr<DocumentStore> optimized_document_store =
+ std::move(create_result.document_store);
// Usage scores should be the same.
// The original document_id2 should have become document_id2 - 1.
@@ -2730,6 +2914,88 @@
IsOkAndHolds(expected_scores));
}
+TEST_F(DocumentStoreTest, DetectPartialDataLoss) {
+ {
+ // Can put and delete fine.
+ ICING_ASSERT_OK_AND_ASSIGN(
+ DocumentStore::CreateResult create_result,
+ DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
+ schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
+ EXPECT_THAT(create_result.data_loss, Eq(DataLoss::NONE));
+
+ ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id,
+ doc_store->Put(DocumentProto(test_document1_)));
+ EXPECT_THAT(doc_store->Get(document_id),
+ IsOkAndHolds(EqualsProto(test_document1_)));
+ }
+
+ // "Corrupt" the content written in the log by adding non-checksummed data to
+ // it. This will mess up the checksum of the proto log, forcing it to rewind
+ // to the last saved point and triggering data loss.
+ DocumentProto document = DocumentBuilder().SetKey("namespace", "uri").Build();
+ const std::string serialized_document = document.SerializeAsString();
+
+ const std::string document_log_file =
+ absl_ports::StrCat(document_store_dir_, "/document_log");
+ int64_t file_size = filesystem_.GetFileSize(document_log_file.c_str());
+ filesystem_.PWrite(document_log_file.c_str(), file_size,
+ serialized_document.data(), serialized_document.size());
+
+ // Successfully recover from a data loss issue.
+ ICING_ASSERT_OK_AND_ASSIGN(
+ DocumentStore::CreateResult create_result,
+ DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
+ schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
+ ASSERT_THAT(create_result.data_loss, Eq(DataLoss::PARTIAL));
+}
+
+TEST_F(DocumentStoreTest, DetectCompleteDataLoss) {
+ int64_t corruptible_offset;
+ const std::string document_log_file =
+ absl_ports::StrCat(document_store_dir_, "/document_log");
+ {
+ // Can put and delete fine.
+ ICING_ASSERT_OK_AND_ASSIGN(
+ DocumentStore::CreateResult create_result,
+ DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
+ schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
+ EXPECT_THAT(create_result.data_loss, Eq(DataLoss::NONE));
+
+ // There's some space at the beginning of the file (e.g. header, kmagic,
+ // etc) that is necessary to initialize the FileBackedProtoLog. We can't
+ // corrupt that region, so we need to figure out the offset at which
+ // documents will be written to - which is the file size after
+ // initialization.
+ corruptible_offset = filesystem_.GetFileSize(document_log_file.c_str());
+
+ ICING_ASSERT_OK_AND_ASSIGN(DocumentId document_id,
+ doc_store->Put(DocumentProto(test_document1_)));
+ EXPECT_THAT(doc_store->Get(document_id),
+ IsOkAndHolds(EqualsProto(test_document1_)));
+ }
+
+ // "Corrupt" the persisted content written in the log. We can't recover if
+ // the persisted data was corrupted.
+ std::string corruption = "abc";
+ filesystem_.PWrite(document_log_file.c_str(), /*offset=*/corruptible_offset,
+ corruption.data(), corruption.size());
+
+ // Successfully recover from a data loss issue.
+ ICING_ASSERT_OK_AND_ASSIGN(
+ DocumentStore::CreateResult create_result,
+ DocumentStore::Create(&filesystem_, document_store_dir_, &fake_clock_,
+ schema_store_.get()));
+ std::unique_ptr<DocumentStore> doc_store =
+ std::move(create_result.document_store);
+ ASSERT_THAT(create_result.data_loss, Eq(DataLoss::COMPLETE));
+}
+
} // namespace
} // namespace lib
diff --git a/icing/testing/fake-clock.h b/icing/testing/fake-clock.h
index 54b56c3..f9f3654 100644
--- a/icing/testing/fake-clock.h
+++ b/icing/testing/fake-clock.h
@@ -20,6 +20,22 @@
namespace icing {
namespace lib {
+// A fake timer class for tests. It makes sure that the elapsed time changes
+// every time it's requested.
+class FakeTimer : public Timer {
+ public:
+ int64_t GetElapsedMilliseconds() override {
+ return fake_elapsed_milliseconds_;
+ }
+
+ void SetElapsedMilliseconds(int64_t elapsed_milliseconds) {
+ fake_elapsed_milliseconds_ = elapsed_milliseconds;
+ }
+
+ private:
+ int64_t fake_elapsed_milliseconds_ = 0;
+};
+
// Wrapper around real-time clock functions. This is separated primarily so
// tests can override this clock and inject it into the class under test.
class FakeClock : public Clock {
@@ -30,8 +46,17 @@
milliseconds_ = milliseconds;
}
+ std::unique_ptr<Timer> GetNewTimer() const override {
+ return std::make_unique<FakeTimer>(fake_timer_);
+ }
+
+ void SetTimerElapsedMilliseconds(int64_t timer_elapsed_milliseconds) {
+ fake_timer_.SetElapsedMilliseconds(timer_elapsed_milliseconds);
+ }
+
private:
int64_t milliseconds_ = 0;
+ FakeTimer fake_timer_;
};
} // namespace lib
diff --git a/icing/testing/fake-clock_test.cc b/icing/testing/fake-clock_test.cc
index 3c75ae9..4b36727 100644
--- a/icing/testing/fake-clock_test.cc
+++ b/icing/testing/fake-clock_test.cc
@@ -24,7 +24,7 @@
using ::testing::Eq;
-TEST(FakeClockTest, GetSetOk) {
+TEST(FakeClockTest, GetSetSystemTimeOk) {
FakeClock fake_clock;
EXPECT_THAT(fake_clock.GetSystemTimeMilliseconds(), Eq(0));
@@ -35,6 +35,17 @@
EXPECT_THAT(fake_clock.GetSystemTimeMilliseconds(), Eq(-1));
}
+TEST(FakeClockTest, GetSetTimerElapsedTimeOk) {
+ FakeClock fake_clock;
+ EXPECT_THAT(fake_clock.GetNewTimer()->GetElapsedMilliseconds(), Eq(0));
+
+ fake_clock.SetTimerElapsedMilliseconds(10);
+ EXPECT_THAT(fake_clock.GetNewTimer()->GetElapsedMilliseconds(), Eq(10));
+
+ fake_clock.SetTimerElapsedMilliseconds(-1);
+ EXPECT_THAT(fake_clock.GetNewTimer()->GetElapsedMilliseconds(), Eq(-1));
+}
+
} // namespace
} // namespace lib
diff --git a/icing/testing/platform.h b/icing/testing/platform.h
new file mode 100644
index 0000000..7b7f212
--- /dev/null
+++ b/icing/testing/platform.h
@@ -0,0 +1,42 @@
+// Copyright (C) 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ICING_TESTING_PLATFORM_H_
+#define ICING_TESTING_PLATFORM_H_
+
+// This file is meant to hold util functions for tests that help the test
+// determine which platform-specific configuration it may be running in.
+namespace icing {
+namespace lib {
+
+// Returns true if the test was built with the CFStringTokenizer as the
+// implementation of LanguageSegmenter.
+inline bool IsCfStringTokenization() {
+#if defined(__APPLE__) && !defined(ICING_IOS_ICU4C_SEGMENTATION)
+ return true;
+#endif // defined(__APPLE__) && !defined(ICING_IOS_ICU4C_SEGMENTATION)
+ return false;
+}
+
+inline bool IsReverseJniTokenization() {
+#ifdef ICING_REVERSE_JNI_SEGMENTATION
+ return true;
+#endif // ICING_REVERSE_JNI_SEGMENTATION
+ return false;
+}
+
+} // namespace lib
+} // namespace icing
+
+#endif // ICING_TESTING_PLATFORM_H_
diff --git a/icing/tokenization/icu/icu-language-segmenter-factory.cc b/icing/tokenization/icu/icu-language-segmenter-factory.cc
index 9213fbe..363bc6d 100644
--- a/icing/tokenization/icu/icu-language-segmenter-factory.cc
+++ b/icing/tokenization/icu/icu-language-segmenter-factory.cc
@@ -32,7 +32,7 @@
// A LanguageSegmenter on success
// INVALID_ARGUMENT if locale string is invalid
//
-// TODO(samzheng): Figure out if we want to verify locale strings and notify
+// TODO(b/156383798): Figure out if we want to verify locale strings and notify
// users. Right now illegal locale strings will be ignored by ICU. ICU
// components will be created with its default locale.
libtextclassifier3::StatusOr<std::unique_ptr<LanguageSegmenter>> Create(
diff --git a/icing/tokenization/icu/icu-language-segmenter_test.cc b/icing/tokenization/icu/icu-language-segmenter_test.cc
index e60f6d5..c0d6d43 100644
--- a/icing/tokenization/icu/icu-language-segmenter_test.cc
+++ b/icing/tokenization/icu/icu-language-segmenter_test.cc
@@ -395,7 +395,6 @@
IsOkAndHolds(ElementsAre("āăąḃḅḇčćç")));
}
-// TODO(samzheng): test cases for more languages (e.g. top 20 in the world)
TEST_P(IcuLanguageSegmenterAllLocalesTest, WhitespaceSplitLanguages) {
ICING_ASSERT_OK_AND_ASSIGN(auto language_segmenter,
language_segmenter_factory::Create(GetOptions()));
@@ -408,7 +407,6 @@
IsOkAndHolds(ElementsAre("나는", " ", "매일", " ", "출근합니다", ".")));
}
-// TODO(samzheng): more mixed languages test cases
TEST_P(IcuLanguageSegmenterAllLocalesTest, MixedLanguages) {
ICING_ASSERT_OK_AND_ASSIGN(auto language_segmenter,
language_segmenter_factory::Create(GetOptions()));
diff --git a/icing/tokenization/language-segmenter-iterator_test.cc b/icing/tokenization/language-segmenter-iterator_test.cc
index a1b031a..2b1911e 100644
--- a/icing/tokenization/language-segmenter-iterator_test.cc
+++ b/icing/tokenization/language-segmenter-iterator_test.cc
@@ -17,6 +17,7 @@
#include "icing/absl_ports/str_cat.h"
#include "icing/helpers/icu/icu-data-file-helper.h"
#include "icing/testing/common-matchers.h"
+#include "icing/testing/platform.h"
#include "icing/testing/test-data.h"
#include "icing/tokenization/language-segmenter-factory.h"
#include "icing/tokenization/language-segmenter.h"
@@ -35,10 +36,12 @@
class LanguageSegmenterIteratorTest : public testing::Test {
protected:
void SetUp() override {
- ICING_ASSERT_OK(
- // File generated via icu_data_file rule in //icing/BUILD.
- icu_data_file_helper::SetUpICUDataFile(
- GetTestFilePath("icing/icu.dat")));
+ if (!IsCfStringTokenization() && !IsReverseJniTokenization()) {
+ ICING_ASSERT_OK(
+ // File generated via icu_data_file rule in //icing/BUILD.
+ icu_data_file_helper::SetUpICUDataFile(
+ GetTestFilePath("icing/icu.dat")));
+ }
}
};
diff --git a/icing/tokenization/plain-tokenizer_test.cc b/icing/tokenization/plain-tokenizer_test.cc
index df0981b..f578567 100644
--- a/icing/tokenization/plain-tokenizer_test.cc
+++ b/icing/tokenization/plain-tokenizer_test.cc
@@ -21,6 +21,7 @@
#include "icing/helpers/icu/icu-data-file-helper.h"
#include "icing/testing/common-matchers.h"
#include "icing/testing/icu-i18n-test-utils.h"
+#include "icing/testing/platform.h"
#include "icing/testing/test-data.h"
#include "icing/tokenization/language-segmenter-factory.h"
#include "icing/tokenization/tokenizer-factory.h"
@@ -35,10 +36,12 @@
class PlainTokenizerTest : public ::testing::Test {
protected:
void SetUp() override {
- ICING_ASSERT_OK(
- // File generated via icu_data_file rule in //icing/BUILD.
- icu_data_file_helper::SetUpICUDataFile(
- GetTestFilePath("icing/icu.dat")));
+ if (!IsCfStringTokenization() && !IsReverseJniTokenization()) {
+ ICING_ASSERT_OK(
+ // File generated via icu_data_file rule in //icing/BUILD.
+ icu_data_file_helper::SetUpICUDataFile(
+ GetTestFilePath("icing/icu.dat")));
+ }
}
};
@@ -132,14 +135,29 @@
EqualsToken(Token::REGULAR, "World"))));
// Full-width punctuation marks are filtered out.
- EXPECT_THAT(
- plain_tokenizer->TokenizeAll("你好,世界!你好:世界。“你好”世界?"),
- IsOkAndHolds(ElementsAre(EqualsToken(Token::REGULAR, "你好"),
- EqualsToken(Token::REGULAR, "世界"),
- EqualsToken(Token::REGULAR, "你好"),
- EqualsToken(Token::REGULAR, "世界"),
- EqualsToken(Token::REGULAR, "你好"),
- EqualsToken(Token::REGULAR, "世界"))));
+ std::vector<std::string_view> exp_tokens;
+ if (IsCfStringTokenization()) {
+ EXPECT_THAT(
+ plain_tokenizer->TokenizeAll("你好,世界!你好:世界。“你好”世界?"),
+ IsOkAndHolds(ElementsAre(EqualsToken(Token::REGULAR, "你"),
+ EqualsToken(Token::REGULAR, "好"),
+ EqualsToken(Token::REGULAR, "世界"),
+ EqualsToken(Token::REGULAR, "你"),
+ EqualsToken(Token::REGULAR, "好"),
+ EqualsToken(Token::REGULAR, "世界"),
+ EqualsToken(Token::REGULAR, "你"),
+ EqualsToken(Token::REGULAR, "好"),
+ EqualsToken(Token::REGULAR, "世界"))));
+ } else {
+ EXPECT_THAT(
+ plain_tokenizer->TokenizeAll("你好,世界!你好:世界。“你好”世界?"),
+ IsOkAndHolds(ElementsAre(EqualsToken(Token::REGULAR, "你好"),
+ EqualsToken(Token::REGULAR, "世界"),
+ EqualsToken(Token::REGULAR, "你好"),
+ EqualsToken(Token::REGULAR, "世界"),
+ EqualsToken(Token::REGULAR, "你好"),
+ EqualsToken(Token::REGULAR, "世界"))));
+ }
}
TEST_F(PlainTokenizerTest, SpecialCharacters) {
@@ -166,7 +184,10 @@
}
TEST_F(PlainTokenizerTest, CJKT) {
- language_segmenter_factory::SegmenterOptions options(ULOC_US);
+ // In plain tokenizer, CJKT characters are handled the same way as non-CJKT
+ // characters, just add these tests as sanity checks.
+ // Chinese
+ language_segmenter_factory::SegmenterOptions options(ULOC_SIMPLIFIED_CHINESE);
ICING_ASSERT_OK_AND_ASSIGN(
auto language_segmenter,
language_segmenter_factory::Create(std::move(options)));
@@ -174,11 +195,6 @@
tokenizer_factory::CreateIndexingTokenizer(
StringIndexingConfig::TokenizerType::PLAIN,
language_segmenter.get()));
-
- // In plain tokenizer, CJKT characters are handled the same way as non-CJKT
- // characters, just add these tests as sanity checks.
-
- // Chinese
EXPECT_THAT(plain_tokenizer->TokenizeAll("我每天走路去上班。"),
IsOkAndHolds(ElementsAre(EqualsToken(Token::REGULAR, "我"),
EqualsToken(Token::REGULAR, "每天"),
@@ -186,16 +202,38 @@
EqualsToken(Token::REGULAR, "去"),
EqualsToken(Token::REGULAR, "上班"))));
// Japanese
- EXPECT_THAT(
- plain_tokenizer->TokenizeAll("私は毎日仕事に歩いています。"),
- IsOkAndHolds(ElementsAre(
- EqualsToken(Token::REGULAR, "私"), EqualsToken(Token::REGULAR, "は"),
- EqualsToken(Token::REGULAR, "毎日"),
- EqualsToken(Token::REGULAR, "仕事"),
- EqualsToken(Token::REGULAR, "に"), EqualsToken(Token::REGULAR, "歩"),
- EqualsToken(Token::REGULAR, "い"),
- EqualsToken(Token::REGULAR, "てい"),
- EqualsToken(Token::REGULAR, "ます"))));
+ options = language_segmenter_factory::SegmenterOptions(ULOC_JAPANESE);
+ ICING_ASSERT_OK_AND_ASSIGN(
+ language_segmenter,
+ language_segmenter_factory::Create(std::move(options)));
+ ICING_ASSERT_OK_AND_ASSIGN(plain_tokenizer,
+ tokenizer_factory::CreateIndexingTokenizer(
+ StringIndexingConfig::TokenizerType::PLAIN,
+ language_segmenter.get()));
+ if (IsCfStringTokenization()) {
+ EXPECT_THAT(plain_tokenizer->TokenizeAll("私は毎日仕事に歩いています。"),
+ IsOkAndHolds(ElementsAre(EqualsToken(Token::REGULAR, "私"),
+ EqualsToken(Token::REGULAR, "は"),
+ EqualsToken(Token::REGULAR, "毎日"),
+ EqualsToken(Token::REGULAR, "仕事"),
+ EqualsToken(Token::REGULAR, "に"),
+ EqualsToken(Token::REGULAR, "歩い"),
+ EqualsToken(Token::REGULAR, "て"),
+ EqualsToken(Token::REGULAR, "い"),
+ EqualsToken(Token::REGULAR, "ます"))));
+ } else {
+ EXPECT_THAT(plain_tokenizer->TokenizeAll("私は毎日仕事に歩いています。"),
+ IsOkAndHolds(ElementsAre(EqualsToken(Token::REGULAR, "私"),
+ EqualsToken(Token::REGULAR, "は"),
+ EqualsToken(Token::REGULAR, "毎日"),
+ EqualsToken(Token::REGULAR, "仕事"),
+ EqualsToken(Token::REGULAR, "に"),
+ EqualsToken(Token::REGULAR, "歩"),
+ EqualsToken(Token::REGULAR, "い"),
+ EqualsToken(Token::REGULAR, "てい"),
+ EqualsToken(Token::REGULAR, "ます"))));
+ }
+
// Khmer
EXPECT_THAT(plain_tokenizer->TokenizeAll("ញុំដើរទៅធ្វើការរាល់ថ្ងៃ។"),
IsOkAndHolds(ElementsAre(EqualsToken(Token::REGULAR, "ញុំ"),
@@ -210,13 +248,27 @@
EqualsToken(Token::REGULAR, "출근합니다"))));
// Thai
- EXPECT_THAT(plain_tokenizer->TokenizeAll("ฉันเดินไปทำงานทุกวัน"),
- IsOkAndHolds(ElementsAre(EqualsToken(Token::REGULAR, "ฉัน"),
- EqualsToken(Token::REGULAR, "เดิน"),
- EqualsToken(Token::REGULAR, "ไป"),
- EqualsToken(Token::REGULAR, "ทำงาน"),
- EqualsToken(Token::REGULAR, "ทุก"),
- EqualsToken(Token::REGULAR, "วัน"))));
+ // DIFFERENCE!! Disagreement over how to segment "ทุกวัน" (iOS groups).
+ // This difference persists even when locale is set to THAI
+ if (IsCfStringTokenization()) {
+ ICING_ASSERT_OK_AND_ASSIGN(
+ std::vector<Token> tokens,
+ plain_tokenizer->TokenizeAll("ฉันเดินไปทำงานทุกวัน"));
+
+ EXPECT_THAT(tokens, ElementsAre(EqualsToken(Token::REGULAR, "ฉัน"),
+ EqualsToken(Token::REGULAR, "เดิน"),
+ EqualsToken(Token::REGULAR, "ไป"),
+ EqualsToken(Token::REGULAR, "ทำงาน"),
+ EqualsToken(Token::REGULAR, "ทุกวัน")));
+ } else {
+ EXPECT_THAT(plain_tokenizer->TokenizeAll("ฉันเดินไปทำงานทุกวัน"),
+ IsOkAndHolds(ElementsAre(EqualsToken(Token::REGULAR, "ฉัน"),
+ EqualsToken(Token::REGULAR, "เดิน"),
+ EqualsToken(Token::REGULAR, "ไป"),
+ EqualsToken(Token::REGULAR, "ทำงาน"),
+ EqualsToken(Token::REGULAR, "ทุก"),
+ EqualsToken(Token::REGULAR, "วัน"))));
+ }
}
TEST_F(PlainTokenizerTest, ResetToTokenAfterSimple) {
diff --git a/icing/tokenization/raw-query-tokenizer.cc b/icing/tokenization/raw-query-tokenizer.cc
index 50b25c5..205d3a2 100644
--- a/icing/tokenization/raw-query-tokenizer.cc
+++ b/icing/tokenization/raw-query-tokenizer.cc
@@ -247,7 +247,7 @@
//
// NOTE: Please update the state transition table above if this is updated.
//
-// TODO(samzheng): support syntax "-property1:term1", right now we don't allow
+// TODO(tjbarron): support syntax "-property1:term1", right now we don't allow
// exclusion and property restriction applied on the same term.
// TODO(b/141007791): figure out how we'd like to support special characters
// like "+", "&", "@", "#" in indexing and query tokenizers.
diff --git a/icing/tokenization/raw-query-tokenizer_test.cc b/icing/tokenization/raw-query-tokenizer_test.cc
index d4af9ed..e1a666b 100644
--- a/icing/tokenization/raw-query-tokenizer_test.cc
+++ b/icing/tokenization/raw-query-tokenizer_test.cc
@@ -18,6 +18,7 @@
#include "gtest/gtest.h"
#include "icing/helpers/icu/icu-data-file-helper.h"
#include "icing/testing/common-matchers.h"
+#include "icing/testing/platform.h"
#include "icing/testing/test-data.h"
#include "icing/tokenization/language-segmenter-factory.h"
#include "icing/tokenization/tokenizer-factory.h"
@@ -33,10 +34,12 @@
class RawQueryTokenizerTest : public ::testing::Test {
protected:
void SetUp() override {
- ICING_ASSERT_OK(
- // File generated via icu_data_file rule in //icing/BUILD.
- icu_data_file_helper::SetUpICUDataFile(
- GetTestFilePath("icing/icu.dat")));
+ if (!IsCfStringTokenization() && !IsReverseJniTokenization()) {
+ ICING_ASSERT_OK(
+ // File generated via icu_data_file rule in //icing/BUILD.
+ icu_data_file_helper::SetUpICUDataFile(
+ GetTestFilePath("icing/icu.dat")));
+ }
}
};
@@ -466,16 +469,35 @@
language_segmenter.get()));
// Exclusion only applies to the term right after it.
- EXPECT_THAT(raw_query_tokenizer->TokenizeAll("-今天天气很好"),
- IsOkAndHolds(ElementsAre(EqualsToken(Token::QUERY_EXCLUSION, ""),
- EqualsToken(Token::REGULAR, "今天"),
- EqualsToken(Token::REGULAR, "天气"),
- EqualsToken(Token::REGULAR, "很好"))));
+ if (IsCfStringTokenization()) {
+ EXPECT_THAT(
+ raw_query_tokenizer->TokenizeAll("-今天天气很好"),
+ IsOkAndHolds(ElementsAre(EqualsToken(Token::QUERY_EXCLUSION, ""),
+ EqualsToken(Token::REGULAR, "今天"),
+ EqualsToken(Token::REGULAR, "天气"),
+ EqualsToken(Token::REGULAR, "很"),
+ EqualsToken(Token::REGULAR, "好"))));
+ } else {
+ EXPECT_THAT(
+ raw_query_tokenizer->TokenizeAll("-今天天气很好"),
+ IsOkAndHolds(ElementsAre(EqualsToken(Token::QUERY_EXCLUSION, ""),
+ EqualsToken(Token::REGULAR, "今天"),
+ EqualsToken(Token::REGULAR, "天气"),
+ EqualsToken(Token::REGULAR, "很好"))));
+ }
- EXPECT_THAT(
- raw_query_tokenizer->TokenizeAll("property1:你好"),
- IsOkAndHolds(ElementsAre(EqualsToken(Token::QUERY_PROPERTY, "property1"),
- EqualsToken(Token::REGULAR, "你好"))));
+ if (IsCfStringTokenization()) {
+ EXPECT_THAT(raw_query_tokenizer->TokenizeAll("property1:你好"),
+ IsOkAndHolds(
+ ElementsAre(EqualsToken(Token::QUERY_PROPERTY, "property1"),
+ EqualsToken(Token::REGULAR, "你"),
+ EqualsToken(Token::REGULAR, "好"))));
+ } else {
+ EXPECT_THAT(raw_query_tokenizer->TokenizeAll("property1:你好"),
+ IsOkAndHolds(
+ ElementsAre(EqualsToken(Token::QUERY_PROPERTY, "property1"),
+ EqualsToken(Token::REGULAR, "你好"))));
+ }
EXPECT_THAT(
raw_query_tokenizer->TokenizeAll("标题:你好"),
@@ -567,21 +589,42 @@
tokenizer_factory::CreateQueryTokenizer(tokenizer_factory::RAW_QUERY,
language_segmenter.get()));
- EXPECT_THAT(
- raw_query_tokenizer->TokenizeAll(
- "こんにちはgood afternoon, title:今天 OR (ในวันนี้ -B12)"),
- IsOkAndHolds(ElementsAre(
- EqualsToken(Token::REGULAR, "こんにちは"),
- EqualsToken(Token::REGULAR, "good"),
- EqualsToken(Token::REGULAR, "afternoon"),
- EqualsToken(Token::QUERY_PROPERTY, "title"),
- EqualsToken(Token::REGULAR, "今天"), EqualsToken(Token::QUERY_OR, ""),
- EqualsToken(Token::QUERY_LEFT_PARENTHESES, ""),
- EqualsToken(Token::REGULAR, "ใน"), EqualsToken(Token::REGULAR, "วัน"),
- EqualsToken(Token::REGULAR, "นี้"),
- EqualsToken(Token::QUERY_EXCLUSION, ""),
- EqualsToken(Token::REGULAR, "B12"),
- EqualsToken(Token::QUERY_RIGHT_PARENTHESES, ""))));
+ if (IsCfStringTokenization()) {
+ EXPECT_THAT(raw_query_tokenizer->TokenizeAll(
+ "こんにちはgood afternoon, title:今天 OR (ในวันนี้ -B12)"),
+ IsOkAndHolds(ElementsAre(
+ EqualsToken(Token::REGULAR, "こんにちは"),
+ EqualsToken(Token::REGULAR, "good"),
+ EqualsToken(Token::REGULAR, "afternoon"),
+ EqualsToken(Token::QUERY_PROPERTY, "title"),
+ EqualsToken(Token::REGULAR, "今天"),
+ EqualsToken(Token::QUERY_OR, ""),
+ EqualsToken(Token::QUERY_LEFT_PARENTHESES, ""),
+ EqualsToken(Token::REGULAR, "ใน"),
+ EqualsToken(Token::REGULAR, "วันนี้"),
+ EqualsToken(Token::QUERY_EXCLUSION, ""),
+ EqualsToken(Token::REGULAR, "B12"),
+ EqualsToken(Token::QUERY_RIGHT_PARENTHESES, ""))));
+ } else {
+ ICING_ASSERT_OK_AND_ASSIGN(
+ std::vector<Token> tokens,
+ raw_query_tokenizer->TokenizeAll(
+ "こんにちはgood afternoon, title:今天 OR (ในวันนี้ -B12)"));
+ EXPECT_THAT(tokens,
+ ElementsAre(EqualsToken(Token::REGULAR, "こんにちは"),
+ EqualsToken(Token::REGULAR, "good"),
+ EqualsToken(Token::REGULAR, "afternoon"),
+ EqualsToken(Token::QUERY_PROPERTY, "title"),
+ EqualsToken(Token::REGULAR, "今天"),
+ EqualsToken(Token::QUERY_OR, ""),
+ EqualsToken(Token::QUERY_LEFT_PARENTHESES, ""),
+ EqualsToken(Token::REGULAR, "ใน"),
+ EqualsToken(Token::REGULAR, "วัน"),
+ EqualsToken(Token::REGULAR, "นี้"),
+ EqualsToken(Token::QUERY_EXCLUSION, ""),
+ EqualsToken(Token::REGULAR, "B12"),
+ EqualsToken(Token::QUERY_RIGHT_PARENTHESES, "")));
+ }
}
} // namespace
diff --git a/icing/tokenization/reverse_jni/reverse-jni-language-segmenter-factory.cc b/icing/tokenization/reverse_jni/reverse-jni-language-segmenter-factory.cc
index db973f3..0da4c2d 100644
--- a/icing/tokenization/reverse_jni/reverse-jni-language-segmenter-factory.cc
+++ b/icing/tokenization/reverse_jni/reverse-jni-language-segmenter-factory.cc
@@ -34,7 +34,7 @@
// A LanguageSegmenter on success
// INVALID_ARGUMENT if locale string is invalid
//
-// TODO(samzheng): Figure out if we want to verify locale strings and notify
+// TODO(b/156383798): Figure out if we want to verify locale strings and notify
// users. Right now illegal locale strings will be ignored by ICU. ICU
// components will be created with its default locale.
libtextclassifier3::StatusOr<std::unique_ptr<LanguageSegmenter>> Create(
diff --git a/icing/tokenization/reverse_jni/reverse-jni-language-segmenter-test.cc b/icing/tokenization/reverse_jni/reverse-jni-language-segmenter-test.cc
index 1cd6fa3..2c268ff 100644
--- a/icing/tokenization/reverse_jni/reverse-jni-language-segmenter-test.cc
+++ b/icing/tokenization/reverse_jni/reverse-jni-language-segmenter-test.cc
@@ -423,7 +423,6 @@
IsOkAndHolds(ElementsAre("āăąḃḅḇčćç")));
}
-// TODO(samzheng): test cases for more languages (e.g. top 20 in the world)
TEST_P(ReverseJniLanguageSegmenterTest, WhitespaceSplitLanguages) {
ICING_ASSERT_OK_AND_ASSIGN(
auto language_segmenter,
@@ -438,7 +437,6 @@
IsOkAndHolds(ElementsAre("나는", " ", "매일", " ", "출근합니다", ".")));
}
-// TODO(samzheng): more mixed languages test cases
TEST_P(ReverseJniLanguageSegmenterTest, MixedLanguages) {
ICING_ASSERT_OK_AND_ASSIGN(
auto language_segmenter,
diff --git a/icing/tokenization/simple/space-language-segmenter-factory.cc b/icing/tokenization/simple/space-language-segmenter-factory.cc
index 1cca603..856ba0a 100644
--- a/icing/tokenization/simple/space-language-segmenter-factory.cc
+++ b/icing/tokenization/simple/space-language-segmenter-factory.cc
@@ -27,7 +27,7 @@
// A LanguageSegmenter on success
// INVALID_ARGUMENT if locale string is invalid
//
-// TODO(samzheng): Figure out if we want to verify locale strings and notify
+// TODO(b/156383798): Figure out if we want to verify locale strings and notify
// users. Right now illegal locale strings will be ignored by ICU. ICU
// components will be created with its default locale.
libtextclassifier3::StatusOr<std::unique_ptr<LanguageSegmenter>> Create(
diff --git a/icing/tokenization/token.h b/icing/tokenization/token.h
index 0bb3aaf..dda9efc 100644
--- a/icing/tokenization/token.h
+++ b/icing/tokenization/token.h
@@ -20,10 +20,6 @@
namespace icing {
namespace lib {
-// TODO(samzheng) Add group id support if needed. Right now in raw query we
-// don't need group ids since all our query operators (OR, Exclusion, Property
-// Restriction) only apply to the token right after them (vs. applying to
-// multiple tokens after them). The "groups" of tokens can be easily recognized.
struct Token {
enum Type {
// Common types
diff --git a/icing/transform/icu/icu-normalizer.cc b/icing/transform/icu/icu-normalizer.cc
index 0bb8326..eb0eead 100644
--- a/icing/transform/icu/icu-normalizer.cc
+++ b/icing/transform/icu/icu-normalizer.cc
@@ -41,7 +41,8 @@
// form decomposition) and NFKC (compatible normalization form composition)
// are applied as well as some other rules we need. More information at
// http://www.unicode.org/reports/tr15/
-// TODO(samzheng) Figure out if we need to support small hiragana to katakana
+//
+// Please note that the following rules don't support small hiragana to katakana
// transformation.
constexpr UChar kTransformRulesUtf16[] =
u"Lower; " // Lowercase
@@ -74,7 +75,7 @@
}
// Maximum number of pieces a Unicode character can be decomposed into.
- // TODO(samzheng) figure out if this number is proper.
+ // TODO(tjbarron) figure out if this number is proper.
constexpr int kDecompositionBufferCapacity = 5;
// A buffer used to store Unicode decomposition mappings of only one
diff --git a/icing/transform/icu/icu-normalizer_test.cc b/icing/transform/icu/icu-normalizer_test.cc
index 83fa972..f5d20ff 100644
--- a/icing/transform/icu/icu-normalizer_test.cc
+++ b/icing/transform/icu/icu-normalizer_test.cc
@@ -125,7 +125,6 @@
// Our current ICU rules can't handle Hebrew properly, e.g. the accents in
// "אָלֶף־בֵּית עִבְרִי"
// will be removed.
- // TODO (samzheng): figure out how we should handle Hebrew.
}
TEST_F(IcuNormalizerTest, FullWidthCharsToASCII) {
diff --git a/icing/util/clock.cc b/icing/util/clock.cc
index 7843bc4..270b5f0 100644
--- a/icing/util/clock.cc
+++ b/icing/util/clock.cc
@@ -16,16 +16,11 @@
#include <chrono> // NOLINT. Abseil library is not available in AOSP so we have
// to use chrono to get current time in milliseconds.
+#include <memory>
namespace icing {
namespace lib {
-int64_t Clock::GetSystemTimeMilliseconds() const {
- return std::chrono::duration_cast<std::chrono::milliseconds>(
- std::chrono::system_clock::now().time_since_epoch())
- .count();
-}
-
int64_t GetSteadyTimeNanoseconds() {
return std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::steady_clock::now().time_since_epoch())
@@ -38,5 +33,15 @@
.count();
}
+int64_t Clock::GetSystemTimeMilliseconds() const {
+ return std::chrono::duration_cast<std::chrono::milliseconds>(
+ std::chrono::system_clock::now().time_since_epoch())
+ .count();
+}
+
+std::unique_ptr<Timer> Clock::GetNewTimer() const {
+ return std::make_unique<Timer>();
+}
+
} // namespace lib
} // namespace icing
diff --git a/icing/util/clock.h b/icing/util/clock.h
index a37fe58..06f1c9d 100644
--- a/icing/util/clock.h
+++ b/icing/util/clock.h
@@ -16,21 +16,11 @@
#define ICING_UTIL_CLOCK_H_
#include <cstdint>
+#include <memory>
namespace icing {
namespace lib {
-// Wrapper around real-time clock functions. This is separated primarily so
-// tests can override this clock and inject it into the class under test.
-class Clock {
- public:
- virtual ~Clock() = default;
-
- // Returns the current time in milliseconds, it's guaranteed that the return
- // value is non-negative.
- virtual int64_t GetSystemTimeMilliseconds() const;
-};
-
// Returns the current steady time in nanoseconds. The steady clock is different
// from the system clock. It's monotonic and never returns a lower value than a
// previous call, while a system clock can be occasionally adjusted.
@@ -42,6 +32,38 @@
// adjusted.
int64_t GetSteadyTimeMilliseconds();
+// Used to calculate the elapsed time.
+class Timer {
+ public:
+ // Creates and starts the timer.
+ Timer() : start_timestamp_milliseconds_(GetSteadyTimeMilliseconds()) {}
+
+ virtual ~Timer() = default;
+
+ // Returns the elapsed time from when timer started.
+ virtual int64_t GetElapsedMilliseconds() {
+ return GetSteadyTimeMilliseconds() - start_timestamp_milliseconds_;
+ }
+
+ private:
+ int64_t start_timestamp_milliseconds_;
+};
+
+// Wrapper around real-time clock functions. This is separated primarily so
+// tests can override this clock and inject it into the class under test.
+class Clock {
+ public:
+ virtual ~Clock() = default;
+
+ // Returns the current time in milliseconds, it's guaranteed that the return
+ // value is non-negative.
+ virtual int64_t GetSystemTimeMilliseconds() const;
+
+ // Returns a timer used to calculate the elapsed time. The timer starts when
+ // the method returns.
+ virtual std::unique_ptr<Timer> GetNewTimer() const;
+};
+
} // namespace lib
} // namespace icing
diff --git a/icing/util/crc32.h b/icing/util/crc32.h
index e8c7c8f..5befe44 100644
--- a/icing/util/crc32.h
+++ b/icing/util/crc32.h
@@ -28,10 +28,6 @@
// implementation.
//
// See https://www.zlib.net/manual.html#Checksum for more details.
-//
-// TODO (samzheng): investigate/benchmark swapping zlib crc32 with
-// util/hash/crc32c.h. Regarding util/hash/crc32c.h, CRC32C::Extend crashes as
-// described in b/145837799.
class Crc32 {
public:
// Default to the checksum of an empty string, that is "0".
diff --git a/icing/util/data-loss.h b/icing/util/data-loss.h
new file mode 100644
index 0000000..cb19ce2
--- /dev/null
+++ b/icing/util/data-loss.h
@@ -0,0 +1,36 @@
+// Copyright (C) 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ICING_UTIL_DATA_LOSS_H_
+#define ICING_UTIL_DATA_LOSS_H_
+
+namespace icing {
+namespace lib {
+
+enum DataLoss {
+ // No data loss happened. Everything initialized correctly.
+ NONE,
+
+ // Anything changes made after a persist to disk call were lost. This includes
+ // adding new data, removing old data, and modifying existing data.
+ PARTIAL,
+
+ // All data is lost. IcingSearchEngine has completely reset.
+ COMPLETE
+};
+
+}
+} // namespace icing
+
+#endif // ICING_UTIL_DATA_LOSS_H_
diff --git a/icing/util/document-validator.cc b/icing/util/document-validator.cc
index 36b84f8..4d86913 100644
--- a/icing/util/document-validator.cc
+++ b/icing/util/document-validator.cc
@@ -101,7 +101,6 @@
const PropertyConfigProto& property_config = *property_iter->second;
// Get the property value size according to data type.
- // TODO (samzheng): make sure values of other data types are empty.
int value_size = 0;
if (property_config.data_type() == PropertyConfigProto::DataType::STRING) {
value_size = property.string_values_size();
diff --git a/icing/util/document-validator_test.cc b/icing/util/document-validator_test.cc
index 16bdf78..6067162 100644
--- a/icing/util/document-validator_test.cc
+++ b/icing/util/document-validator_test.cc
@@ -23,6 +23,7 @@
#include "icing/proto/schema.pb.h"
#include "icing/schema/schema-store.h"
#include "icing/testing/common-matchers.h"
+#include "icing/testing/fake-clock.h"
#include "icing/testing/tmp-directory.h"
namespace icing {
@@ -57,7 +58,8 @@
CreateConversationTypeConfig(type_config);
ICING_ASSERT_OK_AND_ASSIGN(
- schema_store_, SchemaStore::Create(&filesystem_, GetTestTempDir()));
+ schema_store_,
+ SchemaStore::Create(&filesystem_, GetTestTempDir(), &fake_clock_));
ASSERT_THAT(schema_store_->SetSchema(schema), IsOk());
document_validator_ =
@@ -121,6 +123,7 @@
std::unique_ptr<DocumentValidator> document_validator_;
std::unique_ptr<SchemaStore> schema_store_;
Filesystem filesystem_;
+ FakeClock fake_clock_;
};
TEST_F(DocumentValidatorTest, ValidateSimpleSchemasOk) {
@@ -334,7 +337,7 @@
// Set a schema with only the 'Email' type
ICING_ASSERT_OK_AND_ASSIGN(
std::unique_ptr<SchemaStore> schema_store,
- SchemaStore::Create(&filesystem_, custom_schema_dir));
+ SchemaStore::Create(&filesystem_, custom_schema_dir, &fake_clock_));
ASSERT_THAT(schema_store->SetSchema(email_schema), IsOk());
DocumentValidator document_validator(schema_store.get());
diff --git a/icing/util/timer.h b/icing/util/timer.h
deleted file mode 100644
index da872fe..0000000
--- a/icing/util/timer.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (C) 2019 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ICING_UTIL_TIMER_H_
-#define ICING_UTIL_TIMER_H_
-
-#include <cstdint>
-
-#include "icing/util/clock.h"
-
-namespace icing {
-namespace lib {
-
-// A util class to calculate the elapsed time.
-class Timer {
- public:
- // Timer starts.
- Timer() : start_timestamp_milliseconds_(GetSteadyTimeMilliseconds()) {}
-
- // Returns the elapsed time from when timer started.
- int64_t GetElapsedMilliseconds() {
- return GetSteadyTimeMilliseconds() - start_timestamp_milliseconds_;
- }
-
- private:
- int64_t start_timestamp_milliseconds_;
-};
-
-} // namespace lib
-} // namespace icing
-
-#endif // ICING_UTIL_TIMER_H_
diff --git a/java/src/com/google/android/icing/IcingSearchEngine.java b/java/src/com/google/android/icing/IcingSearchEngine.java
index 76fa33d..cac9fcd 100644
--- a/java/src/com/google/android/icing/IcingSearchEngine.java
+++ b/java/src/com/google/android/icing/IcingSearchEngine.java
@@ -30,6 +30,7 @@
import com.google.android.icing.proto.OptimizeResultProto;
import com.google.android.icing.proto.PersistToDiskResultProto;
import com.google.android.icing.proto.PutResultProto;
+import com.google.android.icing.proto.ReportUsageResultProto;
import com.google.android.icing.proto.ResetResultProto;
import com.google.android.icing.proto.ResultSpecProto;
import com.google.android.icing.proto.SchemaProto;
@@ -38,6 +39,7 @@
import com.google.android.icing.proto.SearchSpecProto;
import com.google.android.icing.proto.SetSchemaResultProto;
import com.google.android.icing.proto.StatusProto;
+import com.google.android.icing.proto.UsageReport;
import com.google.protobuf.ExtensionRegistryLite;
import com.google.protobuf.InvalidProtocolBufferException;
@@ -48,7 +50,7 @@
private static final ExtensionRegistryLite EXTENSION_REGISTRY_LITE =
ExtensionRegistryLite.getEmptyRegistry();
- private final long nativePointer;
+ private long nativePointer;
static {
// NOTE: This can fail with an UnsatisfiedLinkError
@@ -192,6 +194,26 @@
}
@NonNull
+ public ReportUsageResultProto reportUsage(@NonNull UsageReport usageReport) {
+ byte[] reportUsageResultBytes = nativeReportUsage(nativePointer, usageReport.toByteArray());
+ if (reportUsageResultBytes == null) {
+ Log.e(TAG, "Received null ReportUsageResultProto from native.");
+ return ReportUsageResultProto.newBuilder()
+ .setStatus(StatusProto.newBuilder().setCode(StatusProto.Code.INTERNAL))
+ .build();
+ }
+
+ try {
+ return ReportUsageResultProto.parseFrom(reportUsageResultBytes, EXTENSION_REGISTRY_LITE);
+ } catch (InvalidProtocolBufferException e) {
+ Log.e(TAG, "Error parsing ReportUsageResultProto.", e);
+ return ReportUsageResultProto.newBuilder()
+ .setStatus(StatusProto.newBuilder().setCode(StatusProto.Code.INTERNAL))
+ .build();
+ }
+ }
+
+ @NonNull
public GetAllNamespacesResultProto getAllNamespaces() {
byte[] getAllNamespacesResultBytes = nativeGetAllNamespaces(nativePointer);
if (getAllNamespacesResultBytes == null) {
@@ -338,8 +360,7 @@
}
try {
- return DeleteResultProto.parseFrom(
- deleteResultBytes, EXTENSION_REGISTRY_LITE);
+ return DeleteResultProto.parseFrom(deleteResultBytes, EXTENSION_REGISTRY_LITE);
} catch (InvalidProtocolBufferException e) {
Log.e(TAG, "Error parsing DeleteResultProto.", e);
return DeleteResultProto.newBuilder()
@@ -429,8 +450,17 @@
}
}
+ public void destroy() {
+ if (nativePointer != 0) {
+ nativeDestroy(nativePointer);
+ }
+ nativePointer = 0;
+ }
+
private static native long nativeCreate(byte[] icingSearchEngineOptionsBytes);
+ private static native void nativeDestroy(long nativePointer);
+
private static native byte[] nativeInitialize(long nativePointer);
private static native byte[] nativeSetSchema(
@@ -444,6 +474,8 @@
private static native byte[] nativeGet(long nativePointer, String namespace, String uri);
+ private static native byte[] nativeReportUsage(long nativePointer, byte[] usageReportBytes);
+
private static native byte[] nativeGetAllNamespaces(long nativePointer);
private static native byte[] nativeSearch(
diff --git a/java/tests/instrumentation/src/com/google/android/icing/IcingSearchEngineTest.java b/java/tests/instrumentation/src/com/google/android/icing/IcingSearchEngineTest.java
index 4c05a7a..ee8ff37 100644
--- a/java/tests/instrumentation/src/com/google/android/icing/IcingSearchEngineTest.java
+++ b/java/tests/instrumentation/src/com/google/android/icing/IcingSearchEngineTest.java
@@ -33,6 +33,7 @@
import com.google.android.icing.proto.PropertyConfigProto;
import com.google.android.icing.proto.PropertyProto;
import com.google.android.icing.proto.PutResultProto;
+import com.google.android.icing.proto.ReportUsageResultProto;
import com.google.android.icing.proto.ResetResultProto;
import com.google.android.icing.proto.ResultSpecProto;
import com.google.android.icing.proto.SchemaProto;
@@ -45,10 +46,12 @@
import com.google.android.icing.proto.StringIndexingConfig;
import com.google.android.icing.proto.StringIndexingConfig.TokenizerType;
import com.google.android.icing.proto.TermMatchType;
+import com.google.android.icing.proto.UsageReport;
import com.google.android.icing.IcingSearchEngine;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
+import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -68,6 +71,8 @@
private File tempDir;
+ private IcingSearchEngine icingSearchEngine;
+
private static SchemaTypeConfigProto createEmailTypeConfig() {
return SchemaTypeConfigProto.newBuilder()
.setSchemaType(EMAIL_TYPE)
@@ -104,77 +109,72 @@
@Before
public void setUp() throws Exception {
tempDir = temporaryFolder.newFolder();
+ IcingSearchEngineOptions options =
+ IcingSearchEngineOptions.newBuilder().setBaseDir(tempDir.getCanonicalPath()).build();
+ icingSearchEngine = new IcingSearchEngine(options);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ icingSearchEngine.destroy();
}
@Test
public void testInitialize() throws Exception {
- IcingSearchEngineOptions options =
- IcingSearchEngineOptions.newBuilder().setBaseDir(tempDir.getCanonicalPath()).build();
- IcingSearchEngine icing = new IcingSearchEngine(options);
-
- InitializeResultProto initializeResultProto = icing.initialize();
+ InitializeResultProto initializeResultProto = icingSearchEngine.initialize();
assertStatusOk(initializeResultProto.getStatus());
}
@Test
public void testSetAndGetSchema() throws Exception {
- IcingSearchEngineOptions options =
- IcingSearchEngineOptions.newBuilder().setBaseDir(tempDir.getCanonicalPath()).build();
- IcingSearchEngine icing = new IcingSearchEngine(options);
- assertStatusOk(icing.initialize().getStatus());
+ assertStatusOk(icingSearchEngine.initialize().getStatus());
SchemaTypeConfigProto emailTypeConfig = createEmailTypeConfig();
SchemaProto schema = SchemaProto.newBuilder().addTypes(emailTypeConfig).build();
SetSchemaResultProto setSchemaResultProto =
- icing.setSchema(schema, /*ignoreErrorsAndDeleteDocuments=*/ false);
+ icingSearchEngine.setSchema(schema, /*ignoreErrorsAndDeleteDocuments=*/ false);
assertStatusOk(setSchemaResultProto.getStatus());
- GetSchemaResultProto getSchemaResultProto = icing.getSchema();
+ GetSchemaResultProto getSchemaResultProto = icingSearchEngine.getSchema();
assertStatusOk(getSchemaResultProto.getStatus());
assertThat(getSchemaResultProto.getSchema()).isEqualTo(schema);
GetSchemaTypeResultProto getSchemaTypeResultProto =
- icing.getSchemaType(emailTypeConfig.getSchemaType());
+ icingSearchEngine.getSchemaType(emailTypeConfig.getSchemaType());
assertStatusOk(getSchemaTypeResultProto.getStatus());
assertThat(getSchemaTypeResultProto.getSchemaTypeConfig()).isEqualTo(emailTypeConfig);
}
@Test
public void testPutAndGetDocuments() throws Exception {
- IcingSearchEngineOptions options =
- IcingSearchEngineOptions.newBuilder().setBaseDir(tempDir.getCanonicalPath()).build();
- IcingSearchEngine icing = new IcingSearchEngine(options);
- assertStatusOk(icing.initialize().getStatus());
+ assertStatusOk(icingSearchEngine.initialize().getStatus());
SchemaTypeConfigProto emailTypeConfig = createEmailTypeConfig();
SchemaProto schema = SchemaProto.newBuilder().addTypes(emailTypeConfig).build();
assertThat(
- icing
+ icingSearchEngine
.setSchema(schema, /*ignoreErrorsAndDeleteDocuments=*/ false)
.getStatus()
.getCode())
.isEqualTo(StatusProto.Code.OK);
DocumentProto emailDocument = createEmailDocument("namespace", "uri");
- PutResultProto putResultProto = icing.put(emailDocument);
+ PutResultProto putResultProto = icingSearchEngine.put(emailDocument);
assertStatusOk(putResultProto.getStatus());
- GetResultProto getResultProto = icing.get("namespace", "uri");
+ GetResultProto getResultProto = icingSearchEngine.get("namespace", "uri");
assertStatusOk(getResultProto.getStatus());
assertThat(getResultProto.getDocument()).isEqualTo(emailDocument);
}
@Test
public void testSearch() throws Exception {
- IcingSearchEngineOptions options =
- IcingSearchEngineOptions.newBuilder().setBaseDir(tempDir.getCanonicalPath()).build();
- IcingSearchEngine icing = new IcingSearchEngine(options);
- assertStatusOk(icing.initialize().getStatus());
+ assertStatusOk(icingSearchEngine.initialize().getStatus());
SchemaTypeConfigProto emailTypeConfig = createEmailTypeConfig();
SchemaProto schema = SchemaProto.newBuilder().addTypes(emailTypeConfig).build();
assertThat(
- icing
+ icingSearchEngine
.setSchema(schema, /*ignoreErrorsAndDeleteDocuments=*/ false)
.getStatus()
.getCode())
@@ -184,7 +184,7 @@
createEmailDocument("namespace", "uri").toBuilder()
.addProperties(PropertyProto.newBuilder().setName("subject").addStringValues("foo"))
.build();
- assertStatusOk(icing.put(emailDocument).getStatus());
+ assertStatusOk(icingSearchEngine.put(emailDocument).getStatus());
SearchSpecProto searchSpec =
SearchSpecProto.newBuilder()
@@ -193,7 +193,7 @@
.build();
SearchResultProto searchResultProto =
- icing.search(
+ icingSearchEngine.search(
searchSpec,
ScoringSpecProto.getDefaultInstance(),
ResultSpecProto.getDefaultInstance());
@@ -204,15 +204,12 @@
@Test
public void testGetNextPage() throws Exception {
- IcingSearchEngineOptions options =
- IcingSearchEngineOptions.newBuilder().setBaseDir(tempDir.getCanonicalPath()).build();
- IcingSearchEngine icing = new IcingSearchEngine(options);
- assertStatusOk(icing.initialize().getStatus());
+ assertStatusOk(icingSearchEngine.initialize().getStatus());
SchemaTypeConfigProto emailTypeConfig = createEmailTypeConfig();
SchemaProto schema = SchemaProto.newBuilder().addTypes(emailTypeConfig).build();
assertThat(
- icing
+ icingSearchEngine
.setSchema(schema, /*ignoreErrorsAndDeleteDocuments=*/ false)
.getStatus()
.getCode())
@@ -225,8 +222,8 @@
.addProperties(PropertyProto.newBuilder().setName("subject").addStringValues("foo"))
.build();
documents.put("uri:" + i, emailDocument);
- assertWithMessage(icing.put(emailDocument).getStatus().getMessage())
- .that(icing.put(emailDocument).getStatus().getCode())
+ assertWithMessage(icingSearchEngine.put(emailDocument).getStatus().getMessage())
+ .that(icingSearchEngine.put(emailDocument).getStatus().getCode())
.isEqualTo(StatusProto.Code.OK);
}
@@ -238,7 +235,8 @@
ResultSpecProto resultSpecProto = ResultSpecProto.newBuilder().setNumPerPage(1).build();
SearchResultProto searchResultProto =
- icing.search(searchSpec, ScoringSpecProto.getDefaultInstance(), resultSpecProto);
+ icingSearchEngine.search(
+ searchSpec, ScoringSpecProto.getDefaultInstance(), resultSpecProto);
assertStatusOk(searchResultProto.getStatus());
assertThat(searchResultProto.getResultsCount()).isEqualTo(1);
DocumentProto resultDocument = searchResultProto.getResults(0).getDocument();
@@ -246,7 +244,7 @@
// fetch rest pages
for (int i = 1; i < 5; i++) {
- searchResultProto = icing.getNextPage(searchResultProto.getNextPageToken());
+ searchResultProto = icingSearchEngine.getNextPage(searchResultProto.getNextPageToken());
assertWithMessage(searchResultProto.getStatus().getMessage())
.that(searchResultProto.getStatus().getCode())
.isEqualTo(StatusProto.Code.OK);
@@ -256,120 +254,109 @@
}
// invalidate rest result
- icing.invalidateNextPageToken(searchResultProto.getNextPageToken());
+ icingSearchEngine.invalidateNextPageToken(searchResultProto.getNextPageToken());
- searchResultProto = icing.getNextPage(searchResultProto.getNextPageToken());
+ searchResultProto = icingSearchEngine.getNextPage(searchResultProto.getNextPageToken());
assertStatusOk(searchResultProto.getStatus());
assertThat(searchResultProto.getResultsCount()).isEqualTo(0);
}
@Test
public void testDelete() throws Exception {
- IcingSearchEngineOptions options =
- IcingSearchEngineOptions.newBuilder().setBaseDir(tempDir.getCanonicalPath()).build();
- IcingSearchEngine icing = new IcingSearchEngine(options);
- assertStatusOk(icing.initialize().getStatus());
+ assertStatusOk(icingSearchEngine.initialize().getStatus());
SchemaTypeConfigProto emailTypeConfig = createEmailTypeConfig();
SchemaProto schema = SchemaProto.newBuilder().addTypes(emailTypeConfig).build();
assertThat(
- icing
+ icingSearchEngine
.setSchema(schema, /*ignoreErrorsAndDeleteDocuments=*/ false)
.getStatus()
.getCode())
.isEqualTo(StatusProto.Code.OK);
DocumentProto emailDocument = createEmailDocument("namespace", "uri");
- assertStatusOk(icing.put(emailDocument).getStatus());
+ assertStatusOk(icingSearchEngine.put(emailDocument).getStatus());
- DeleteResultProto deleteResultProto = icing.delete("namespace", "uri");
+ DeleteResultProto deleteResultProto = icingSearchEngine.delete("namespace", "uri");
assertStatusOk(deleteResultProto.getStatus());
- GetResultProto getResultProto = icing.get("namespace", "uri");
+ GetResultProto getResultProto = icingSearchEngine.get("namespace", "uri");
assertThat(getResultProto.getStatus().getCode()).isEqualTo(StatusProto.Code.NOT_FOUND);
}
@Test
public void testDeleteByNamespace() throws Exception {
- IcingSearchEngineOptions options =
- IcingSearchEngineOptions.newBuilder().setBaseDir(tempDir.getCanonicalPath()).build();
- IcingSearchEngine icing = new IcingSearchEngine(options);
- assertStatusOk(icing.initialize().getStatus());
+ assertStatusOk(icingSearchEngine.initialize().getStatus());
SchemaTypeConfigProto emailTypeConfig = createEmailTypeConfig();
SchemaProto schema = SchemaProto.newBuilder().addTypes(emailTypeConfig).build();
assertThat(
- icing
+ icingSearchEngine
.setSchema(schema, /*ignoreErrorsAndDeleteDocuments=*/ false)
.getStatus()
.getCode())
.isEqualTo(StatusProto.Code.OK);
DocumentProto emailDocument = createEmailDocument("namespace", "uri");
- assertStatusOk(icing.put(emailDocument).getStatus());
+ assertStatusOk(icingSearchEngine.put(emailDocument).getStatus());
DeleteByNamespaceResultProto deleteByNamespaceResultProto =
- icing.deleteByNamespace("namespace");
+ icingSearchEngine.deleteByNamespace("namespace");
assertStatusOk(deleteByNamespaceResultProto.getStatus());
- GetResultProto getResultProto = icing.get("namespace", "uri");
+ GetResultProto getResultProto = icingSearchEngine.get("namespace", "uri");
assertThat(getResultProto.getStatus().getCode()).isEqualTo(StatusProto.Code.NOT_FOUND);
}
@Test
public void testDeleteBySchemaType() throws Exception {
- IcingSearchEngineOptions options =
- IcingSearchEngineOptions.newBuilder().setBaseDir(tempDir.getCanonicalPath()).build();
- IcingSearchEngine icing = new IcingSearchEngine(options);
- assertStatusOk(icing.initialize().getStatus());
+ assertStatusOk(icingSearchEngine.initialize().getStatus());
SchemaTypeConfigProto emailTypeConfig = createEmailTypeConfig();
SchemaProto schema = SchemaProto.newBuilder().addTypes(emailTypeConfig).build();
assertThat(
- icing
+ icingSearchEngine
.setSchema(schema, /*ignoreErrorsAndDeleteDocuments=*/ false)
.getStatus()
.getCode())
.isEqualTo(StatusProto.Code.OK);
DocumentProto emailDocument = createEmailDocument("namespace", "uri");
- assertStatusOk(icing.put(emailDocument).getStatus());
+ assertStatusOk(icingSearchEngine.put(emailDocument).getStatus());
DeleteBySchemaTypeResultProto deleteBySchemaTypeResultProto =
- icing.deleteBySchemaType(EMAIL_TYPE);
+ icingSearchEngine.deleteBySchemaType(EMAIL_TYPE);
assertStatusOk(deleteBySchemaTypeResultProto.getStatus());
- GetResultProto getResultProto = icing.get("namespace", "uri");
+ GetResultProto getResultProto = icingSearchEngine.get("namespace", "uri");
assertThat(getResultProto.getStatus().getCode()).isEqualTo(StatusProto.Code.NOT_FOUND);
}
-
@Test
public void testDeleteByQuery() throws Exception {
- IcingSearchEngineOptions options =
- IcingSearchEngineOptions.newBuilder().setBaseDir(tempDir.getCanonicalPath()).build();
- IcingSearchEngine icing = new IcingSearchEngine(options);
- assertStatusOk(icing.initialize().getStatus());
+ assertStatusOk(icingSearchEngine.initialize().getStatus());
SchemaTypeConfigProto emailTypeConfig = createEmailTypeConfig();
SchemaProto schema = SchemaProto.newBuilder().addTypes(emailTypeConfig).build();
assertThat(
- icing
- .setSchema(schema, /*ignoreErrorsAndDeleteDocuments=*/ false)
- .getStatus()
- .getCode())
+ icingSearchEngine
+ .setSchema(schema, /*ignoreErrorsAndDeleteDocuments=*/ false)
+ .getStatus()
+ .getCode())
.isEqualTo(StatusProto.Code.OK);
DocumentProto emailDocument1 =
createEmailDocument("namespace", "uri1").toBuilder()
- .addProperties(PropertyProto.newBuilder().setName("subject").addStringValues("foo"))
- .build();;
- assertStatusOk(icing.put(emailDocument1).getStatus());
+ .addProperties(PropertyProto.newBuilder().setName("subject").addStringValues("foo"))
+ .build();
+
+ assertStatusOk(icingSearchEngine.put(emailDocument1).getStatus());
DocumentProto emailDocument2 =
createEmailDocument("namespace", "uri2").toBuilder()
- .addProperties(PropertyProto.newBuilder().setName("subject").addStringValues("bar"))
- .build();;
- assertStatusOk(icing.put(emailDocument2).getStatus());
+ .addProperties(PropertyProto.newBuilder().setName("subject").addStringValues("bar"))
+ .build();
+
+ assertStatusOk(icingSearchEngine.put(emailDocument2).getStatus());
SearchSpecProto searchSpec =
SearchSpecProto.newBuilder()
@@ -378,7 +365,7 @@
.build();
SearchResultProto searchResultProto =
- icing.search(
+ icingSearchEngine.search(
searchSpec,
ScoringSpecProto.getDefaultInstance(),
ResultSpecProto.getDefaultInstance());
@@ -386,45 +373,36 @@
assertThat(searchResultProto.getResultsCount()).isEqualTo(1);
assertThat(searchResultProto.getResults(0).getDocument()).isEqualTo(emailDocument1);
- DeleteResultProto deleteResultProto = icing.deleteByQuery(searchSpec);
+ DeleteResultProto deleteResultProto = icingSearchEngine.deleteByQuery(searchSpec);
assertStatusOk(deleteResultProto.getStatus());
- GetResultProto getResultProto = icing.get("namespace", "uri1");
+ GetResultProto getResultProto = icingSearchEngine.get("namespace", "uri1");
assertThat(getResultProto.getStatus().getCode()).isEqualTo(StatusProto.Code.NOT_FOUND);
- getResultProto = icing.get("namespace", "uri2");
+ getResultProto = icingSearchEngine.get("namespace", "uri2");
assertStatusOk(getResultProto.getStatus());
}
@Test
public void testPersistToDisk() throws Exception {
- IcingSearchEngineOptions options =
- IcingSearchEngineOptions.newBuilder().setBaseDir(tempDir.getCanonicalPath()).build();
- IcingSearchEngine icing = new IcingSearchEngine(options);
- assertStatusOk(icing.initialize().getStatus());
+ assertStatusOk(icingSearchEngine.initialize().getStatus());
- PersistToDiskResultProto persistToDiskResultProto = icing.persistToDisk();
+ PersistToDiskResultProto persistToDiskResultProto = icingSearchEngine.persistToDisk();
assertStatusOk(persistToDiskResultProto.getStatus());
}
@Test
public void testOptimize() throws Exception {
- IcingSearchEngineOptions options =
- IcingSearchEngineOptions.newBuilder().setBaseDir(tempDir.getCanonicalPath()).build();
- IcingSearchEngine icing = new IcingSearchEngine(options);
- assertStatusOk(icing.initialize().getStatus());
+ assertStatusOk(icingSearchEngine.initialize().getStatus());
- OptimizeResultProto optimizeResultProto = icing.optimize();
+ OptimizeResultProto optimizeResultProto = icingSearchEngine.optimize();
assertStatusOk(optimizeResultProto.getStatus());
}
@Test
public void testGetOptimizeInfo() throws Exception {
- IcingSearchEngineOptions options =
- IcingSearchEngineOptions.newBuilder().setBaseDir(tempDir.getCanonicalPath()).build();
- IcingSearchEngine icing = new IcingSearchEngine(options);
- assertStatusOk(icing.initialize().getStatus());
+ assertStatusOk(icingSearchEngine.initialize().getStatus());
- GetOptimizeInfoResultProto getOptimizeInfoResultProto = icing.getOptimizeInfo();
+ GetOptimizeInfoResultProto getOptimizeInfoResultProto = icingSearchEngine.getOptimizeInfo();
assertStatusOk(getOptimizeInfoResultProto.getStatus());
assertThat(getOptimizeInfoResultProto.getOptimizableDocs()).isEqualTo(0);
assertThat(getOptimizeInfoResultProto.getEstimatedOptimizableBytes()).isEqualTo(0);
@@ -432,39 +410,63 @@
@Test
public void testGetAllNamespaces() throws Exception {
- IcingSearchEngineOptions options =
- IcingSearchEngineOptions.newBuilder().setBaseDir(tempDir.getCanonicalPath()).build();
- IcingSearchEngine icing = new IcingSearchEngine(options);
- assertStatusOk(icing.initialize().getStatus());
+ assertStatusOk(icingSearchEngine.initialize().getStatus());
SchemaTypeConfigProto emailTypeConfig = createEmailTypeConfig();
SchemaProto schema = SchemaProto.newBuilder().addTypes(emailTypeConfig).build();
assertThat(
- icing
- .setSchema(schema, /*ignoreErrorsAndDeleteDocuments=*/ false)
- .getStatus()
- .getCode())
+ icingSearchEngine
+ .setSchema(schema, /*ignoreErrorsAndDeleteDocuments=*/ false)
+ .getStatus()
+ .getCode())
.isEqualTo(StatusProto.Code.OK);
DocumentProto emailDocument = createEmailDocument("namespace", "uri");
- assertStatusOk(icing.put(emailDocument).getStatus());
+ assertStatusOk(icingSearchEngine.put(emailDocument).getStatus());
- GetAllNamespacesResultProto getAllNamespacesResultProto = icing.getAllNamespaces();
+ GetAllNamespacesResultProto getAllNamespacesResultProto = icingSearchEngine.getAllNamespaces();
assertStatusOk(getAllNamespacesResultProto.getStatus());
assertThat(getAllNamespacesResultProto.getNamespacesList()).containsExactly("namespace");
}
@Test
public void testReset() throws Exception {
- IcingSearchEngineOptions options =
- IcingSearchEngineOptions.newBuilder().setBaseDir(tempDir.getCanonicalPath()).build();
- IcingSearchEngine icing = new IcingSearchEngine(options);
- assertStatusOk(icing.initialize().getStatus());
+ assertStatusOk(icingSearchEngine.initialize().getStatus());
- ResetResultProto resetResultProto = icing.reset();
+ ResetResultProto resetResultProto = icingSearchEngine.reset();
assertStatusOk(resetResultProto.getStatus());
}
+ @Test
+ public void testReportUsage() throws Exception {
+ assertStatusOk(icingSearchEngine.initialize().getStatus());
+
+ // Set schema and put a document.
+ SchemaTypeConfigProto emailTypeConfig = createEmailTypeConfig();
+ SchemaProto schema = SchemaProto.newBuilder().addTypes(emailTypeConfig).build();
+ assertThat(
+ icingSearchEngine
+ .setSchema(schema, /*ignoreErrorsAndDeleteDocuments=*/ false)
+ .getStatus()
+ .getCode())
+ .isEqualTo(StatusProto.Code.OK);
+
+ DocumentProto emailDocument = createEmailDocument("namespace", "uri");
+ PutResultProto putResultProto = icingSearchEngine.put(emailDocument);
+ assertStatusOk(putResultProto.getStatus());
+
+ // Report usage
+ UsageReport usageReport =
+ UsageReport.newBuilder()
+ .setDocumentNamespace("namespace")
+ .setDocumentUri("uri")
+ .setUsageTimestampMs(1)
+ .setUsageType(UsageReport.UsageType.USAGE_TYPE1)
+ .build();
+ ReportUsageResultProto reportUsageResultProto = icingSearchEngine.reportUsage(usageReport);
+ assertStatusOk(reportUsageResultProto.getStatus());
+ }
+
private static void assertStatusOk(StatusProto status) {
assertWithMessage(status.getMessage()).that(status.getCode()).isEqualTo(StatusProto.Code.OK);
}