summaryrefslogtreecommitdiffstats
path: root/searchcore
diff options
context:
space:
mode:
authorTor Egge <Tor.Egge@broadpark.no>2017-03-01 12:24:44 +0100
committerGitHub <noreply@github.com>2017-03-01 12:24:44 +0100
commit0aed212b3b981b2b50c94444161ef6b33c1e57c1 (patch)
tree85838769ea0393e782017adfe21b9e91483c0e01 /searchcore
parentf1179b5e605a528e561b9ef98b41422b0a603dee (diff)
parentc4fc6b2a0d2fc097f94c38d0ebd3602ca0643d1d (diff)
Merge pull request #1893 from yahoo/geirst/attribute-context-for-imported-attributes
Geirst/attribute context for imported attributes
Diffstat (limited to 'searchcore')
-rw-r--r--searchcore/CMakeLists.txt1
-rw-r--r--searchcore/src/tests/proton/attribute/imported_attributes_context/CMakeLists.txt8
-rw-r--r--searchcore/src/tests/proton/attribute/imported_attributes_context/DESC1
-rw-r--r--searchcore/src/tests/proton/attribute/imported_attributes_context/FILES1
-rw-r--r--searchcore/src/tests/proton/attribute/imported_attributes_context/imported_attributes_context_test.cpp159
-rw-r--r--searchcore/src/tests/proton/attribute/imported_attributes_repo/imported_attributes_repo_test.cpp55
-rw-r--r--searchcore/src/tests/proton/reference/document_db_reference_resolver/document_db_reference_resolver_test.cpp12
-rw-r--r--searchcore/src/vespa/searchcore/proton/attribute/CMakeLists.txt1
-rw-r--r--searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_context.cpp94
-rw-r--r--searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_context.h69
-rw-r--r--searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_repo.cpp20
-rw-r--r--searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_repo.h15
-rw-r--r--searchcore/src/vespa/searchcore/proton/reference/document_db_reference_resolver.cpp23
-rw-r--r--searchcore/src/vespa/searchcore/proton/reference/document_db_reference_resolver.h22
14 files changed, 402 insertions, 79 deletions
diff --git a/searchcore/CMakeLists.txt b/searchcore/CMakeLists.txt
index b45c4b38058..4f6586d7404 100644
--- a/searchcore/CMakeLists.txt
+++ b/searchcore/CMakeLists.txt
@@ -67,6 +67,7 @@ vespa_define_module(
src/tests/proton/attribute/attributes_state_explorer
src/tests/proton/attribute/document_field_populator
src/tests/proton/attribute/exclusive_attribute_read_accessor
+ src/tests/proton/attribute/imported_attributes_context
src/tests/proton/attribute/imported_attributes_repo
src/tests/proton/bucketdb/bucketdb
src/tests/proton/common
diff --git a/searchcore/src/tests/proton/attribute/imported_attributes_context/CMakeLists.txt b/searchcore/src/tests/proton/attribute/imported_attributes_context/CMakeLists.txt
new file mode 100644
index 00000000000..58d0e87f53c
--- /dev/null
+++ b/searchcore/src/tests/proton/attribute/imported_attributes_context/CMakeLists.txt
@@ -0,0 +1,8 @@
+# Copyright 2017 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+vespa_add_executable(searchcore_imported_attributes_context_test_app TEST
+ SOURCES
+ imported_attributes_context_test.cpp
+ DEPENDS
+ searchcore_attribute
+)
+vespa_add_test(NAME searchcore_imported_attributes_context_test_app COMMAND searchcore_imported_attributes_context_test_app)
diff --git a/searchcore/src/tests/proton/attribute/imported_attributes_context/DESC b/searchcore/src/tests/proton/attribute/imported_attributes_context/DESC
new file mode 100644
index 00000000000..02050ecaf20
--- /dev/null
+++ b/searchcore/src/tests/proton/attribute/imported_attributes_context/DESC
@@ -0,0 +1 @@
+imported_attributes_context test. Take a look at imported_attributes_context_test.cpp for details.
diff --git a/searchcore/src/tests/proton/attribute/imported_attributes_context/FILES b/searchcore/src/tests/proton/attribute/imported_attributes_context/FILES
new file mode 100644
index 00000000000..6ff2c1b61f6
--- /dev/null
+++ b/searchcore/src/tests/proton/attribute/imported_attributes_context/FILES
@@ -0,0 +1 @@
+imported_attributes_context_test.cpp
diff --git a/searchcore/src/tests/proton/attribute/imported_attributes_context/imported_attributes_context_test.cpp b/searchcore/src/tests/proton/attribute/imported_attributes_context/imported_attributes_context_test.cpp
new file mode 100644
index 00000000000..6f6ef33e4f2
--- /dev/null
+++ b/searchcore/src/tests/proton/attribute/imported_attributes_context/imported_attributes_context_test.cpp
@@ -0,0 +1,159 @@
+// Copyright 2017 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#include <vespa/fastos/fastos.h>
+#include <vespa/log/log.h>
+LOG_SETUP("imported_attributes_context_test");
+#include <vespa/vespalib/testkit/testapp.h>
+
+#include <vespa/searchcore/proton/attribute/imported_attributes_context.h>
+#include <vespa/searchcore/proton/attribute/imported_attributes_repo.h>
+#include <vespa/searchlib/attribute/attribute.h>
+#include <vespa/searchlib/attribute/attributefactory.h>
+#include <vespa/searchlib/attribute/imported_attribute_vector.h>
+#include <thread>
+
+using namespace proton;
+using search::AttributeVector;
+using search::attribute::BasicType;
+using search::attribute::Config;
+using search::attribute::IAttributeVector;
+using search::attribute::ImportedAttributeVector;
+using search::attribute::ReferenceAttribute;
+using generation_t = AttributeVector::generation_t;
+
+ReferenceAttribute::SP
+createReferenceAttribute(const vespalib::string &name)
+{
+ return std::make_shared<ReferenceAttribute>(name, Config(BasicType::REFERENCE));
+}
+
+AttributeVector::SP
+createTargetAttribute(const vespalib::string &name)
+{
+ return search::AttributeFactory::createAttribute(name, Config(BasicType::STRING));
+}
+
+void
+addDoc(AttributeVector &attr)
+{
+ attr.addDocs(1);
+ attr.commit();
+}
+
+bool
+hasActiveEnumGuards(AttributeVector &attr)
+{
+ bool result;
+ std::thread thread([&result,&attr]() { result = attr.hasActiveEnumGuards(); });
+ thread.join();
+ return result;
+}
+
+void
+assertGuards(AttributeVector &attr, generation_t expCurrentGeneration, generation_t expFirstUsedGeneration, bool expHasActiveEnumGuards)
+{
+ EXPECT_EQUAL(expCurrentGeneration, attr.getCurrentGeneration());
+ EXPECT_EQUAL(expFirstUsedGeneration, attr.getFirstUsedGeneration());
+ EXPECT_EQUAL(expHasActiveEnumGuards, hasActiveEnumGuards(attr));
+}
+
+void
+addDocAndAssertGuards(AttributeVector &attr, generation_t expCurrentGeneration, generation_t expFirstUsedGeneration, bool expHasActiveEnumGuards)
+{
+ addDoc(attr);
+ assertGuards(attr, expCurrentGeneration, expFirstUsedGeneration, expHasActiveEnumGuards);
+}
+
+struct Fixture {
+ ImportedAttributesRepo repo;
+ std::unique_ptr<ImportedAttributesContext> ctx;
+ Fixture()
+ : repo(),
+ ctx(std::make_unique<ImportedAttributesContext>(repo))
+ {
+ }
+ Fixture &addAttribute(const vespalib::string &name) {
+ auto attr = std::make_shared<ImportedAttributeVector>(name,
+ createReferenceAttribute(name + "_ref"),
+ createTargetAttribute(name + "_target"));
+ repo.add(name, attr);
+ return *this;
+ }
+ AttributeVector::SP getTargetAttribute(const vespalib::string &importedName) const {
+ return repo.get(importedName)->getTargetAttribute();
+ }
+ void clearContext() {
+ ctx.reset();
+ }
+};
+
+TEST_F("require that attributes can be retrieved", Fixture)
+{
+ f.addAttribute("foo").addAttribute("bar");
+ EXPECT_EQUAL("foo", f.ctx->getAttribute("foo")->getName());
+ EXPECT_EQUAL("bar", f.ctx->getAttribute("bar")->getName());
+ EXPECT_EQUAL("bar", f.ctx->getAttribute("bar")->getName());
+ EXPECT_TRUE(f.ctx->getAttribute("not_found") == nullptr);
+}
+
+TEST_F("require that stable enum attributes can be retrieved", Fixture)
+{
+ f.addAttribute("foo").addAttribute("bar");
+ EXPECT_EQUAL("foo", f.ctx->getAttributeStableEnum("foo")->getName());
+ EXPECT_EQUAL("bar", f.ctx->getAttributeStableEnum("bar")->getName());
+ EXPECT_EQUAL("bar", f.ctx->getAttributeStableEnum("bar")->getName());
+ EXPECT_TRUE(f.ctx->getAttributeStableEnum("not_found") == nullptr);
+}
+
+TEST_F("require that all attributes can be retrieved", Fixture)
+{
+ f.addAttribute("foo").addAttribute("bar");
+ std::vector<const IAttributeVector *> list;
+ f.ctx->getAttributeList(list);
+ EXPECT_EQUAL(2u, list.size());
+ EXPECT_EQUAL("bar", list[0]->getName());
+ EXPECT_EQUAL("foo", list[1]->getName());
+}
+
+TEST_F("require that guards are cached", Fixture)
+{
+ f.addAttribute("foo");
+ auto targetAttr = f.getTargetAttribute("foo");
+ TEST_DO(addDocAndAssertGuards(*targetAttr, 2, 2, false));
+
+ f.ctx->getAttribute("foo"); // guard is taken and cached
+ TEST_DO(addDocAndAssertGuards(*targetAttr, 4, 2, false));
+
+ f.clearContext(); // guard is released
+ TEST_DO(addDocAndAssertGuards(*targetAttr, 6, 6, false));
+}
+
+TEST_F("require that stable enum guards are cached", Fixture)
+{
+ f.addAttribute("foo");
+ auto targetAttr = f.getTargetAttribute("foo");
+ TEST_DO(addDocAndAssertGuards(*targetAttr, 2, 2, false));
+
+ f.ctx->getAttributeStableEnum("foo"); // enum guard is taken and cached
+ TEST_DO(addDocAndAssertGuards(*targetAttr, 4, 2, true));
+
+ f.clearContext(); // guard is released
+ TEST_DO(addDocAndAssertGuards(*targetAttr, 6, 6, false));
+}
+
+TEST_F("require that stable enum guards can be released", Fixture)
+{
+ f.addAttribute("foo");
+ auto targetAttr = f.getTargetAttribute("foo");
+ TEST_DO(addDocAndAssertGuards(*targetAttr, 2, 2, false));
+
+ f.ctx->getAttributeStableEnum("foo"); // enum guard is taken and cached
+ TEST_DO(addDocAndAssertGuards(*targetAttr, 4, 2, true));
+
+ f.ctx->releaseEnumGuards();
+ TEST_DO(addDocAndAssertGuards(*targetAttr, 6, 6, false));
+}
+
+TEST_MAIN()
+{
+ TEST_RUN_ALL();
+}
diff --git a/searchcore/src/tests/proton/attribute/imported_attributes_repo/imported_attributes_repo_test.cpp b/searchcore/src/tests/proton/attribute/imported_attributes_repo/imported_attributes_repo_test.cpp
index f44004a3a2e..d9b4031e22f 100644
--- a/searchcore/src/tests/proton/attribute/imported_attributes_repo/imported_attributes_repo_test.cpp
+++ b/searchcore/src/tests/proton/attribute/imported_attributes_repo/imported_attributes_repo_test.cpp
@@ -4,46 +4,42 @@
LOG_SETUP("imported_attributes_repo_test");
#include <vespa/vespalib/testkit/testapp.h>
+#include <vespa/searchcommon/attribute/basictype.h>
#include <vespa/searchcommon/attribute/iattributevector.h>
#include <vespa/searchcore/proton/attribute/imported_attributes_repo.h>
-#include <vespa/searchlib/attribute/not_implemented_attribute.h>
-#include <vespa/searchcommon/attribute/basictype.h>
+#include <vespa/searchlib/attribute/imported_attribute_vector.h>
+#include <vespa/searchlib/attribute/reference_attribute.h>
using proton::ImportedAttributesRepo;
+using search::AttributeVector;
using search::attribute::BasicType;
using search::attribute::Config;
-using search::attribute::IAttributeVector;
-using search::NotImplementedAttribute;
-
-struct MyAttributeVector : public NotImplementedAttribute {
-private:
- virtual void onCommit() override {}
- virtual void onUpdateStat() override {}
+using search::attribute::ImportedAttributeVector;
+using search::attribute::ReferenceAttribute;
-public:
- MyAttributeVector(const vespalib::string &name)
- : NotImplementedAttribute(name, Config(BasicType::NONE))
- {}
- static IAttributeVector::SP create(const vespalib::string &name) {
- return std::make_shared<MyAttributeVector>(name);
- }
-};
+ImportedAttributeVector::SP
+createAttr(const vespalib::string &name)
+{
+ return std::make_shared<ImportedAttributeVector>(name,
+ ReferenceAttribute::SP(),
+ AttributeVector::SP());
+}
struct Fixture {
ImportedAttributesRepo repo;
Fixture() : repo() {}
- void add(IAttributeVector::SP attr) {
+ void add(ImportedAttributeVector::SP attr) {
repo.add(attr->getName(), attr);
}
- IAttributeVector::SP get(const vespalib::string &name) const {
+ ImportedAttributeVector::SP get(const vespalib::string &name) const {
return repo.get(name);
}
};
TEST_F("require that attributes can be added and retrieved", Fixture)
{
- IAttributeVector::SP fooAttr = MyAttributeVector::create("foo");
- IAttributeVector::SP barAttr = MyAttributeVector::create("bar");
+ ImportedAttributeVector::SP fooAttr = createAttr("foo");
+ ImportedAttributeVector::SP barAttr = createAttr("bar");
f.add(fooAttr);
f.add(barAttr);
EXPECT_EQUAL(2u, f.repo.size());
@@ -53,8 +49,8 @@ TEST_F("require that attributes can be added and retrieved", Fixture)
TEST_F("require that attribute can be replaced", Fixture)
{
- IAttributeVector::SP attr1 = MyAttributeVector::create("foo");
- IAttributeVector::SP attr2 = MyAttributeVector::create("foo");
+ ImportedAttributeVector::SP attr1 = createAttr("foo");
+ ImportedAttributeVector::SP attr2 = createAttr("foo");
f.add(attr1);
f.add(attr2);
EXPECT_EQUAL(1u, f.repo.size());
@@ -63,10 +59,21 @@ TEST_F("require that attribute can be replaced", Fixture)
TEST_F("require that not-found attribute returns nullptr", Fixture)
{
- IAttributeVector *notFound = nullptr;
+ ImportedAttributeVector *notFound = nullptr;
EXPECT_EQUAL(f.get("not_found").get(), notFound);
}
+TEST_F("require that all attributes can be retrieved", Fixture)
+{
+ f.add(createAttr("foo"));
+ f.add(createAttr("bar"));
+ std::vector<ImportedAttributeVector::SP> list;
+ f.repo.getAll(list);
+ EXPECT_EQUAL(2u, list.size());
+ EXPECT_EQUAL("bar", list[0]->getName());
+ EXPECT_EQUAL("foo", list[1]->getName());
+}
+
TEST_MAIN()
{
TEST_RUN_ALL();
diff --git a/searchcore/src/tests/proton/reference/document_db_reference_resolver/document_db_reference_resolver_test.cpp b/searchcore/src/tests/proton/reference/document_db_reference_resolver/document_db_reference_resolver_test.cpp
index 48311c9e509..187106a9818 100644
--- a/searchcore/src/tests/proton/reference/document_db_reference_resolver/document_db_reference_resolver_test.cpp
+++ b/searchcore/src/tests/proton/reference/document_db_reference_resolver/document_db_reference_resolver_test.cpp
@@ -6,15 +6,16 @@
#include <vespa/document/datatype/referencedatatype.h>
#include <vespa/log/log.h>
#include <vespa/searchcore/proton/attribute/imported_attributes_repo.h>
+#include <vespa/searchcore/proton/common/monitored_refcount.h>
#include <vespa/searchcore/proton/reference/document_db_reference_resolver.h>
+#include <vespa/searchcore/proton/reference/gid_to_lid_change_listener.h>
#include <vespa/searchcore/proton/reference/i_document_db_referent.h>
#include <vespa/searchcore/proton/reference/i_document_db_referent_registry.h>
#include <vespa/searchcore/proton/reference/i_gid_to_lid_change_listener.h>
-#include <vespa/searchcore/proton/reference/gid_to_lid_change_listener.h>
#include <vespa/searchcore/proton/test/mock_document_db_referent.h>
#include <vespa/searchcore/proton/test/mock_gid_to_lid_change_handler.h>
-#include <vespa/searchcore/proton/common/monitored_refcount.h>
#include <vespa/searchlib/attribute/attributefactory.h>
+#include <vespa/searchlib/attribute/imported_attribute_vector.h>
#include <vespa/searchlib/attribute/reference_attribute.h>
#include <vespa/searchlib/common/i_gid_to_lid_mapper.h>
#include <vespa/searchlib/common/i_gid_to_lid_mapper_factory.h>
@@ -233,12 +234,11 @@ struct Fixture {
void assertImportedAttribute(const vespalib::string &name,
const vespalib::string &referenceField,
const vespalib::string &targetField,
- IAttributeVector::SP attr) {
+ ImportedAttributeVector::SP attr) {
ASSERT_TRUE(attr.get());
EXPECT_EQUAL(name, attr->getName());
- const ImportedAttributeVector &importedAttr = asImportedAttribute(*attr);
- EXPECT_EQUAL(attrMgr.getReferenceAttribute(referenceField), importedAttr.getReferenceAttribute().get());
- EXPECT_EQUAL(parentReferent->getAttribute(targetField).get(), importedAttr.getTargetAttribute().get());
+ EXPECT_EQUAL(attrMgr.getReferenceAttribute(referenceField), attr->getReferenceAttribute().get());
+ EXPECT_EQUAL(parentReferent->getAttribute(targetField).get(), attr->getTargetAttribute().get());
}
MockGidToLidChangeHandler &getGidToLidChangeHandler(const vespalib::string &referencedDocTypeName) {
diff --git a/searchcore/src/vespa/searchcore/proton/attribute/CMakeLists.txt b/searchcore/src/vespa/searchcore/proton/attribute/CMakeLists.txt
index dc6b9c5e8d1..6e85cc79638 100644
--- a/searchcore/src/vespa/searchcore/proton/attribute/CMakeLists.txt
+++ b/searchcore/src/vespa/searchcore/proton/attribute/CMakeLists.txt
@@ -23,6 +23,7 @@ vespa_add_library(searchcore_attribute STATIC
exclusive_attribute_read_accessor.cpp
filter_attribute_manager.cpp
flushableattribute.cpp
+ imported_attributes_context.cpp
imported_attributes_repo.cpp
initialized_attributes_result.cpp
sequential_attributes_initializer.cpp
diff --git a/searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_context.cpp b/searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_context.cpp
new file mode 100644
index 00000000000..63ae28444d3
--- /dev/null
+++ b/searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_context.cpp
@@ -0,0 +1,94 @@
+// Copyright 2017 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#include <vespa/fastos/fastos.h>
+#include "imported_attributes_context.h"
+#include "imported_attributes_repo.h"
+#include <vespa/searchlib/attribute/attributeguard.h>
+#include <vespa/searchlib/attribute/imported_attribute_vector.h>
+#include <vespa/vespalib/stllike/hash_map.hpp>
+
+using search::attribute::IAttributeVector;
+using search::attribute::ImportedAttributeVector;
+using LockGuard = std::lock_guard<std::mutex>;
+
+namespace proton {
+
+ImportedAttributesContext::GuardedAttribute::GuardedAttribute(ImportedAttributeVector::SP attr,
+ bool stableEnumGuard)
+ : _attr(std::move(attr)),
+ _guard(stableEnumGuard ? _attr->acquireEnumGuard() : _attr->acquireGuard())
+{
+}
+
+ImportedAttributesContext::GuardedAttribute::~GuardedAttribute()
+{
+}
+
+const IAttributeVector *
+ImportedAttributesContext::GuardedAttribute::get() const
+{
+ return _attr.get();
+}
+
+const IAttributeVector *
+ImportedAttributesContext::getOrCacheAttribute(const vespalib::string &name,
+ AttributeCache &attributes,
+ bool stableEnumGuard,
+ const LockGuard &) const
+{
+ auto itr = attributes.find(name);
+ if (itr != attributes.end()) {
+ return itr->second.get();
+ }
+ ImportedAttributeVector::SP result = _repo.get(name);
+ if (result.get() != nullptr) {
+ attributes.emplace(name, GuardedAttribute(result, stableEnumGuard));
+ return result.get();
+ } else {
+ return nullptr;
+ }
+}
+
+ImportedAttributesContext::ImportedAttributesContext(const ImportedAttributesRepo &repo)
+ : _repo(repo),
+ _guardedAttributes(),
+ _enumGuardedAttributes(),
+ _cacheMutex()
+{
+}
+
+ImportedAttributesContext::~ImportedAttributesContext()
+{
+}
+
+const IAttributeVector *
+ImportedAttributesContext::getAttribute(const vespalib::string &name) const
+{
+ LockGuard guard(_cacheMutex);
+ return getOrCacheAttribute(name, _guardedAttributes, false, guard);
+}
+
+const IAttributeVector *
+ImportedAttributesContext::getAttributeStableEnum(const vespalib::string &name) const
+{
+ LockGuard guard(_cacheMutex);
+ return getOrCacheAttribute(name, _enumGuardedAttributes, true, guard);
+}
+
+void
+ImportedAttributesContext::getAttributeList(std::vector<const IAttributeVector *> &list) const
+{
+ std::vector<ImportedAttributeVector::SP> attributes;
+ _repo.getAll(attributes);
+ for (const auto &attr : attributes) {
+ list.push_back(getAttribute(attr->getName()));
+ }
+}
+
+void
+ImportedAttributesContext::releaseEnumGuards()
+{
+ LockGuard guard(_cacheMutex);
+ _enumGuardedAttributes.clear();
+}
+
+}
diff --git a/searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_context.h b/searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_context.h
new file mode 100644
index 00000000000..0fae4d015ce
--- /dev/null
+++ b/searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_context.h
@@ -0,0 +1,69 @@
+// Copyright 2017 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#pragma once
+
+#include <vespa/searchcommon/attribute/iattributecontext.h>
+#include <vespa/vespalib/stllike/hash_fun.h>
+#include <vespa/vespalib/stllike/hash_map.h>
+#include <mutex>
+#include <unordered_map>
+
+namespace search {
+class AttributeGuard;
+namespace attribute {
+class IAttributeVector;
+class ImportedAttributeVector;
+}}
+
+namespace proton {
+
+class ImportedAttributesRepo;
+
+/**
+ * Short lived context class that gives access to all imported attributes in a given repo.
+ *
+ * Attribute guards and enum guards are cached in this class and released upon destruction.
+ */
+class ImportedAttributesContext : public search::attribute::IAttributeContext {
+private:
+ using AttributeGuard = search::AttributeGuard;
+ using IAttributeVector = search::attribute::IAttributeVector;
+ using ImportedAttributeVector = search::attribute::ImportedAttributeVector;
+
+ class GuardedAttribute {
+ private:
+ std::shared_ptr<ImportedAttributeVector> _attr;
+ std::unique_ptr<AttributeGuard> _guard;
+
+ public:
+ GuardedAttribute(std::shared_ptr<ImportedAttributeVector> attr, bool stableEnumGuard);
+ ~GuardedAttribute();
+ GuardedAttribute(GuardedAttribute &&rhs) = default;
+ GuardedAttribute &operator=(GuardedAttribute &&rhs) = default;
+ const IAttributeVector *get() const;
+ };
+
+ using AttributeCache = std::unordered_map<vespalib::string, GuardedAttribute, vespalib::hash<vespalib::string>>;
+ using LockGuard = std::lock_guard<std::mutex>;
+
+ const ImportedAttributesRepo &_repo;
+ mutable AttributeCache _guardedAttributes;
+ mutable AttributeCache _enumGuardedAttributes;
+ mutable std::mutex _cacheMutex;
+
+ const IAttributeVector *getOrCacheAttribute(const vespalib::string &name,
+ AttributeCache &attributes,
+ bool stableEnumGuard,
+ const LockGuard &) const;
+
+public:
+ ImportedAttributesContext(const ImportedAttributesRepo &repo);
+ ~ImportedAttributesContext();
+
+ // Implements search::attribute::IAttributeContext
+ virtual const IAttributeVector *getAttribute(const vespalib::string &name) const override;
+ virtual const IAttributeVector *getAttributeStableEnum(const vespalib::string &name) const override;
+ virtual void getAttributeList(std::vector<const IAttributeVector *> &list) const override;
+ virtual void releaseEnumGuards() override;
+};
+
+}
diff --git a/searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_repo.cpp b/searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_repo.cpp
index 2e36a64069c..d7a87609995 100644
--- a/searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_repo.cpp
+++ b/searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_repo.cpp
@@ -1,11 +1,12 @@
// Copyright 2017 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include <vespa/fastos/fastos.h>
#include "imported_attributes_repo.h"
-#include <vespa/searchcommon/attribute/iattributevector.h>
+#include <vespa/searchlib/attribute/imported_attribute_vector.h>
+#include <vespa/vespalib/stllike/hash_map.hpp>
namespace proton {
-using search::attribute::IAttributeVector;
+using search::attribute::ImportedAttributeVector;
ImportedAttributesRepo::ImportedAttributesRepo()
: _repo()
@@ -18,19 +19,28 @@ ImportedAttributesRepo::~ImportedAttributesRepo()
void
ImportedAttributesRepo::add(const vespalib::string &name,
- IAttributeVector::SP attr)
+ ImportedAttributeVector::SP attr)
{
_repo[name] = std::move(attr);
}
-IAttributeVector::SP
+ImportedAttributeVector::SP
ImportedAttributesRepo::get(const vespalib::string &name) const
{
auto itr = _repo.find(name);
if (itr != _repo.end()) {
return itr->second;
}
- return IAttributeVector::SP();
+ return ImportedAttributeVector::SP();
+}
+
+void
+ImportedAttributesRepo::getAll(std::vector<std::shared_ptr<ImportedAttributeVector>> &result) const
+{
+ result.reserve(_repo.size());
+ for (const auto &itr : _repo) {
+ result.push_back(itr.second);
+ }
}
}
diff --git a/searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_repo.h b/searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_repo.h
index 5a776dfb057..497773722e8 100644
--- a/searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_repo.h
+++ b/searchcore/src/vespa/searchcore/proton/attribute/imported_attributes_repo.h
@@ -1,11 +1,11 @@
// Copyright 2017 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once
-#include <map>
+#include <vespa/vespalib/stllike/hash_map.h>
#include <vespa/vespalib/stllike/string.h>
+#include <vector>
-namespace search {
-namespace attribute { class IAttributeVector; } }
+namespace search { namespace attribute { class ImportedAttributeVector; } }
namespace proton {
@@ -14,8 +14,8 @@ namespace proton {
*/
class ImportedAttributesRepo {
private:
- using IAttributeVector = search::attribute::IAttributeVector;
- using Repo = std::map<vespalib::string, std::shared_ptr<IAttributeVector>>;
+ using ImportedAttributeVector = search::attribute::ImportedAttributeVector;
+ using Repo = vespalib::hash_map<vespalib::string, std::shared_ptr<ImportedAttributeVector>>;
Repo _repo;
@@ -23,8 +23,9 @@ public:
using UP = std::unique_ptr<ImportedAttributesRepo>;
ImportedAttributesRepo();
~ImportedAttributesRepo();
- void add(const vespalib::string &name, std::shared_ptr<IAttributeVector> attr);
- std::shared_ptr<IAttributeVector> get(const vespalib::string &name) const;
+ void add(const vespalib::string &name, std::shared_ptr<ImportedAttributeVector> attr);
+ std::shared_ptr<ImportedAttributeVector> get(const vespalib::string &name) const;
+ void getAll(std::vector<std::shared_ptr<ImportedAttributeVector>> &result) const;
size_t size() const { return _repo.size(); }
};
diff --git a/searchcore/src/vespa/searchcore/proton/reference/document_db_reference_resolver.cpp b/searchcore/src/vespa/searchcore/proton/reference/document_db_reference_resolver.cpp
index c55e73c6f30..52fe6271041 100644
--- a/searchcore/src/vespa/searchcore/proton/reference/document_db_reference_resolver.cpp
+++ b/searchcore/src/vespa/searchcore/proton/reference/document_db_reference_resolver.cpp
@@ -2,18 +2,19 @@
#include <vespa/fastos/fastos.h>
#include "document_db_reference_resolver.h"
-#include "i_document_db_referent_registry.h"
+#include "gid_to_lid_change_listener.h"
+#include "gid_to_lid_change_registrator.h"
#include "i_document_db_referent.h"
+#include "i_document_db_referent_registry.h"
#include <vespa/config-imported-fields.h>
#include <vespa/document/datatype/documenttype.h>
#include <vespa/document/datatype/referencedatatype.h>
#include <vespa/document/repo/documenttyperepo.h>
+#include <vespa/searchcommon/attribute/iattributevector.h>
#include <vespa/searchcore/proton/attribute/imported_attributes_repo.h>
#include <vespa/searchlib/attribute/iattributemanager.h>
+#include <vespa/searchlib/attribute/imported_attribute_vector.h>
#include <vespa/searchlib/attribute/reference_attribute.h>
-#include <vespa/searchcommon/attribute/iattributevector.h>
-#include "gid_to_lid_change_registrator.h"
-#include "gid_to_lid_change_listener.h"
using document::DataType;
using document::DocumentType;
@@ -22,6 +23,7 @@ using document::ReferenceDataType;
using search::attribute::BasicType;
using search::attribute::Config;
using search::attribute::IAttributeVector;
+using search::attribute::ImportedAttributeVector;
using search::attribute::ReferenceAttribute;
using search::AttributeGuard;
using search::AttributeVector;
@@ -73,15 +75,6 @@ getReferenceAttributes(const IAttributeManager &attrMgr)
}
-ImportedAttributeVector::ImportedAttributeVector(vespalib::stringref name,
- ReferenceAttribute::SP refAttr,
- IAttributeVector::SP targetAttr)
- : NotImplementedAttribute(name, Config(targetAttr->getBasicType(), targetAttr->getCollectionType())),
- _refAttr(std::move(refAttr)),
- _targetAttr(std::move(targetAttr))
-{
-}
-
GidToLidChangeRegistrator &
DocumentDBReferenceResolver::getRegistrator(const vespalib::string &docTypeName)
{
@@ -148,8 +141,8 @@ DocumentDBReferenceResolver::createImportedAttributesRepo(const IAttributeManage
auto result = std::make_unique<ImportedAttributesRepo>();
for (const auto &attr : _importedFieldsCfg.attribute) {
ReferenceAttribute::SP refAttr = getReferenceAttribute(attr.referencefield, attrMgr);
- IAttributeVector::SP targetAttr = getTargetDocumentDB(refAttr->getName())->getAttribute(attr.targetfield);
- IAttributeVector::SP importedAttr = std::make_shared<ImportedAttributeVector>(attr.name, refAttr, targetAttr);
+ AttributeVector::SP targetAttr = getTargetDocumentDB(refAttr->getName())->getAttribute(attr.targetfield);
+ ImportedAttributeVector::SP importedAttr = std::make_shared<ImportedAttributeVector>(attr.name, refAttr, targetAttr);
result->add(importedAttr->getName(), importedAttr);
}
return result;
diff --git a/searchcore/src/vespa/searchcore/proton/reference/document_db_reference_resolver.h b/searchcore/src/vespa/searchcore/proton/reference/document_db_reference_resolver.h
index 6096b27ceaa..c5af076b624 100644
--- a/searchcore/src/vespa/searchcore/proton/reference/document_db_reference_resolver.h
+++ b/searchcore/src/vespa/searchcore/proton/reference/document_db_reference_resolver.h
@@ -53,26 +53,4 @@ public:
virtual void teardown(const search::IAttributeManager &oldAttrMgr) override;
};
-/**
- * Temporary placeholder for an imported attribute vector.
- * TODO: Remove when search::attribute::ImportedAttributeVector is finished
- */
-class ImportedAttributeVector : public search::NotImplementedAttribute {
-private:
- vespalib::string _name;
- std::shared_ptr<search::attribute::ReferenceAttribute> _refAttr;
- std::shared_ptr<search::attribute::IAttributeVector> _targetAttr;
-
- virtual void onCommit() override {}
- virtual void onUpdateStat() override {}
-
-public:
- ImportedAttributeVector(vespalib::stringref name,
- std::shared_ptr<search::attribute::ReferenceAttribute> refAttr,
- std::shared_ptr<search::attribute::IAttributeVector> targetAttr);
-
- std::shared_ptr<search::attribute::ReferenceAttribute> getReferenceAttribute() const { return _refAttr; }
- std::shared_ptr<search::attribute::IAttributeVector> getTargetAttribute() const { return _targetAttr; }
-};
-
}