blob: f1d29a2ed5d68969b86c65f334a006ee12174ebd [file] [log] [blame]
/**
* Copyright 2011-2015 Quickstep Technologies LLC.
* Copyright 2015 Pivotal Software, Inc.
*
* Licensed 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 "utility/ScopedDeleter.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(ColumnVector *column, const bool owns = true) {
// If this is not the first column to be added, make sure it is the same
// length as the others.
DCHECK(columns_.empty()
|| (column->isNative()
? (static_cast<const NativeColumnVector*>(column)->size() == column_length_)
: (static_cast<const IndirectColumnVector*>(column)->size() == column_length_)));
columns_.push_back(column);
column_native_.push_back(column->isNative());
if (owns) {
deleter_.addObject(column);
}
column_length_
= column->isNative()
? static_cast<const NativeColumnVector*>(column)->size()
: static_cast<const IndirectColumnVector*>(column)->size();
}
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_;
}
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);
}
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<ColumnVector*> columns_;
std::vector<bool> column_native_;
std::size_t column_length_;
std::size_t current_position_;
ScopedDeleter deleter_;
DISALLOW_COPY_AND_ASSIGN(ColumnVectorsValueAccessor);
};
} // namespace quickstep
#endif // QUICKSTEP_TYPES_CONTAINERS_COLUMN_VECTORS_VALUE_ACCESSOR_HPP_