Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix LocalVocab merge #1617

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/engine/LocalVocab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "absl/strings/str_cat.h"
#include "global/Id.h"
#include "global/ValueId.h"
#include "util/BlankNodeManager.h"

// _____________________________________________________________________________
LocalVocab LocalVocab::clone() const {
Expand Down Expand Up @@ -84,7 +85,9 @@ BlankNodeIndex LocalVocab::getBlankNodeIndex(
AD_CONTRACT_CHECK(blankNodeManager);
// Initialize the `localBlankNodeManager_` if it doesn't exist yet.
if (!localBlankNodeManager_) [[unlikely]] {
localBlankNodeManager_.emplace(blankNodeManager);
localBlankNodeManager_ =
std::make_shared<ad_utility::BlankNodeManager::LocalBlankNodeManager>(
blankNodeManager);
}
return BlankNodeIndex::make(localBlankNodeManager_->getId());
}
Expand Down
25 changes: 24 additions & 1 deletion src/engine/LocalVocab.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

#pragma once

#include <algorithm>
#include <cstdlib>
#include <memory>
#include <ranges>
#include <span>
#include <string>
#include <vector>
Expand Down Expand Up @@ -39,7 +41,7 @@ class LocalVocab {
auto& primaryWordSet() { return *primaryWordSet_; }
const auto& primaryWordSet() const { return *primaryWordSet_; }

std::optional<ad_utility::BlankNodeManager::LocalBlankNodeManager>
std::shared_ptr<ad_utility::BlankNodeManager::LocalBlankNodeManager>
localBlankNodeManager_;

public:
Expand Down Expand Up @@ -100,6 +102,27 @@ class LocalVocab {
std::ranges::copy(vocab.otherWordSets_, inserter);
*inserter = vocab.primaryWordSet_;
}

// Also merge the `vocabs` `LocalBlankNodeManager`s, if they exist.
using LocalBlankNodeManager =
ad_utility::BlankNodeManager::LocalBlankNodeManager;
if (auto it = std::ranges::find_if(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can write the auto it = ... outside the loop and then do if (it == end) { return;}, to reduce the nestedness of the code.

vocabs,
[](const LocalVocab& vocab) -> bool {
return vocab.localBlankNodeManager_.get() != nullptr;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return vocab.localBlankNodeManager_.get() != nullptr;
return vocab.localBlankNodeManager_ != nullptr;

Also can be applied in a similar lambda in BlankNodeManager.h.

});
it != vocabs.end()) {
if (!localBlankNodeManager_) {
localBlankNodeManager_ = std::make_shared<LocalBlankNodeManager>(
(*it).localBlankNodeManager_->blankNodeManager_);
}
localBlankNodeManager_->mergeWith(
vocabs | std::views::transform(
[](const LocalVocab& vocab)
-> std::shared_ptr<const LocalBlankNodeManager> {
return vocab.localBlankNodeManager_;
}));
Comment on lines +120 to +124
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. You can bind this view to a variable, and then also use it for the find_if above.
  2. you can then initially in this function introduce an alias using ShortName = shared_ptr<const LocalBla> to make the lambdas shorter.
  3. The transform lambda should return const shared_ptr&, or shared_ptr& (copying shared pointers is not free, and the lifetime is okay here.

}
}

// Return all the words from all the word sets as a vector.
Expand Down
15 changes: 13 additions & 2 deletions src/util/BlankNodeManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

#include "util/BlankNodeManager.h"

#include "util/Exception.h"

namespace ad_utility {

// _____________________________________________________________________________
Expand Down Expand Up @@ -62,9 +64,18 @@ uint64_t BlankNodeManager::LocalBlankNodeManager::getId() {
// _____________________________________________________________________________
bool BlankNodeManager::LocalBlankNodeManager::containsBlankNodeIndex(
uint64_t index) const {
return std::ranges::any_of(blocks_, [index](const Block& block) {
auto containsIndex = [index](const Block& block) {
return index >= block.startIdx_ && index < block.nextIdx_;
});
};
auto otherBlocks = std::views::join(
otherManagers_ |
std::views::transform(
[](const std::shared_ptr<const LocalBlankNodeManager>& l) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This copies the blocks.
Explicit make the lambda return ->decltype(auto) to only return the references to the vectors of blocks.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this then also fixes the build failures (otherwise we might have to analyze them further:)

return l->blocks_;
}));

return std::ranges::any_of(blocks_, containsIndex) ||
std::ranges::any_of(otherBlocks, containsIndex);
}

} // namespace ad_utility
20 changes: 17 additions & 3 deletions src/util/BlankNodeManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,16 +87,30 @@ class BlankNodeManager {
// Return true iff the `index` was returned by a previous call to `getId()`.
bool containsBlankNodeIndex(uint64_t index) const;

private:
// Reserved blocks.
std::vector<BlankNodeManager::Block> blocks_;
// Merge passed `LocalBlankNodeManager`s to keep alive their reserved
// BlankNodeIndex blocks.
template <std::ranges::range R>
void mergeWith(const R& localBlankNodeManagers) {
std::ranges::copy_if(
localBlankNodeManagers, std::back_inserter(otherManagers_),
[](const std::shared_ptr<const LocalBlankNodeManager>& l) -> bool {
return l.get() != nullptr;
});
}

// Reference to the BlankNodeManager, used to free the reserved blocks.
BlankNodeManager* blankNodeManager_;

private:
// Reserved blocks.
std::vector<BlankNodeManager::Block> blocks_;

// The first index after the current Block.
uint64_t idxAfterCurrentBlock_{0};

// Other LocalBlankNodeManagers merged into this instance.
std::vector<std::shared_ptr<const LocalBlankNodeManager>> otherManagers_;

FRIEND_TEST(BlankNodeManager, LocalBlankNodeManagerGetID);
};

Expand Down
18 changes: 18 additions & 0 deletions test/LocalVocabTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,24 @@ TEST(LocalVocab, merge) {
EXPECT_EQ(*indices[1], lit("twoA"));
EXPECT_EQ(*indices[2], lit("oneB"));
EXPECT_EQ(*indices[3], lit("twoB"));

// Test that the `LocalBlankNodeManager` of vocabs is merged correctly.
LocalVocab vocC, vocD;
ad_utility::BlankNodeManager bnm;
auto id = vocC.getBlankNodeIndex(&bnm);
auto vocabs2 = std::vector{&std::as_const(vocC), &std::as_const(vocD)};
LocalVocab localVocabMerged2 = LocalVocab::merge(vocabs2);
localVocabMerged2.isBlankNodeIndexContained(id);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't you miss an EXPECT_TRUE or something similar here?


LocalVocab vocE, vocF;
auto id2 = vocE.getBlankNodeIndex(&bnm);
auto vocabs3 =
std::vector{&std::as_const(localVocabMerged2), &std::as_const(vocF)};
vocE.mergeWith(vocabs3 | std::views::transform(
[](const LocalVocab* l) -> const LocalVocab& {
return *l;
}));
vocE.isBlankNodeIndexContained(id2);
}

// _____________________________________________________________________________
Expand Down
Loading