summaryrefslogtreecommitdiffstats
path: root/searchcore
diff options
context:
space:
mode:
authorGeir Storli <geirst@verizonmedia.com>2019-03-08 10:06:00 +0000
committerGeir Storli <geirst@verizonmedia.com>2019-03-08 13:22:36 +0000
commit659032d48faba60fc59224c702d19a24a99ca1c7 (patch)
tree1baabbc2dcf8fdb14684d53e48bfa50605d1990d /searchcore
parent4d5ac042bb2e463a87f652b34ec3f5e89747240a (diff)
Optimize updates to tensor attributes by only updating them in-memory and no longer go via the document store.
This makes tensor attributes behave as regular attributes. Reprocessing is updated to correctly handle adding and removal of attribute aspect.
Diffstat (limited to 'searchcore')
-rw-r--r--searchcore/src/tests/proton/attribute/attribute_aspect_delayer/attribute_aspect_delayer_test.cpp28
-rw-r--r--searchcore/src/tests/proton/documentdb/feedview/feedview_test.cpp43
-rw-r--r--searchcore/src/tests/proton/reprocessing/attribute_reprocessing_initializer/attribute_reprocessing_initializer_test.cpp17
-rw-r--r--searchcore/src/vespa/searchcore/proton/attribute/attribute_aspect_delayer.cpp1
-rw-r--r--searchcore/src/vespa/searchcore/proton/reprocessing/attribute_reprocessing_initializer.cpp3
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.cpp4
6 files changed, 55 insertions, 41 deletions
diff --git a/searchcore/src/tests/proton/attribute/attribute_aspect_delayer/attribute_aspect_delayer_test.cpp b/searchcore/src/tests/proton/attribute/attribute_aspect_delayer/attribute_aspect_delayer_test.cpp
index a9e8cbf9675..7141dc7baf7 100644
--- a/searchcore/src/tests/proton/attribute/attribute_aspect_delayer/attribute_aspect_delayer_test.cpp
+++ b/searchcore/src/tests/proton/attribute/attribute_aspect_delayer/attribute_aspect_delayer_test.cpp
@@ -204,7 +204,7 @@ public:
void assertAttributeConfig(const std::vector<AttributesConfig::Attribute> &exp)
{
auto actConfig = _delayer.getAttributesConfig();
- EXPECT_TRUE(exp == actConfig->attribute);
+ EXPECT_EQ(exp, actConfig->attribute);
}
void assertSummarymapConfig(const std::vector<SummarymapConfig::Override> &exp)
{
@@ -290,14 +290,24 @@ TEST_F(DelayerTest, require_that_removing_attribute_aspect_is_not_delayed_if_als
assertSummarymapConfig({});
}
-TEST_F(DelayerTest, require_that_removing_attribute_aspect_is_not_delayed_for_tensor)
+TEST_F(DelayerTest, require_that_adding_attribute_aspect_is_delayed_for_tensor_field)
{
addFields({"a"});
- setup(attrCfg({make_tensor_cfg("tensor(x[10])")}), smCfg({make_attribute_override("a")}), attrCfg({}), sCfg({make_summary_field("a", "tensor")}), smCfg({}));
+ setup(attrCfg({}), smCfg({}),
+ attrCfg({make_tensor_cfg("tensor(x[10])")}), sCfg({make_summary_field("a", "tensor")}), smCfg({make_attribute_override("a")}));
assertAttributeConfig({});
assertSummarymapConfig({});
}
+TEST_F(DelayerTest, require_that_removing_attribute_aspect_is_delayed_for_tensor_field)
+{
+ addFields({"a"});
+ setup(attrCfg({make_tensor_cfg("tensor(x[10])")}), smCfg({make_attribute_override("a")}),
+ attrCfg({}), sCfg({make_summary_field("a", "tensor")}), smCfg({}));
+ assertAttributeConfig({make_tensor_cfg("tensor(x[10])")});
+ assertSummarymapConfig({make_attribute_override("a")});
+}
+
TEST_F(DelayerTest, require_that_removing_attribute_aspect_is_not_delayed_for_predicate)
{
addFields({"a"});
@@ -330,19 +340,21 @@ TEST_F(DelayerTest, require_that_fast_access_flag_change_is_delayed_true_false_e
assertSummarymapConfig({make_attribute_override("a")});
}
-TEST_F(DelayerTest, require_that_fast_access_flag_change_is_delayed_false_true_edge_on_tensor_attr)
+TEST_F(DelayerTest, require_that_fast_access_flag_change_is_delayed_false_true_edge_on_tensor_attribute)
{
addFields({"a"});
- setup(attrCfg({make_tensor_cfg("tensor(x[10])")}), smCfg({make_attribute_override("a")}), attrCfg({make_fa(make_tensor_cfg("tensor(x[10])"))}), sCfg({make_summary_field("a", "tensor")}), smCfg({make_attribute_override("a")}));
+ setup(attrCfg({make_tensor_cfg("tensor(x[10])")}), smCfg({make_attribute_override("a")}),
+ attrCfg({make_fa(make_tensor_cfg("tensor(x[10])"))}), sCfg({make_summary_field("a", "tensor")}), smCfg({make_attribute_override("a")}));
assertAttributeConfig({make_tensor_cfg("tensor(x[10])")});
assertSummarymapConfig({make_attribute_override("a")});
}
-TEST_F(DelayerTest, require_that_fast_access_flag_change_is_not_delayed_true_false_edge_on_tensor_attr)
+TEST_F(DelayerTest, require_that_fast_access_flag_change_is_delayed_true_false_edge_on_tensor_attribute)
{
addFields({"a"});
- setup(attrCfg({make_fa(make_tensor_cfg("tensor(x[10])"))}), smCfg({make_attribute_override("a")}), attrCfg({make_tensor_cfg("tensor(x[10])")}), sCfg({make_summary_field("a", "tensor")}), smCfg({make_attribute_override("a")}));
- assertAttributeConfig({make_tensor_cfg("tensor(x[10])")});
+ setup(attrCfg({make_fa(make_tensor_cfg("tensor(x[10])"))}), smCfg({make_attribute_override("a")}),
+ attrCfg({make_tensor_cfg("tensor(x[10])")}), sCfg({make_summary_field("a", "tensor")}), smCfg({make_attribute_override("a")}));
+ assertAttributeConfig({make_fa(make_tensor_cfg("tensor(x[10])"))});
assertSummarymapConfig({make_attribute_override("a")});
}
diff --git a/searchcore/src/tests/proton/documentdb/feedview/feedview_test.cpp b/searchcore/src/tests/proton/documentdb/feedview/feedview_test.cpp
index 0f9df1fc594..fd1984a79fe 100644
--- a/searchcore/src/tests/proton/documentdb/feedview/feedview_test.cpp
+++ b/searchcore/src/tests/proton/documentdb/feedview/feedview_test.cpp
@@ -1070,46 +1070,43 @@ void putDocumentAndUpdate(Fixture &f, const vespalib::string &fieldName)
}
template <typename Fixture>
-void requireThatUpdateOnlyUpdatesAttributeAndNotDocumentStore(Fixture &f)
+void requireThatUpdateOnlyUpdatesAttributeAndNotDocumentStore(Fixture &f,
+ const vespalib::string &fieldName)
{
- putDocumentAndUpdate(f, "a1");
+ putDocumentAndUpdate(f, fieldName);
EXPECT_EQUAL(1u, f.msa._store._lastSyncToken); // document store not updated
assertAttributeUpdate(2u, DocumentId("doc:test:1"), 1, f.maw);
}
+template <typename Fixture>
+void requireThatUpdateUpdatesAttributeAndDocumentStore(Fixture &f,
+ const vespalib::string &fieldName)
+{
+ putDocumentAndUpdate(f, fieldName);
+
+ EXPECT_EQUAL(2u, f.msa._store._lastSyncToken); // document store updated
+ assertAttributeUpdate(2u, DocumentId("doc:test:1"), 1, f.maw);
+}
+
TEST_F("require that update() to fast-access attribute only updates attribute and not document store",
FastAccessFeedViewFixture)
{
f.maw._attrs.insert("a1"); // mark a1 as fast-access attribute field
- requireThatUpdateOnlyUpdatesAttributeAndNotDocumentStore(f);
+ requireThatUpdateOnlyUpdatesAttributeAndNotDocumentStore(f, "a1");
}
TEST_F("require that update() to attribute only updates attribute and not document store",
SearchableFeedViewFixture)
{
f.maw._attrs.insert("a1"); // mark a1 as attribute field
- requireThatUpdateOnlyUpdatesAttributeAndNotDocumentStore(f);
+ requireThatUpdateOnlyUpdatesAttributeAndNotDocumentStore(f, "a1");
}
TEST_F("require that update to non fast-access attribute also updates document store",
FastAccessFeedViewFixture)
{
- putDocumentAndUpdate(f, "a1");
-
- EXPECT_EQUAL(2u, f.msa._store._lastSyncToken); // document store updated
- assertAttributeUpdate(2u, DocumentId("doc:test:1"), 1, f.maw);
-}
-
-template <typename Fixture>
-void requireThatUpdateUpdatesAttributeAndDocumentStore(Fixture &f,
- const vespalib::string &
- fieldName)
-{
- putDocumentAndUpdate(f, fieldName);
-
- EXPECT_EQUAL(2u, f.msa._store._lastSyncToken); // document store updated
- assertAttributeUpdate(2u, DocumentId("doc:test:1"), 1, f.maw);
+ requireThatUpdateUpdatesAttributeAndDocumentStore(f, "a1");
}
TEST_F("require that update() to fast-access predicate attribute updates attribute and document store",
@@ -1126,18 +1123,18 @@ TEST_F("require that update() to predicate attribute updates attribute and docum
requireThatUpdateUpdatesAttributeAndDocumentStore(f, "a2");
}
-TEST_F("require that update() to fast-access tensor attribute updates attribute and document store",
+TEST_F("require that update() to fast-access tensor attribute only updates attribute and NOT document store",
FastAccessFeedViewFixture)
{
f.maw._attrs.insert("a3"); // mark a3 as fast-access attribute field
- requireThatUpdateUpdatesAttributeAndDocumentStore(f, "a3");
+ requireThatUpdateOnlyUpdatesAttributeAndNotDocumentStore(f, "a3");
}
-TEST_F("require that update() to tensor attribute updates attribute and document store",
+TEST_F("require that update() to tensor attribute only updates attribute and NOT document store",
SearchableFeedViewFixture)
{
f.maw._attrs.insert("a3"); // mark a3 as attribute field
- requireThatUpdateUpdatesAttributeAndDocumentStore(f, "a3");
+ requireThatUpdateOnlyUpdatesAttributeAndNotDocumentStore(f, "a3");
}
TEST_F("require that compactLidSpace() propagates to document meta store and document store and "
diff --git a/searchcore/src/tests/proton/reprocessing/attribute_reprocessing_initializer/attribute_reprocessing_initializer_test.cpp b/searchcore/src/tests/proton/reprocessing/attribute_reprocessing_initializer/attribute_reprocessing_initializer_test.cpp
index 868c26deff8..95cbdafb8e4 100644
--- a/searchcore/src/tests/proton/reprocessing/attribute_reprocessing_initializer/attribute_reprocessing_initializer_test.cpp
+++ b/searchcore/src/tests/proton/reprocessing/attribute_reprocessing_initializer/attribute_reprocessing_initializer_test.cpp
@@ -266,11 +266,20 @@ TEST_F(InitializerTest, require_that_initializer_can_setup_both_attribute_and_do
assertFields({"a"});
}
-TEST_F(InitializerTest, require_that_tensor_fields_are_not_populated_from_attribute)
+TEST_F(InitializerTest, require_that_adding_attribute_aspect_on_tensor_field_require_attribute_populate)
{
- addOldConfig({"a", "b", "c", "d", "tensor"}, {"a", "b", "c", "d", "tensor"}).
- addNewConfig({"a", "b", "c", "d", "tensor"}, {"a", "b"}).init();
- assertFields({"c", "d"});
+ addOldConfig({"tensor"}, {}).
+ addNewConfig({"tensor"}, {"tensor"}).init();
+ assertAttributes({"tensor"});
+ assertFields({});
+}
+
+TEST_F(InitializerTest, require_that_removing_attribute_aspect_from_tensor_field_require_document_field_populate)
+{
+ addOldConfig({"tensor"}, {"tensor"}).
+ addNewConfig({"tensor"}, {}).init();
+ assertAttributes({});
+ assertFields({"tensor"});
}
TEST_F(InitializerTest, require_that_predicate_fields_are_not_populated_from_attribute)
diff --git a/searchcore/src/vespa/searchcore/proton/attribute/attribute_aspect_delayer.cpp b/searchcore/src/vespa/searchcore/proton/attribute/attribute_aspect_delayer.cpp
index 4cf2df97fd0..cbf4729cb9d 100644
--- a/searchcore/src/vespa/searchcore/proton/attribute/attribute_aspect_delayer.cpp
+++ b/searchcore/src/vespa/searchcore/proton/attribute/attribute_aspect_delayer.cpp
@@ -27,7 +27,6 @@ using AttributesConfigHash = ConfigHash<AttributesConfig::Attribute>;
bool fastPartialUpdateAttribute(const search::attribute::Config &cfg) {
auto basicType = cfg.basicType().type();
return ((basicType != BasicType::Type::PREDICATE) &&
- (basicType != BasicType::Type::TENSOR) &&
(basicType != BasicType::Type::REFERENCE));
}
diff --git a/searchcore/src/vespa/searchcore/proton/reprocessing/attribute_reprocessing_initializer.cpp b/searchcore/src/vespa/searchcore/proton/reprocessing/attribute_reprocessing_initializer.cpp
index afae967c4fb..bee6cee1cb6 100644
--- a/searchcore/src/vespa/searchcore/proton/reprocessing/attribute_reprocessing_initializer.cpp
+++ b/searchcore/src/vespa/searchcore/proton/reprocessing/attribute_reprocessing_initializer.cpp
@@ -32,9 +32,8 @@ toStr(bool value)
}
bool fastPartialUpdateAttribute(BasicType::Type attrType) {
- // Partial update to tensor or predicate attribute must update document
+ // Partial update to predicate or reference attribute must update document
return ((attrType != BasicType::Type::PREDICATE) &&
- (attrType != BasicType::Type::TENSOR) &&
(attrType != BasicType::Type::REFERENCE));
}
diff --git a/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.cpp b/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.cpp
index 59b9a655d2a..3dc6ae404ff 100644
--- a/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.cpp
@@ -401,10 +401,8 @@ namespace {
bool isAttributeUpdateable(const search::AttributeVector *attribute) {
search::attribute::BasicType::Type attrType = attribute->getBasicType();
- // Partial update to tensor, predicate or reference attribute
- // must update document
+ // Partial update to predicate or reference attribute must update document
return ((attrType != search::attribute::BasicType::Type::PREDICATE) &&
- (attrType != search::attribute::BasicType::Type::TENSOR) &&
(attrType != search::attribute::BasicType::Type::REFERENCE));
}
}