| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| **/ |
| |
| #ifndef QUICKSTEP_TYPES_CONTAINERS_COLUMN_VECTORS_VALUE_ACCESSOR_HPP_ |
| #define QUICKSTEP_TYPES_CONTAINERS_COLUMN_VECTORS_VALUE_ACCESSOR_HPP_ |
| |
| #include <cstddef> |
| #include <limits> |
| #include <utility> |
| #include <vector> |
| |
| #include "catalog/CatalogTypedefs.hpp" |
| #include "storage/StorageBlockInfo.hpp" |
| #include "storage/ValueAccessor.hpp" |
| #include "types/TypedValue.hpp" |
| #include "types/containers/ColumnVector.hpp" |
| #include "types/containers/Tuple.hpp" |
| #include "utility/Macros.hpp" |
| |
| #include "glog/logging.h" |
| |
| namespace quickstep { |
| |
| class TupleIdSequence; |
| |
| /** |
| * @brief Implementation of ValueAccessor as a group of equal-length |
| * ColumnVectors (one per "attribute"). |
| **/ |
| class ColumnVectorsValueAccessor : public ValueAccessor { |
| public: |
| ColumnVectorsValueAccessor() |
| : column_length_(0), |
| current_position_(std::numeric_limits<std::size_t>::max()) { |
| } |
| |
| ~ColumnVectorsValueAccessor() override { |
| } |
| |
| Implementation getImplementationType() const override { |
| return Implementation::kColumnVectors; |
| } |
| |
| bool isTupleIdSequenceAdapter() const override { |
| return false; |
| } |
| |
| bool isOrderedTupleIdSequenceAdapter() const override { |
| return false; |
| } |
| |
| /** |
| * @brief Adds a column vector as an attribute to the value-accessor. |
| * |
| * @param column Column vector added to this value-accessor. |
| * @param owns Whether this value-accessor owns this column vector. If true, |
| * this value-accessor is responsible for freeing this column |
| * vector. |
| **/ |
| void addColumn(ColumnVectorPtr column) { |
| // If this is not the first column to be added, make sure it is the same |
| // length as the others. |
| DCHECK(columns_.empty() || column->size() == column_length_); |
| columns_.push_back(column); |
| column_native_.push_back(column->isNative()); |
| column_length_ = column->size(); |
| } |
| |
| void addColumn(ColumnVector *column) { |
| addColumn(ColumnVectorPtr(column)); |
| } |
| |
| inline void beginIteration() { |
| current_position_ = std::numeric_limits<std::size_t>::max(); |
| } |
| |
| inline bool iterationFinished() const { |
| return current_position_ + 1 >= column_length_; |
| } |
| |
| inline bool next() { |
| ++current_position_; |
| return current_position_ < column_length_; |
| } |
| |
| inline void previous() { |
| --current_position_; |
| } |
| |
| inline tuple_id getCurrentPosition() const { |
| return current_position_; |
| } |
| |
| inline tuple_id getEndPosition() const { |
| return column_length_; |
| } |
| |
| inline tuple_id getNumTuples() const { |
| return column_length_; |
| } |
| |
| /** |
| * @brief Get a pointer to a ColumnAccessor object that provides a fast strided memory |
| * access on the underlying storage block. |
| * @note The ownership of the returned object lies with the caller. |
| * @warning This method should only be called if isColumnAccessorSupported() method |
| * returned true. If ColumnAccessor is not supported this method will return a nullptr. |
| * |
| * @param attr_id The attribute id on which this ColumnAccessor will be created. |
| * |
| * @return A pointer to a ColumnAccessor object with specific properties set that can be used |
| * in a tight loop iterations over the underlying storage block. |
| **/ |
| template <bool check_null = true> |
| inline const ColumnAccessor<check_null>* getColumnAccessor(const attribute_id attr_id) const { |
| // Column Accessors are currently unsupported for this value accessor, hence nullptr. |
| return nullptr; |
| } |
| |
| inline std::size_t getNumColumns() const { |
| return columns_.size(); |
| } |
| |
| template <bool check_null = true> |
| inline const void* getUntypedValue(const attribute_id attr_id) const { |
| return getUntypedValueAtAbsolutePosition<check_null>(attr_id, current_position_); |
| } |
| |
| inline TypedValue getTypedValue(const attribute_id attr_id) const { |
| return getTypedValueAtAbsolutePosition(attr_id, current_position_); |
| } |
| |
| template <bool check_null = true> |
| inline const void* getUntypedValueAtAbsolutePosition(const attribute_id attr_id, |
| const tuple_id tid) const { |
| DCHECK(attributeIdInRange(attr_id)); |
| DCHECK(tupleIdInRange(tid)); |
| if (column_native_[attr_id]) { |
| return static_cast<const NativeColumnVector&>(*columns_[attr_id]).getUntypedValue<check_null>(tid); |
| } else { |
| return static_cast<const IndirectColumnVector&>(*columns_[attr_id]).getUntypedValue<check_null>(tid); |
| } |
| } |
| |
| inline TypedValue getTypedValueAtAbsolutePosition(const attribute_id attr_id, |
| const tuple_id tid) const { |
| DCHECK(attributeIdInRange(attr_id)); |
| DCHECK(tupleIdInRange(tid)); |
| if (column_native_[attr_id]) { |
| return static_cast<const NativeColumnVector&>(*columns_[attr_id]) |
| .getTypedValue(tid) |
| .makeReferenceToThis(); |
| } else { |
| return static_cast<const IndirectColumnVector&>(*columns_[attr_id]) |
| .getTypedValue(tid) |
| .makeReferenceToThis(); |
| } |
| } |
| |
| inline Tuple* getTuple() const { |
| return getTupleAtAbsolutePosition(current_position_); |
| } |
| |
| inline Tuple* getTupleWithAttributes(const std::vector<attribute_id> &attributes) const { |
| return getTupleAtAbsolutePositionWithAttributes(current_position_, attributes); |
| } |
| |
| inline Tuple* getTupleAtAbsolutePosition(const tuple_id tid) const { |
| DCHECK(tupleIdInRange(tid)); |
| std::vector<TypedValue> values; |
| for (attribute_id attr_id = 0; |
| attr_id < static_cast<attribute_id>(columns_.size()); |
| ++attr_id) { |
| values.emplace_back(getTypedValueAtAbsolutePosition(attr_id, tid)); |
| } |
| return new Tuple(std::move(values)); |
| } |
| |
| inline Tuple* getTupleAtAbsolutePositionWithAttributes( |
| const tuple_id tid, |
| const std::vector<attribute_id> &attributes) const { |
| DCHECK(tupleIdInRange(tid)); |
| std::vector<TypedValue> values; |
| for (const attribute_id attr_id : attributes) { |
| values.emplace_back(getTypedValueAtAbsolutePosition(attr_id, tid)); |
| } |
| return new Tuple(std::move(values)); |
| } |
| |
| inline TupleIdSequenceAdapterValueAccessor<ColumnVectorsValueAccessor>* |
| createSharedTupleIdSequenceAdapter(const TupleIdSequence &id_sequence) { |
| return new TupleIdSequenceAdapterValueAccessor<ColumnVectorsValueAccessor>( |
| this, |
| id_sequence, |
| false); |
| } |
| |
| inline OrderedTupleIdSequenceAdapterValueAccessor<ColumnVectorsValueAccessor>* |
| createSharedOrderedTupleIdSequenceAdapter(const OrderedTupleIdSequence& id_sequence) { |
| return new OrderedTupleIdSequenceAdapterValueAccessor<ColumnVectorsValueAccessor>(this, id_sequence, false); |
| } |
| |
| inline const TupleIdSequence* getTupleIdSequence() const { |
| return nullptr; |
| } |
| |
| // Implementation of virtuals that pass-through to the inline |
| // implementations. |
| void beginIterationVirtual() override { |
| beginIteration(); |
| } |
| |
| bool iterationFinishedVirtual() const override { |
| return iterationFinished(); |
| } |
| |
| bool nextVirtual() override { |
| return next(); |
| } |
| |
| void previousVirtual() override { |
| previous(); |
| } |
| |
| tuple_id getCurrentPositionVirtual() const override { |
| return getCurrentPosition(); |
| } |
| |
| tuple_id getEndPositionVirtual() const override { |
| return getEndPosition(); |
| } |
| |
| tuple_id getNumTuplesVirtual() const override { |
| return getNumTuples(); |
| } |
| |
| const void* getUntypedValueVirtual(const attribute_id attr_id) const override { |
| return getUntypedValue(attr_id); |
| } |
| |
| TypedValue getTypedValueVirtual(const attribute_id attr_id) const override { |
| return getTypedValue(attr_id); |
| } |
| |
| const void* getUntypedValueAtAbsolutePositionVirtual( |
| const attribute_id attr_id, |
| const tuple_id tid) const override { |
| return getUntypedValueAtAbsolutePosition(attr_id, tid); |
| } |
| |
| TypedValue getTypedValueAtAbsolutePositionVirtual( |
| const attribute_id attr_id, |
| const tuple_id tid) const override { |
| return getTypedValueAtAbsolutePosition(attr_id, tid); |
| } |
| |
| Tuple* getTupleVirtual() const override { |
| return getTuple(); |
| } |
| |
| Tuple* getTupleWithAttributesVirtual( |
| const std::vector<attribute_id> &attributes) const override { |
| return getTupleWithAttributes(attributes); |
| } |
| |
| ValueAccessor* createSharedTupleIdSequenceAdapterVirtual( |
| const TupleIdSequence &id_sequence) override { |
| return createSharedTupleIdSequenceAdapter(id_sequence); |
| } |
| |
| ValueAccessor* createSharedOrderedTupleIdSequenceAdapterVirtual( |
| const OrderedTupleIdSequence &id_sequence) override { |
| return createSharedOrderedTupleIdSequenceAdapter(id_sequence); |
| } |
| |
| const TupleIdSequence* getTupleIdSequenceVirtual() const override { |
| return getTupleIdSequence(); |
| } |
| |
| private: |
| inline bool tupleIdInRange(const tuple_id tid) const { |
| return (tid >= 0) && (static_cast<std::size_t>(tid) < column_length_); |
| } |
| |
| inline bool attributeIdInRange(const attribute_id attr_id) const { |
| return (attr_id >= 0) |
| && (static_cast<std::vector<ColumnVector*>::size_type>(attr_id) < columns_.size()); |
| } |
| |
| std::vector<ColumnVectorPtr> columns_; |
| std::vector<bool> column_native_; |
| std::size_t column_length_; |
| std::size_t current_position_; |
| |
| DISALLOW_COPY_AND_ASSIGN(ColumnVectorsValueAccessor); |
| }; |
| |
| } // namespace quickstep |
| |
| #endif // QUICKSTEP_TYPES_CONTAINERS_COLUMN_VECTORS_VALUE_ACCESSOR_HPP_ |