summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTor Egge <Tor.Egge@yahoo-inc.com>2017-02-17 13:57:57 +0000
committerTor Egge <Tor.Egge@yahoo-inc.com>2017-02-17 13:57:57 +0000
commitfefc3be06342f0ba2cadb5c28595faa00c94fcb6 (patch)
tree5a8f7075cb10400e0574afd627fd8da96076b575
parent1e128ce03e253e69e8bf1145e595fcddf88465a0 (diff)
Add notifyGidToLidChange() method to reference attribute, to handle
information about changed gid to lid mapping.
-rw-r--r--searchlib/src/tests/attribute/reference_attribute/reference_attribute_test.cpp32
-rw-r--r--searchlib/src/vespa/searchlib/attribute/reference_attribute.cpp8
-rw-r--r--searchlib/src/vespa/searchlib/attribute/reference_attribute.h4
-rw-r--r--searchlib/src/vespa/searchlib/datastore/unique_store.h1
-rw-r--r--searchlib/src/vespa/searchlib/datastore/unique_store.hpp13
5 files changed, 57 insertions, 1 deletions
diff --git a/searchlib/src/tests/attribute/reference_attribute/reference_attribute_test.cpp b/searchlib/src/tests/attribute/reference_attribute/reference_attribute_test.cpp
index df967c6b171..61ac12e634f 100644
--- a/searchlib/src/tests/attribute/reference_attribute/reference_attribute_test.cpp
+++ b/searchlib/src/tests/attribute/reference_attribute/reference_attribute_test.cpp
@@ -112,6 +112,10 @@ struct Fixture
}
}
+ const ReferenceAttribute::Reference *getRef(uint32_t doc) {
+ return _attr->getReference(doc);
+ }
+
void set(uint32_t doc, const GlobalId &gid) {
_attr->update(doc, gid);
}
@@ -133,6 +137,12 @@ struct Fixture
EXPECT_EQUAL(toGid(str), *gid);
}
+ void assertRefLid(uint32_t expLid, uint32_t doc) {
+ auto ref = getRef(doc);
+ EXPECT_TRUE(ref != nullptr);
+ EXPECT_EQUAL(expLid, ref->lid());
+ }
+
void save() {
attr().save();
}
@@ -165,6 +175,10 @@ struct Fixture
uint32_t referencedDoc = _attr->getReferencedLid(doc);
EXPECT_EQUAL(expReferencedDoc, referencedDoc);
}
+
+ void notifyGidToLidChange(const GlobalId &gid, uint32_t referencedDoc) {
+ _attr->notifyGidToLidChange(gid, referencedDoc);
+ }
};
TEST_F("require that we can instantiate reference attribute", Fixture)
@@ -277,4 +291,22 @@ TEST_F("require that we can use gid mapper", Fixture)
TEST_DO(f.assertReferencedLid(5, 0));
}
+TEST_F("require that notifyGidToLidChange works", Fixture)
+{
+ f.ensureDocIdLimit(4);
+ f.set(1, toGid(doc1));
+ f.set(2, toGid(doc2));
+ f.set(3, toGid(doc1));
+ f.commit();
+ TEST_DO(f.assertRefLid(0, 1));
+ TEST_DO(f.assertRefLid(0, 2));
+ TEST_DO(f.assertRefLid(0, 3));
+ f.notifyGidToLidChange(toGid(doc1), 10);
+ f.notifyGidToLidChange(toGid(doc2), 20);
+ f.notifyGidToLidChange(toGid(doc3), 30);
+ TEST_DO(f.assertRefLid(10, 1));
+ TEST_DO(f.assertRefLid(20, 2));
+ TEST_DO(f.assertRefLid(10, 3));
+}
+
TEST_MAIN() { TEST_RUN_ALL(); }
diff --git a/searchlib/src/vespa/searchlib/attribute/reference_attribute.cpp b/searchlib/src/vespa/searchlib/attribute/reference_attribute.cpp
index 8cf8dc83b4b..b3cfdbde054 100644
--- a/searchlib/src/vespa/searchlib/attribute/reference_attribute.cpp
+++ b/searchlib/src/vespa/searchlib/attribute/reference_attribute.cpp
@@ -250,6 +250,14 @@ ReferenceAttribute::getReferencedLid(DocId doc) const
return mapper->mapGidToLid(_store.get(oldRef).gid());
}
+void
+ReferenceAttribute::notifyGidToLidChange(const GlobalId &gid, DocId referencedLid)
+{
+ EntryRef ref = _store.find(gid);
+ if (ref.valid()) {
+ _store.get(ref).setLid(referencedLid);
+ }
+}
IMPLEMENT_IDENTIFIABLE_ABSTRACT(ReferenceAttribute, AttributeVector);
diff --git a/searchlib/src/vespa/searchlib/attribute/reference_attribute.h b/searchlib/src/vespa/searchlib/attribute/reference_attribute.h
index 091d5c2bcab..1d7c53f83a1 100644
--- a/searchlib/src/vespa/searchlib/attribute/reference_attribute.h
+++ b/searchlib/src/vespa/searchlib/attribute/reference_attribute.h
@@ -24,7 +24,7 @@ public:
using GlobalId = document::GlobalId;
class Reference {
GlobalId _gid;
- uint32_t _lid;
+ mutable uint32_t _lid;
public:
Reference()
: _gid(),
@@ -41,6 +41,7 @@ public:
}
const GlobalId &gid() const { return _gid; }
uint32_t lid() const { return _lid; }
+ void setLid(uint32_t referencedLid) const { _lid = referencedLid; }
};
using Store = datastore::UniqueStore<Reference>;
using IndicesCopyVector = vespalib::Array<EntryRef>;
@@ -74,6 +75,7 @@ public:
const Reference *getReference(DocId doc);
void setGidToLidMapperFactory(std::shared_ptr<IGidToLidMapperFactory> gidToLidMapperFactory);
DocId getReferencedLid(DocId doc) const;
+ void notifyGidToLidChange(const GlobalId &gid, DocId referencedLid);
};
}
diff --git a/searchlib/src/vespa/searchlib/datastore/unique_store.h b/searchlib/src/vespa/searchlib/datastore/unique_store.h
index 90e31a3fa62..a82752977be 100644
--- a/searchlib/src/vespa/searchlib/datastore/unique_store.h
+++ b/searchlib/src/vespa/searchlib/datastore/unique_store.h
@@ -91,6 +91,7 @@ public:
~UniqueStore();
EntryRef move(EntryRef ref);
AddResult add(const EntryType &value);
+ EntryRef find(const EntryType &value);
const EntryType &get(EntryRef ref) const
{
RefType iRef(ref);
diff --git a/searchlib/src/vespa/searchlib/datastore/unique_store.hpp b/searchlib/src/vespa/searchlib/datastore/unique_store.hpp
index 2ec05ee9248..388adf98105 100644
--- a/searchlib/src/vespa/searchlib/datastore/unique_store.hpp
+++ b/searchlib/src/vespa/searchlib/datastore/unique_store.hpp
@@ -61,6 +61,19 @@ UniqueStore<EntryT, RefT>::add(const EntryType &value)
template <typename EntryT, typename RefT>
EntryRef
+UniqueStore<EntryT, RefT>::find(const EntryType &value)
+{
+ Compare comp(_store, value);
+ auto itr = _dict.lowerBound(RefType(), comp);
+ if (itr.valid() && !comp(EntryRef(), itr.getKey())) {
+ return itr.getKey();
+ } else {
+ return EntryRef();
+ }
+}
+
+template <typename EntryT, typename RefT>
+EntryRef
UniqueStore<EntryT, RefT>::move(EntryRef ref)
{
return _store.template allocator<EntryType>(_typeId).alloc(get(ref)).ref;