diff options
author | Tor Egge <Tor.Egge@oath.com> | 2017-08-30 13:57:25 +0000 |
---|---|---|
committer | Tor Egge <Tor.Egge@oath.com> | 2017-08-30 13:58:13 +0000 |
commit | 42a9e2b3bfdd95e3dd835526ec818a79084c0b89 (patch) | |
tree | 47ace8bee5aa8c3fd5f79ea2f20089a8ee899732 | |
parent | 66aa89e733c9cf033352a3e32202b7b1b49bac77 (diff) |
Propagate API changes to GidToLidChangeListener and ReferenceAttribute:
Split put and remove notifications into separate methods.
13 files changed, 150 insertions, 88 deletions
diff --git a/searchcore/src/tests/proton/reference/gid_to_lid_change_handler/gid_to_lid_change_handler_test.cpp b/searchcore/src/tests/proton/reference/gid_to_lid_change_handler/gid_to_lid_change_handler_test.cpp index c9fe214947c..587f58cf8d9 100644 --- a/searchcore/src/tests/proton/reference/gid_to_lid_change_handler/gid_to_lid_change_handler_test.cpp +++ b/searchcore/src/tests/proton/reference/gid_to_lid_change_handler/gid_to_lid_change_handler_test.cpp @@ -31,7 +31,8 @@ vespalib::string doc1("id:test:music::1"); class ListenerStats { using lock_guard = std::lock_guard<std::mutex>; std::mutex _lock; - uint32_t _changes; + uint32_t _putChanges; + uint32_t _removeChanges; uint32_t _createdListeners; uint32_t _registeredListeners; uint32_t _destroyedListeners; @@ -39,7 +40,8 @@ class ListenerStats { public: ListenerStats() : _lock(), - _changes(0u), + _putChanges(0u), + _removeChanges(0u), _createdListeners(0u), _registeredListeners(0u), _destroyedListeners(0u) @@ -51,9 +53,13 @@ public: EXPECT_EQUAL(_createdListeners, _destroyedListeners); } - void notifyGidToLidChange() { + void notifyPut() { lock_guard guard(_lock); - ++_changes; + ++_putChanges; + } + void notifyRemove() { + lock_guard guard(_lock); + ++_removeChanges; } void markCreatedListener() { lock_guard guard(_lock); ++_createdListeners; } void markRegisteredListener() { lock_guard guard(_lock); ++_registeredListeners; } @@ -63,15 +69,18 @@ public: uint32_t getRegisteredListeners() const { return _registeredListeners; } uint32_t getDestroyedListeners() const { return _destroyedListeners; } - void assertCounts(uint32_t expCreatedListeners, - uint32_t expRegisteredListeners, - uint32_t expDestroyedListeners, - uint32_t expChanges) + void assertListeners(uint32_t expCreatedListeners, + uint32_t expRegisteredListeners, + uint32_t expDestroyedListeners) { EXPECT_EQUAL(expCreatedListeners, getCreatedListeners()); EXPECT_EQUAL(expRegisteredListeners, getRegisteredListeners()); EXPECT_EQUAL(expDestroyedListeners, getDestroyedListeners()); - EXPECT_EQUAL(expChanges, _changes); + } + void assertChanges(uint32_t expPutChanges, uint32_t expRemoveChanges) + { + EXPECT_EQUAL(expPutChanges, _putChanges); + EXPECT_EQUAL(expRemoveChanges, _removeChanges); } }; @@ -92,7 +101,8 @@ public: _stats.markCreatedListener(); } virtual ~MyListener() { _stats.markDestroyedListener(); } - virtual void notifyGidToLidChange(GlobalId, uint32_t) override { _stats.notifyGidToLidChange(); } + virtual void notifyPut(GlobalId, uint32_t) override { _stats.notifyPut(); } + virtual void notifyRemove(GlobalId) override { _stats.notifyRemove(); } virtual void notifyRegistered() override { _stats.markRegisteredListener(); } virtual const vespalib::string &getName() const override { return _name; } virtual const vespalib::string &getDocTypeName() const override { return _docTypeName; } @@ -151,13 +161,13 @@ TEST_F("Test that we can register a listener", Fixture) { auto &stats = f.addStats(); auto listener = std::make_unique<MyListener>(stats, "test", "testdoc"); - TEST_DO(stats.assertCounts(1, 0, 0, 0)); + TEST_DO(stats.assertListeners(1, 0, 0)); f.addListener(std::move(listener)); - TEST_DO(stats.assertCounts(1, 1, 0, 0)); + TEST_DO(stats.assertListeners(1, 1, 0)); f.notifyPut(toGid(doc1), 10, 10); - TEST_DO(stats.assertCounts(1, 1, 0, 1)); + TEST_DO(stats.assertChanges(1, 0)); f.removeListeners("testdoc", {}); - TEST_DO(stats.assertCounts(1, 1, 1, 1)); + TEST_DO(stats.assertListeners(1, 1, 1)); } TEST_F("Test that we can register multiple listeners", Fixture) @@ -168,92 +178,92 @@ TEST_F("Test that we can register multiple listeners", Fixture) auto listener1 = std::make_unique<MyListener>(stats1, "test1", "testdoc"); auto listener2 = std::make_unique<MyListener>(stats2, "test2", "testdoc"); auto listener3 = std::make_unique<MyListener>(stats3, "test3", "testdoc2"); - TEST_DO(stats1.assertCounts(1, 0, 0, 0)); - TEST_DO(stats2.assertCounts(1, 0, 0, 0)); - TEST_DO(stats3.assertCounts(1, 0, 0, 0)); + TEST_DO(stats1.assertListeners(1, 0, 0)); + TEST_DO(stats2.assertListeners(1, 0, 0)); + TEST_DO(stats3.assertListeners(1, 0, 0)); f.addListener(std::move(listener1)); f.addListener(std::move(listener2)); f.addListener(std::move(listener3)); - TEST_DO(stats1.assertCounts(1, 1, 0, 0)); - TEST_DO(stats2.assertCounts(1, 1, 0, 0)); - TEST_DO(stats3.assertCounts(1, 1, 0, 0)); + TEST_DO(stats1.assertListeners(1, 1, 0)); + TEST_DO(stats2.assertListeners(1, 1, 0)); + TEST_DO(stats3.assertListeners(1, 1, 0)); f.notifyPut(toGid(doc1), 10, 10); - TEST_DO(stats1.assertCounts(1, 1, 0, 1)); - TEST_DO(stats2.assertCounts(1, 1, 0, 1)); - TEST_DO(stats3.assertCounts(1, 1, 0, 1)); + TEST_DO(stats1.assertChanges(1, 0)); + TEST_DO(stats2.assertChanges(1, 0)); + TEST_DO(stats3.assertChanges(1, 0)); f.removeListeners("testdoc", {"test1"}); - TEST_DO(stats1.assertCounts(1, 1, 0, 1)); - TEST_DO(stats2.assertCounts(1, 1, 1, 1)); - TEST_DO(stats3.assertCounts(1, 1, 0, 1)); + TEST_DO(stats1.assertListeners(1, 1, 0)); + TEST_DO(stats2.assertListeners(1, 1, 1)); + TEST_DO(stats3.assertListeners(1, 1, 0)); f.removeListeners("testdoc", {}); - TEST_DO(stats1.assertCounts(1, 1, 1, 1)); - TEST_DO(stats2.assertCounts(1, 1, 1, 1)); - TEST_DO(stats3.assertCounts(1, 1, 0, 1)); + TEST_DO(stats1.assertListeners(1, 1, 1)); + TEST_DO(stats2.assertListeners(1, 1, 1)); + TEST_DO(stats3.assertListeners(1, 1, 0)); f.removeListeners("testdoc2", {"test3"}); - TEST_DO(stats1.assertCounts(1, 1, 1, 1)); - TEST_DO(stats2.assertCounts(1, 1, 1, 1)); - TEST_DO(stats3.assertCounts(1, 1, 0, 1)); + TEST_DO(stats1.assertListeners(1, 1, 1)); + TEST_DO(stats2.assertListeners(1, 1, 1)); + TEST_DO(stats3.assertListeners(1, 1, 0)); f.removeListeners("testdoc2", {"foo"}); - TEST_DO(stats1.assertCounts(1, 1, 1, 1)); - TEST_DO(stats2.assertCounts(1, 1, 1, 1)); - TEST_DO(stats3.assertCounts(1, 1, 1, 1)); + TEST_DO(stats1.assertListeners(1, 1, 1)); + TEST_DO(stats2.assertListeners(1, 1, 1)); + TEST_DO(stats3.assertListeners(1, 1, 1)); } TEST_F("Test that we keep old listener when registering duplicate", Fixture) { auto &stats = f.addStats(); auto listener = std::make_unique<MyListener>(stats, "test1", "testdoc"); - TEST_DO(stats.assertCounts(1, 0, 0, 0)); + TEST_DO(stats.assertListeners(1, 0, 0)); f.addListener(std::move(listener)); - TEST_DO(stats.assertCounts(1, 1, 0, 0)); + TEST_DO(stats.assertListeners(1, 1, 0)); listener = std::make_unique<MyListener>(stats, "test1", "testdoc"); - TEST_DO(stats.assertCounts(2, 1, 0, 0)); + TEST_DO(stats.assertListeners(2, 1, 0)); f.addListener(std::move(listener)); - TEST_DO(stats.assertCounts(2, 1, 1, 0)); + TEST_DO(stats.assertListeners(2, 1, 1)); } TEST_F("Test that put is ignored if we have a pending remove", Fixture) { auto &stats = f.addStats(); auto listener = std::make_unique<MyListener>(stats, "test", "testdoc"); - TEST_DO(stats.assertCounts(1, 0, 0, 0)); + TEST_DO(stats.assertListeners(1, 0, 0)); f.addListener(std::move(listener)); - TEST_DO(stats.assertCounts(1, 1, 0, 0)); + TEST_DO(stats.assertListeners(1, 1, 0)); f.notifyRemove(toGid(doc1), 20); - TEST_DO(stats.assertCounts(1, 1, 0, 1)); + TEST_DO(stats.assertChanges(0, 1)); f.notifyPut(toGid(doc1), 10, 10); - TEST_DO(stats.assertCounts(1, 1, 0, 1)); + TEST_DO(stats.assertChanges(0, 1)); f.notifyRemoveDone(toGid(doc1), 20); - TEST_DO(stats.assertCounts(1, 1, 0, 1)); + TEST_DO(stats.assertChanges(0, 1)); f.notifyPut(toGid(doc1), 11, 30); - TEST_DO(stats.assertCounts(1, 1, 0, 2)); + TEST_DO(stats.assertChanges(1, 1)); f.removeListeners("testdoc", {}); - TEST_DO(stats.assertCounts(1, 1, 1, 2)); + TEST_DO(stats.assertListeners(1, 1, 1)); } TEST_F("Test that pending removes are merged", Fixture) { auto &stats = f.addStats(); auto listener = std::make_unique<MyListener>(stats, "test", "testdoc"); - TEST_DO(stats.assertCounts(1, 0, 0, 0)); + TEST_DO(stats.assertListeners(1, 0, 0)); f.addListener(std::move(listener)); - TEST_DO(stats.assertCounts(1, 1, 0, 0)); + TEST_DO(stats.assertListeners(1, 1, 0)); f.notifyRemove(toGid(doc1), 20); - TEST_DO(stats.assertCounts(1, 1, 0, 1)); + TEST_DO(stats.assertChanges(0, 1)); f.notifyRemove(toGid(doc1), 40); - TEST_DO(stats.assertCounts(1, 1, 0, 1)); + TEST_DO(stats.assertChanges(0, 1)); f.notifyPut(toGid(doc1), 10, 10); - TEST_DO(stats.assertCounts(1, 1, 0, 1)); + TEST_DO(stats.assertChanges(0, 1)); f.notifyRemoveDone(toGid(doc1), 20); - TEST_DO(stats.assertCounts(1, 1, 0, 1)); + TEST_DO(stats.assertChanges(0, 1)); f.notifyPut(toGid(doc1), 11, 30); - TEST_DO(stats.assertCounts(1, 1, 0, 1)); + TEST_DO(stats.assertChanges(0, 1)); f.notifyRemoveDone(toGid(doc1), 40); - TEST_DO(stats.assertCounts(1, 1, 0, 1)); + TEST_DO(stats.assertChanges(0, 1)); f.notifyPut(toGid(doc1), 12, 50); - TEST_DO(stats.assertCounts(1, 1, 0, 2)); + TEST_DO(stats.assertChanges(1, 1)); f.removeListeners("testdoc", {}); - TEST_DO(stats.assertCounts(1, 1, 1, 2)); + TEST_DO(stats.assertListeners(1, 1, 1)); } } diff --git a/searchcore/src/tests/proton/reference/gid_to_lid_change_listener/gid_to_lid_change_listener_test.cpp b/searchcore/src/tests/proton/reference/gid_to_lid_change_listener/gid_to_lid_change_listener_test.cpp index 780a6d79ad6..08787e41438 100644 --- a/searchcore/src/tests/proton/reference/gid_to_lid_change_listener/gid_to_lid_change_listener_test.cpp +++ b/searchcore/src/tests/proton/reference/gid_to_lid_change_listener/gid_to_lid_change_listener_test.cpp @@ -117,8 +117,8 @@ struct Fixture _listener = std::make_unique<GidToLidChangeListener>(_writer, _attr, _refCount, "test", "testdoc"); } - void notifyGidToLidChange(const GlobalId &gid, uint32_t referencedDoc) { - _listener->notifyGidToLidChange(gid, referencedDoc); + void notifyPut(const GlobalId &gid, uint32_t referencedDoc) { + _listener->notifyPut(gid, referencedDoc); } void notifyListenerRegistered() { @@ -137,9 +137,9 @@ TEST_F("Test that we can use gid to lid change listener", Fixture) TEST_DO(f.assertRefLid(0, 2)); TEST_DO(f.assertRefLid(0, 3)); f.allocListener(); - f.notifyGidToLidChange(toGid(doc1), 10); - f.notifyGidToLidChange(toGid(doc2), 20); - f.notifyGidToLidChange(toGid(doc3), 30); + f.notifyPut(toGid(doc1), 10); + f.notifyPut(toGid(doc2), 20); + f.notifyPut(toGid(doc3), 30); TEST_DO(f.assertRefLid(10, 1)); TEST_DO(f.assertRefLid(20, 2)); TEST_DO(f.assertRefLid(10, 3)); diff --git a/searchcore/src/tests/proton/reference/gid_to_lid_change_registrator/gid_to_lid_change_registrator_test.cpp b/searchcore/src/tests/proton/reference/gid_to_lid_change_registrator/gid_to_lid_change_registrator_test.cpp index e97f117e481..a5231647158 100644 --- a/searchcore/src/tests/proton/reference/gid_to_lid_change_registrator/gid_to_lid_change_registrator_test.cpp +++ b/searchcore/src/tests/proton/reference/gid_to_lid_change_registrator/gid_to_lid_change_registrator_test.cpp @@ -24,7 +24,8 @@ public: { } virtual ~MyListener() { } - virtual void notifyGidToLidChange(document::GlobalId, uint32_t) override { } + virtual void notifyPut(document::GlobalId, uint32_t) override { } + virtual void notifyRemove(document::GlobalId) override { } virtual void notifyRegistered() override { } virtual const vespalib::string &getName() const override { return _name; } virtual const vespalib::string &getDocTypeName() const override { return _docTypeName; } diff --git a/searchcore/src/vespa/searchcore/proton/reference/gid_to_lid_change_handler.cpp b/searchcore/src/vespa/searchcore/proton/reference/gid_to_lid_change_handler.cpp index 0c0b1258027..d7b2c16867a 100644 --- a/searchcore/src/vespa/searchcore/proton/reference/gid_to_lid_change_handler.cpp +++ b/searchcore/src/vespa/searchcore/proton/reference/gid_to_lid_change_handler.cpp @@ -31,10 +31,18 @@ GidToLidChangeHandler::~GidToLidChangeHandler() } void -GidToLidChangeHandler::notifyGidToLidChange(GlobalId gid, uint32_t lid) +GidToLidChangeHandler::notifyPut(GlobalId gid, uint32_t lid) { for (const auto &listener : _listeners) { - listener->notifyGidToLidChange(gid, lid); + listener->notifyPut(gid, lid); + } +} + +void +GidToLidChangeHandler::notifyRemove(GlobalId gid) +{ + for (const auto &listener : _listeners) { + listener->notifyRemove(gid); } } @@ -47,7 +55,7 @@ GidToLidChangeHandler::notifyPut(GlobalId gid, uint32_t lid, SerialNum serialNum assert(itr->second > serialNum); return; // Document has already been removed later on } - notifyGidToLidChange(gid, lid); + notifyPut(gid, lid); } void @@ -59,7 +67,7 @@ GidToLidChangeHandler::notifyRemove(GlobalId gid, SerialNum serialNum) assert(insRes.first->second < serialNum); insRes.first->second = serialNum; } else { - notifyGidToLidChange(gid, 0); + notifyRemove(gid); } } diff --git a/searchcore/src/vespa/searchcore/proton/reference/gid_to_lid_change_handler.h b/searchcore/src/vespa/searchcore/proton/reference/gid_to_lid_change_handler.h index 34172683a58..736a34aba76 100644 --- a/searchcore/src/vespa/searchcore/proton/reference/gid_to_lid_change_handler.h +++ b/searchcore/src/vespa/searchcore/proton/reference/gid_to_lid_change_handler.h @@ -27,7 +27,8 @@ class GidToLidChangeHandler : public std::enable_shared_from_this<GidToLidChange bool _closed; vespalib::hash_map<GlobalId, SerialNum, GlobalId::hash> _pendingRemove; - void notifyGidToLidChange(GlobalId gid, uint32_t lid); + void notifyPut(GlobalId gid, uint32_t lid); + void notifyRemove(GlobalId gid); public: GidToLidChangeHandler(); virtual ~GidToLidChangeHandler(); diff --git a/searchcore/src/vespa/searchcore/proton/reference/gid_to_lid_change_listener.cpp b/searchcore/src/vespa/searchcore/proton/reference/gid_to_lid_change_listener.cpp index 5aba8bf3150..6a368997770 100644 --- a/searchcore/src/vespa/searchcore/proton/reference/gid_to_lid_change_listener.cpp +++ b/searchcore/src/vespa/searchcore/proton/reference/gid_to_lid_change_listener.cpp @@ -26,12 +26,22 @@ GidToLidChangeListener::~GidToLidChangeListener() } void -GidToLidChangeListener::notifyGidToLidChange(document::GlobalId gid, uint32_t lid) +GidToLidChangeListener::notifyPut(document::GlobalId gid, uint32_t lid) { std::promise<bool> promise; std::future<bool> future = promise.get_future(); _attributeFieldWriter.executeLambda(_executorId, - [this, &promise, gid, lid]() { _attr->notifyGidToLidChange(gid, lid); promise.set_value(true); }); + [this, &promise, gid, lid]() { _attr->notifyReferencedPut(gid, lid); promise.set_value(true); }); + (void) future.get(); +} + +void +GidToLidChangeListener::notifyRemove(document::GlobalId gid) +{ + std::promise<bool> promise; + std::future<bool> future = promise.get_future(); + _attributeFieldWriter.executeLambda(_executorId, + [this, &promise, gid]() { _attr->notifyReferencedRemove(gid); promise.set_value(true); }); (void) future.get(); } diff --git a/searchcore/src/vespa/searchcore/proton/reference/gid_to_lid_change_listener.h b/searchcore/src/vespa/searchcore/proton/reference/gid_to_lid_change_listener.h index 8a3a7d00cec..35ff913d7af 100644 --- a/searchcore/src/vespa/searchcore/proton/reference/gid_to_lid_change_listener.h +++ b/searchcore/src/vespa/searchcore/proton/reference/gid_to_lid_change_listener.h @@ -30,7 +30,8 @@ public: const vespalib::string &name, const vespalib::string &docTypeName); virtual ~GidToLidChangeListener(); - virtual void notifyGidToLidChange(document::GlobalId gid, uint32_t lid) override; + virtual void notifyPut(document::GlobalId gid, uint32_t lid) override; + virtual void notifyRemove(document::GlobalId gid) override; virtual void notifyRegistered() override; virtual const vespalib::string &getName() const override; virtual const vespalib::string &getDocTypeName() const override; diff --git a/searchcore/src/vespa/searchcore/proton/reference/i_gid_to_lid_change_listener.h b/searchcore/src/vespa/searchcore/proton/reference/i_gid_to_lid_change_listener.h index 317f378bedc..d02979e168f 100644 --- a/searchcore/src/vespa/searchcore/proton/reference/i_gid_to_lid_change_listener.h +++ b/searchcore/src/vespa/searchcore/proton/reference/i_gid_to_lid_change_listener.h @@ -17,7 +17,8 @@ class IGidToLidChangeListener { public: virtual ~IGidToLidChangeListener() { } - virtual void notifyGidToLidChange(document::GlobalId gid, uint32_t lid) = 0; + virtual void notifyPut(document::GlobalId gid, uint32_t lid) = 0; + virtual void notifyRemove(document::GlobalId gid) = 0; virtual void notifyRegistered() = 0; virtual const vespalib::string &getName() const = 0; virtual const vespalib::string &getDocTypeName() const = 0; 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 7e2e8904170..1b1bc1f8796 100644 --- a/searchlib/src/tests/attribute/reference_attribute/reference_attribute_test.cpp +++ b/searchlib/src/tests/attribute/reference_attribute/reference_attribute_test.cpp @@ -182,8 +182,11 @@ struct Fixture iter, oldStatus.getUsed(), newStatus.getUsed()); } - void notifyGidToLidChange(const GlobalId &gid, uint32_t referencedDoc) { - _attr->notifyGidToLidChange(gid, referencedDoc); + void notifyReferencedPut(const GlobalId &gid, uint32_t referencedDoc) { + _attr->notifyReferencedPut(gid, referencedDoc); + } + void notifyReferencedRemove(const GlobalId &gid) { + _attr->notifyReferencedRemove(gid); } void populateReferencedLids() { _attr->populateReferencedLids(); @@ -300,7 +303,7 @@ TEST_F("require that update() uses gid-mapper to set referenced lid", Fixture) TEST_DO(f.assertRefLid(5, 0)); } -TEST_F("require that notifyGidToLidChange() updates lid-2-lid mapping", Fixture) +TEST_F("require that notifyReferencedPut() updates lid-2-lid mapping", Fixture) { f.ensureDocIdLimit(4); f.set(1, toGid(doc1)); @@ -310,9 +313,9 @@ TEST_F("require that notifyGidToLidChange() updates lid-2-lid mapping", Fixture) TEST_DO(f.assertRefLid(1, 0)); TEST_DO(f.assertRefLid(2, 0)); TEST_DO(f.assertRefLid(3, 0)); - f.notifyGidToLidChange(toGid(doc1), 10); - f.notifyGidToLidChange(toGid(doc2), 20); - f.notifyGidToLidChange(toGid(doc3), 30); + f.notifyReferencedPut(toGid(doc1), 10); + f.notifyReferencedPut(toGid(doc2), 20); + f.notifyReferencedPut(toGid(doc3), 30); TEST_DO(f.assertRefLid(1, 10)); TEST_DO(f.assertRefLid(2, 20)); TEST_DO(f.assertRefLid(3, 10)); @@ -369,18 +372,18 @@ TEST_F("require that populateReferencedLids() uses gid-mapper to update lid-2-li EXPECT_TRUE(vespalib::unlink("test.udat")); } -TEST_F("Require that notifyGidToLidChange changes reverse mapping", Fixture) +TEST_F("Require that notifyReferencedPut and notifyReferencedRemove changes reverse mapping", Fixture) { TEST_DO(preparePopulateReferencedLids(f)); TEST_DO(f.assertLids(10, { })); TEST_DO(f.assertLids(11, { })); - f.notifyGidToLidChange(toGid(doc1), 10); + f.notifyReferencedPut(toGid(doc1), 10); TEST_DO(f.assertLids(10, { 1, 3})); TEST_DO(f.assertLids(11, { })); - f.notifyGidToLidChange(toGid(doc1), 11); + f.notifyReferencedPut(toGid(doc1), 11); TEST_DO(f.assertLids(10, { })); TEST_DO(f.assertLids(11, { 1, 3})); - f.notifyGidToLidChange(toGid(doc1), 0); + f.notifyReferencedRemove(toGid(doc1)); TEST_DO(f.assertLids(10, { })); TEST_DO(f.assertLids(11, { })); } @@ -406,8 +409,8 @@ TEST_F("Require that reverse mapping recovers from temporary out of order glitch TEST_DO(f.assertRefLid(2, 17)); TEST_DO(f.assertRefLid(3, 10)); // Notify reference attribute about gid to lid mapping changes - f.notifyGidToLidChange(toGid(doc1), 0); - f.notifyGidToLidChange(toGid(doc3), 10); + f.notifyReferencedRemove(toGid(doc1)); + f.notifyReferencedPut(toGid(doc3), 10); TEST_DO(f.assertRefLid(1, 0)); TEST_DO(f.assertRefLid(2, 17)); TEST_DO(f.assertRefLid(3, 10)); diff --git a/searchlib/src/vespa/searchlib/attribute/reference_attribute.cpp b/searchlib/src/vespa/searchlib/attribute/reference_attribute.cpp index 7e17ba3a808..2cb05b14503 100644 --- a/searchlib/src/vespa/searchlib/attribute/reference_attribute.cpp +++ b/searchlib/src/vespa/searchlib/attribute/reference_attribute.cpp @@ -320,12 +320,23 @@ ReferenceAttribute::setGidToLidMapperFactory(std::shared_ptr<IGidToLidMapperFact } void -ReferenceAttribute::notifyGidToLidChange(const GlobalId &gid, DocId referencedLid) +ReferenceAttribute::notifyReferencedPut(const GlobalId &gid, DocId referencedLid) { EntryRef ref = _store.find(gid); if (ref.valid()) { const auto &entry = _store.get(ref); - _referenceMappings.notifyGidToLidChange(entry, referencedLid); + _referenceMappings.notifyReferencedPut(entry, referencedLid); + commit(); + } +} + +void +ReferenceAttribute::notifyReferencedRemove(const GlobalId &gid) +{ + EntryRef ref = _store.find(gid); + if (ref.valid()) { + const auto &entry = _store.get(ref); + _referenceMappings.notifyReferencedRemove(entry); commit(); } } diff --git a/searchlib/src/vespa/searchlib/attribute/reference_attribute.h b/searchlib/src/vespa/searchlib/attribute/reference_attribute.h index 4ee277b8733..ce7c908db99 100644 --- a/searchlib/src/vespa/searchlib/attribute/reference_attribute.h +++ b/searchlib/src/vespa/searchlib/attribute/reference_attribute.h @@ -78,7 +78,8 @@ public: ReverseMappingRefs getReverseMappingRefs() const { return _referenceMappings.getReverseMappingRefs(); } const ReverseMapping &getReverseMapping() const { return _referenceMappings.getReverseMapping(); } - void notifyGidToLidChange(const GlobalId &gid, DocId referencedLid); + void notifyReferencedPut(const GlobalId &gid, DocId referencedLid); + void notifyReferencedRemove(const GlobalId &gid); void populateReferencedLids(); virtual void clearDocs(DocId lidLow, DocId lidLimit) override; virtual void onShrinkLidSpace() override; diff --git a/searchlib/src/vespa/searchlib/attribute/reference_mappings.cpp b/searchlib/src/vespa/searchlib/attribute/reference_mappings.cpp index 4edd9d45e60..f2462cdc40d 100644 --- a/searchlib/src/vespa/searchlib/attribute/reference_mappings.cpp +++ b/searchlib/src/vespa/searchlib/attribute/reference_mappings.cpp @@ -93,7 +93,7 @@ ReferenceMappings::buildReverseMapping(const Reference &entry, const std::vector } void -ReferenceMappings::notifyGidToLidChange(const Reference &entry, uint32_t referencedLid) +ReferenceMappings::notifyReferencedPut(const Reference &entry, uint32_t referencedLid) { uint32_t oldReferencedLid = entry.lid(); if (oldReferencedLid != referencedLid) { @@ -107,6 +107,20 @@ ReferenceMappings::notifyGidToLidChange(const Reference &entry, uint32_t referen } void +ReferenceMappings::notifyReferencedRemove(const Reference &entry) +{ + uint32_t oldReferencedLid = entry.lid(); + if (oldReferencedLid != 0) { + if (oldReferencedLid < _reverseMappingIndices.size()) { + _reverseMappingIndices[oldReferencedLid] = EntryRef(); + } + entry.setLid(0); + } + syncReverseMappingIndices(entry); + syncForwardMapping(entry); +} + +void ReferenceMappings::onAddDocs(uint32_t docIdLimit) { _referencedLids.reserve(docIdLimit); diff --git a/searchlib/src/vespa/searchlib/attribute/reference_mappings.h b/searchlib/src/vespa/searchlib/attribute/reference_mappings.h index 3190e1b5a83..73754d9cb13 100644 --- a/searchlib/src/vespa/searchlib/attribute/reference_mappings.h +++ b/searchlib/src/vespa/searchlib/attribute/reference_mappings.h @@ -57,7 +57,8 @@ public: void transferHoldLists(generation_t generation) { _reverseMapping.transferHoldLists(generation); } // Handle mapping changes - void notifyGidToLidChange(const Reference &entry, uint32_t referencedLid); + void notifyReferencedPut(const Reference &entry, uint32_t referencedLid); + void notifyReferencedRemove(const Reference &entry); void removeReverseMapping(const Reference &entry, uint32_t lid); void addReverseMapping(const Reference &entry, uint32_t lid); void syncMappings(const Reference &entry); |