Optimize scanning vertices (#1227)

This commit is contained in:
Gareth Andrew Lloyd 2023-09-09 15:09:25 +01:00 committed by GitHub
parent 1bd47318cd
commit ab56abf4ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 23 additions and 13 deletions

View File

@ -331,17 +331,17 @@ class VerticesIterable final {
it_;
public:
explicit Iterator(storage::VerticesIterable::Iterator it) : it_(it) {}
explicit Iterator(storage::VerticesIterable::Iterator it) : it_(std::move(it)) {}
explicit Iterator(std::unordered_set<VertexAccessor, std::hash<VertexAccessor>, std::equal_to<void>,
utils::Allocator<VertexAccessor>>::iterator it)
: it_(it) {}
VertexAccessor operator*() const {
return std::visit([](auto it_) { return VertexAccessor(*it_); }, it_);
return std::visit([](auto &it_) { return VertexAccessor(*it_); }, it_);
}
Iterator &operator++() {
std::visit([this](auto it_) { this->it_ = ++it_; }, it_);
std::visit([](auto &it_) { ++it_; }, it_);
return *this;
}

View File

@ -444,7 +444,7 @@ class ScanAllCursor : public Cursor {
AbortCheck(context);
while (!vertices_ || vertices_it_.value() == vertices_.value().end()) {
while (!vertices_ || vertices_it_.value() == vertices_end_it_.value()) {
if (!input_cursor_->Pull(frame, context)) return false;
// We need a getter function, because in case of exhausting a lazy
// iterable, we cannot simply reset it by calling begin().
@ -455,6 +455,7 @@ class ScanAllCursor : public Cursor {
// vertices _ = get_vertices_(frame, context);
vertices_.emplace(std::move(next_vertices.value()));
vertices_it_.emplace(vertices_.value().begin());
vertices_end_it_.emplace(vertices_.value().end());
}
#ifdef MG_ENTERPRISE
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker && !FindNextVertex(context)) {
@ -469,7 +470,7 @@ class ScanAllCursor : public Cursor {
#ifdef MG_ENTERPRISE
bool FindNextVertex(const ExecutionContext &context) {
while (vertices_it_.value() != vertices_.value().end()) {
while (vertices_it_.value() != vertices_end_it_.value()) {
if (context.auth_checker->Has(*vertices_it_.value(), view_,
memgraph::query::AuthQuery::FineGrainedPrivilege::READ)) {
return true;
@ -486,6 +487,7 @@ class ScanAllCursor : public Cursor {
input_cursor_->Reset();
vertices_ = std::nullopt;
vertices_it_ = std::nullopt;
vertices_end_it_ = std::nullopt;
}
private:
@ -495,6 +497,7 @@ class ScanAllCursor : public Cursor {
TVerticesFun get_vertices_;
std::optional<typename std::result_of<TVerticesFun(Frame &, ExecutionContext &)>::type::value_type> vertices_;
std::optional<decltype(vertices_.value().begin())> vertices_it_;
std::optional<decltype(vertices_.value().end())> vertices_end_it_;
const char *op_name_;
};

View File

@ -17,11 +17,11 @@ auto AdvanceToVisibleVertex(utils::SkipList<Vertex>::Iterator it, utils::SkipLis
std::optional<VertexAccessor> *vertex, Transaction *tx, View view, Indices *indices,
Constraints *constraints, Config::Items config) {
while (it != end) {
*vertex = VertexAccessor::Create(&*it, tx, indices, constraints, config, view);
if (!*vertex) {
if (not VertexAccessor::IsVisible(&*it, tx, view)) {
++it;
continue;
}
*vertex = VertexAccessor{&*it, tx, indices, constraints, config};
break;
}
return it;
@ -32,7 +32,7 @@ AllVerticesIterable::Iterator::Iterator(AllVerticesIterable *self, utils::SkipLi
it_(AdvanceToVisibleVertex(it, self->vertices_accessor_.end(), &self->vertex_, self->transaction_, self->view_,
self->indices_, self_->constraints_, self->config_)) {}
VertexAccessor AllVerticesIterable::Iterator::operator*() const { return *self_->vertex_; }
VertexAccessor const &AllVerticesIterable::Iterator::operator*() const { return *self_->vertex_; }
AllVerticesIterable::Iterator &AllVerticesIterable::Iterator::operator++() {
++it_;

View File

@ -33,7 +33,7 @@ class AllVerticesIterable final {
public:
Iterator(AllVerticesIterable *self, utils::SkipList<Vertex>::Iterator it);
VertexAccessor operator*() const;
VertexAccessor const &operator*() const;
Iterator &operator++();

View File

@ -67,7 +67,7 @@ class InMemoryLabelIndex : public storage::LabelIndex {
public:
Iterator(Iterable *self, utils::SkipList<Entry>::Iterator index_iterator);
VertexAccessor operator*() const { return current_vertex_accessor_; }
VertexAccessor const &operator*() const { return current_vertex_accessor_; }
bool operator==(const Iterator &other) const { return index_iterator_ == other.index_iterator_; }
bool operator!=(const Iterator &other) const { return index_iterator_ != other.index_iterator_; }

View File

@ -74,7 +74,7 @@ class InMemoryLabelPropertyIndex : public storage::LabelPropertyIndex {
public:
Iterator(Iterable *self, utils::SkipList<Entry>::Iterator index_iterator);
VertexAccessor operator*() const { return current_vertex_accessor_; }
VertexAccessor const &operator*() const { return current_vertex_accessor_; }
bool operator==(const Iterator &other) const { return index_iterator_ == other.index_iterator_; }
bool operator!=(const Iterator &other) const { return index_iterator_ != other.index_iterator_; }

View File

@ -84,6 +84,11 @@ std::optional<VertexAccessor> VertexAccessor::Create(Vertex *vertex, Transaction
return VertexAccessor{vertex, transaction, indices, constraints, config};
}
bool VertexAccessor::IsVisible(const Vertex *vertex, const Transaction *transaction, View view) {
const auto [exists, deleted] = detail::IsVisible(vertex, transaction, view);
return exists && !deleted;
}
bool VertexAccessor::IsVisible(View view) const {
const auto [exists, deleted] = detail::IsVisible(vertex_, transaction_, view);
return exists && (for_deleted_ || !deleted);

View File

@ -45,6 +45,8 @@ class VertexAccessor final {
static std::optional<VertexAccessor> Create(Vertex *vertex, Transaction *transaction, Indices *indices,
Constraints *constraints, Config::Items config, View view);
static bool IsVisible(Vertex const *vertex, Transaction const *transaction, View view);
/// @return true if the object is visible from the current transaction
bool IsVisible(View view) const;

View File

@ -210,7 +210,7 @@ void VerticesIterable::Iterator::Destroy() noexcept {
}
}
VertexAccessor VerticesIterable::Iterator::operator*() const {
VertexAccessor const &VerticesIterable::Iterator::operator*() const {
switch (type_) {
case Type::ALL:
return *all_it_;

View File

@ -63,7 +63,7 @@ class VerticesIterable final {
~Iterator();
VertexAccessor operator*() const;
VertexAccessor const &operator*() const;
Iterator &operator++();