Add version ValidFramesModifier to distinguish between reading-only and reading+modifying

This commit is contained in:
jeremy 2022-11-29 11:05:11 +01:00
parent 8f19ce88d9
commit e946eb50d2
4 changed files with 78 additions and 8 deletions

View File

@ -737,7 +737,7 @@ std::optional<plan::ProfilingStatsWithTotalTime> PullPlan::PullMultiple(AnyStrea
return multi_frame_.HasValidFrame();
};
const auto stream_values = [&output_symbols, &stream](Frame &frame) {
const auto stream_values = [&output_symbols, &stream](const Frame &frame) {
// TODO: The streamed values should also probably use the above memory.
std::vector<TypedValue> values;
values.reserve(output_symbols.size());

View File

@ -80,6 +80,8 @@ void MultiFrame::DefragmentValidFrames() noexcept {
ValidFramesReader MultiFrame::GetValidFramesReader() { return ValidFramesReader(*this); }
ValidFramesModifier MultiFrame::GetValidFramesModifier() { return ValidFramesModifier(*this); }
ValidFramesInvalidator MultiFrame::GetValidFramesInvalidator() { return ValidFramesInvalidator(*this); }
InvalidFramesPopulator MultiFrame::GetInvalidFramesPopulator() { return InvalidFramesPopulator(*this); }
@ -93,6 +95,15 @@ ValidFramesReader::Iterator ValidFramesReader::end() {
return Iterator(&multiframe_.frames_[multiframe_.frames_.size()], *this);
}
ValidFramesModifier::ValidFramesModifier(MultiFrame &multiframe) : multiframe_(multiframe) {}
ValidFramesModifier::~ValidFramesModifier() = default;
ValidFramesModifier::Iterator ValidFramesModifier::begin() { return Iterator(&multiframe_.frames_[0], *this); }
ValidFramesModifier::Iterator ValidFramesModifier::end() {
return Iterator(&multiframe_.frames_[multiframe_.frames_.size()], *this);
}
ValidFramesInvalidator::ValidFramesInvalidator(MultiFrame &multiframe) : multiframe_(multiframe) {}
ValidFramesInvalidator::~ValidFramesInvalidator() {

View File

@ -18,14 +18,16 @@
namespace memgraph::query::v2 {
constexpr unsigned long kNumberOfFramesInMultiframe = 1000; // #NoCommit have it configurable
class ValidFramesReader;
class ValidFramesInvalidator;
class ValidFramesModifier;
class ValidFramesReader;
class InvalidFramesPopulator;
class MultiFrame {
public:
friend class ValidFramesReader;
friend class ValidFramesInvalidator;
friend class ValidFramesModifier;
friend class ValidFramesReader;
friend class InvalidFramesPopulator;
MultiFrame(FrameWithValidity default_frame, size_t number_of_frames, utils::MemoryResource *execution_memory);
@ -40,16 +42,25 @@ class MultiFrame {
Returns a object on which one can iterate in a for-loop. By doing so, you will only get frames that are in a valid
state in the multiframe.
Iteration goes in a deterministic order.
One can't modify the validity of the frame with this implementation.
One can't modify the validity of the frame nor its content with this implementation.
*/
ValidFramesReader GetValidFramesReader();
/*!
Returns a object on which one can iterate in a for-loop. By doing so, you will only get frames that are in a valid
state in the multiframe.
Iteration goes in a deterministic order.
One can't modify the validity of the frame with this implementation. One can modify its content.
*/
ValidFramesModifier GetValidFramesModifier();
/*!
Returns a object on which one can iterate in a for-loop. By doing so, you will only get frames that are in a valid
state in the multiframe.
Iteration goes in a deterministic order.
One can modify the validity of the frame with this implementation.
If you do not plan to modify the validity of the frames, use GetValidFramesReader instead as this is faster.
If you do not plan to modify the validity of the frames, use GetValidFramesReader/GetValidFramesModifer instead as
this is faster.
*/
ValidFramesInvalidator GetValidFramesInvalidator();
@ -88,9 +99,9 @@ class ValidFramesReader {
struct Iterator {
using iterator_category = std::forward_iterator_tag;
using difference_type = std::ptrdiff_t;
using value_type = Frame;
using value_type = const Frame;
using pointer = value_type *;
using reference = Frame &;
using reference = const Frame &;
using internal_ptr = FrameWithValidity *;
Iterator(internal_ptr ptr, ValidFramesReader &iterator_wrapper) : ptr_(ptr), iterator_wrapper_(iterator_wrapper) {}
@ -122,6 +133,54 @@ class ValidFramesReader {
MultiFrame &multiframe_;
};
class ValidFramesModifier {
public:
ValidFramesModifier(MultiFrame &multiframe);
~ValidFramesModifier();
ValidFramesModifier(const ValidFramesModifier &other) = delete; // copy constructor
ValidFramesModifier(ValidFramesModifier &&other) noexcept = delete; // move constructor
ValidFramesModifier &operator=(const ValidFramesModifier &other) = delete; // copy assignment
ValidFramesModifier &operator=(ValidFramesModifier &&other) noexcept = delete; // move assignment
struct Iterator {
using iterator_category = std::forward_iterator_tag;
using difference_type = std::ptrdiff_t;
using value_type = Frame;
using pointer = value_type *;
using reference = Frame &;
using internal_ptr = FrameWithValidity *;
Iterator(internal_ptr ptr, ValidFramesModifier &iterator_wrapper)
: ptr_(ptr), iterator_wrapper_(iterator_wrapper) {}
reference operator*() const { return *ptr_; }
pointer operator->() { return ptr_; }
// Prefix increment
Iterator &operator++() {
do {
ptr_++;
} while (!this->ptr_->IsValid() && *this != iterator_wrapper_.end());
return *this;
}
friend bool operator==(const Iterator &a, const Iterator &b) { return a.ptr_ == b.ptr_; };
friend bool operator!=(const Iterator &a, const Iterator &b) { return a.ptr_ != b.ptr_; };
private:
internal_ptr ptr_;
ValidFramesModifier &iterator_wrapper_;
};
Iterator begin();
Iterator end();
private:
MultiFrame &multiframe_;
};
class ValidFramesInvalidator {
public:
ValidFramesInvalidator(MultiFrame &multiframe);

View File

@ -768,7 +768,7 @@ void Produce::ProduceCursor::PullMultiple(MultiFrame &multi_frame, ExecutionCont
input_cursor_->PullMultiple(multi_frame, context);
auto iterator_for_valid_frame_only = multi_frame.GetValidFramesReader();
auto iterator_for_valid_frame_only = multi_frame.GetValidFramesModifier();
for (auto &frame : iterator_for_valid_frame_only) {
// Produce should always yield the latest results.
ExpressionEvaluator evaluator(&frame, context.symbol_table, context.evaluation_context,