diff options
author | Tor Egge <Tor.Egge@yahoo-inc.com> | 2017-02-17 13:57:57 +0000 |
---|---|---|
committer | Tor Egge <Tor.Egge@yahoo-inc.com> | 2017-02-17 13:57:57 +0000 |
commit | fefc3be06342f0ba2cadb5c28595faa00c94fcb6 (patch) | |
tree | 5a8f7075cb10400e0574afd627fd8da96076b575 | |
parent | 1e128ce03e253e69e8bf1145e595fcddf88465a0 (diff) |
Add notifyGidToLidChange() method to reference attribute, to handle
information about changed gid to lid mapping.
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; |