blob: 496915667aaa2c52acf7e1c2374f1dcffb542256 [file] [log] [blame]
/**
* 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_STORAGE_VALUE_ACCESSOR_UTIL_HPP_
#define QUICKSTEP_STORAGE_VALUE_ACCESSOR_UTIL_HPP_
#include <type_traits>
#include "storage/BasicColumnStoreValueAccessor.hpp"
#include "storage/CompressedColumnStoreValueAccessor.hpp"
#include "storage/CompressedPackedRowStoreValueAccessor.hpp"
#include "storage/SplitRowStoreValueAccessor.hpp"
#include "storage/ValueAccessor.hpp"
#include "types/containers/ColumnVectorsValueAccessor.hpp"
#include "utility/Macros.hpp"
#include "glog/logging.h"
namespace quickstep {
/** \addtogroup Storage
* @{
*/
/**
* @brief Invoke a generic functor (or lambda) on a ValueAccessor (known not to
* be an adapter) that is downcast to its actual concrete type.
* @note This is intended for cases where it is known that a ValueAccessor will
* never be a TupleIdSequenceAdapterValueAccessor or
* OrderedTupleIdSequenceAdapterValueAccessor. If in doubt, consider
* using InvokeOnValueAccessorMaybeTupleIdSequenceAdapter() or
* InvokeOnAnyValueAccessor() instead.
*
* @param accessor A pointer to a ValueAccessor that will be downcast to its
* concrete type so that inline methods can be used.
* @param functor A generic functor or lambda that has a templated call
* operator taking a single argument. The call operator will be invoked
* with the downcast accessor (as a mutable pointer) as its argument.
* @return The return value of functor's call operator applied to the downcast
* accessor pointer.
**/
template <typename FunctorT>
auto InvokeOnValueAccessorNotAdapter(
ValueAccessor *accessor,
const FunctorT &functor) {
DCHECK(!accessor->isTupleIdSequenceAdapter());
DCHECK(!accessor->isOrderedTupleIdSequenceAdapter());
switch (accessor->getImplementationType()) {
case ValueAccessor::Implementation::kBasicColumnStore:
return functor(static_cast<BasicColumnStoreValueAccessor*>(accessor));
case ValueAccessor::Implementation::kCompressedColumnStore:
return functor(static_cast<CompressedColumnStoreValueAccessor*>(accessor));
case ValueAccessor::Implementation::kCompressedPackedRowStore:
return functor(static_cast<CompressedPackedRowStoreValueAccessor*>(accessor));
case ValueAccessor::Implementation::kSplitRowStore:
return functor(static_cast<SplitRowStoreValueAccessor*>(accessor));
case ValueAccessor::Implementation::kColumnVectors:
return functor(static_cast<ColumnVectorsValueAccessor*>(accessor));
default: {
LOG(FATAL) << "Unrecognized ValueAccessor::Implementation: "
<< static_cast<std::underlying_type<ValueAccessor::Implementation>::type>(
accessor->getImplementationType());
}
}
}
/**
* @brief Invoke a generic functor (or lambda) on a ValueAccessor (known to be
* a TupleIdSequenceAdapterValueAccessor) that is downcast to its actual
* concrete type.
* @note This is intended for cases where it is known that a ValueAccessor is
* definitely a TupleIdSequenceAdapterValueAccessor. If in doubt,
* consinder using InvokeOnValueAccessorMaybeTupleIdSequenceAdapter() or
* InvokeOnAnyValueAccessor() instead.
*
* @param accessor A pointer to a ValueAccessor that will be downcast to its
* concrete type so that inline methods can be used.
* @param functor A generic functor or lambda that has a templated call
* operator taking a single argument. The call operator will be invoked
* with the downcast accessor (as a mutable pointer) as its argument.
* @return The return value of functor's call operator applied to the downcast
* accessor pointer.
**/
template <typename FunctorT>
auto InvokeOnTupleIdSequenceAdapterValueAccessor(
ValueAccessor *accessor,
const FunctorT &functor) {
DCHECK(accessor->isTupleIdSequenceAdapter());
DCHECK(!accessor->isOrderedTupleIdSequenceAdapter());
switch (accessor->getImplementationType()) {
case ValueAccessor::Implementation::kBasicColumnStore:
return functor(
static_cast<TupleIdSequenceAdapterValueAccessor<BasicColumnStoreValueAccessor>*>(
accessor));
case ValueAccessor::Implementation::kCompressedColumnStore:
return functor(
static_cast<TupleIdSequenceAdapterValueAccessor<CompressedColumnStoreValueAccessor>*>(
accessor));
case ValueAccessor::Implementation::kCompressedPackedRowStore:
return functor(
static_cast<TupleIdSequenceAdapterValueAccessor<CompressedPackedRowStoreValueAccessor>*>(
accessor));
case ValueAccessor::Implementation::kSplitRowStore:
return functor(
static_cast<TupleIdSequenceAdapterValueAccessor<SplitRowStoreValueAccessor>*>(
accessor));
case ValueAccessor::Implementation::kColumnVectors:
return functor(
static_cast<TupleIdSequenceAdapterValueAccessor<ColumnVectorsValueAccessor>*>(
accessor));
default: {
LOG(FATAL) << "Unrecognized ValueAccessor::Implementation: "
<< static_cast<std::underlying_type<ValueAccessor::Implementation>::type>(
accessor->getImplementationType());
}
}
}
/**
* @brief Invoke a generic functor (or lambda) on a ValueAccessor (known to be
* an OrderedTupleIdSequenceAdapterValueAccessor) that is downcast to
* its actual concrete type.
* @note This is intended for cases where it is known that a ValueAccessor is
* definitely an OrderedTupleIdSequenceAdapterValueAccessor. If in doubt,
* consinder using InvokeOnAnyValueAccessor() instead.
*
* @param accessor A pointer to a ValueAccessor that will be downcast to its
* concrete type so that inline methods can be used.
* @param functor A generic functor or lambda that has a templated call
* operator taking a single argument. The call operator will be invoked
* with the downcast accessor (as a mutable pointer) as its argument.
* @return The return value of functor's call operator applied to the downcast
* accessor pointer.
**/
template <typename FunctorT>
auto InvokeOnOrderedTupleIdSequenceAdapterValueAccessor(
ValueAccessor *accessor,
const FunctorT &functor) {
DCHECK(!accessor->isTupleIdSequenceAdapter());
DCHECK(accessor->isOrderedTupleIdSequenceAdapter());
switch (accessor->getImplementationType()) {
case ValueAccessor::Implementation::kBasicColumnStore:
return functor(
static_cast<OrderedTupleIdSequenceAdapterValueAccessor<BasicColumnStoreValueAccessor>*>(
accessor));
case ValueAccessor::Implementation::kCompressedColumnStore:
return functor(
static_cast<OrderedTupleIdSequenceAdapterValueAccessor<CompressedColumnStoreValueAccessor>*>(
accessor));
case ValueAccessor::Implementation::kCompressedPackedRowStore:
return functor(
static_cast<OrderedTupleIdSequenceAdapterValueAccessor<CompressedPackedRowStoreValueAccessor>*>(
accessor));
case ValueAccessor::Implementation::kSplitRowStore:
return functor(
static_cast<OrderedTupleIdSequenceAdapterValueAccessor<SplitRowStoreValueAccessor>*>(
accessor));
case ValueAccessor::Implementation::kColumnVectors:
return functor(
static_cast<OrderedTupleIdSequenceAdapterValueAccessor<ColumnVectorsValueAccessor>*>(
accessor));
default: {
LOG(FATAL) << "Unrecognized ValueAccessor::Implementation: "
<< static_cast<std::underlying_type<ValueAccessor::Implementation>::type>(
accessor->getImplementationType());
}
}
}
/**
* @brief Invoke a generic functor (or lambda) on a ValueAccessor that is
* downcast to its actual concrete type.
* @note This version of this function may be used with a non-adapter
* ValueAccessor OR a TupleIdSequenceAdapterValueAccessor. The only place
* where it is not safe to use is in the bulk-insert path for inserting
* tuples into StorageBlock(s) via an InsertDestination (in such cases,
* an OrderedTupleIdSequenceAdapterValueAccessor is also possible as we
* may be bulk-inserting tuples sorted from a block without an
* intermediate copy). For that code path, the completely generic
* InvokeOnAnyValueAccessor() is available.
* @note If it is known that a ValueAccessor will never be an adapter, using
* InvokeOnValueAccessorNotAdapter() instead will result in more compact
* code that compiles faster.
*
* @param accessor A pointer to a ValueAccessor that will be downcast to its
* concrete type so that inline methods can be used.
* @param functor A generic functor or lambda that has a templated call
* operator taking a single argument. The call operator will be invoked
* with the downcast accessor (as a mutable pointer) as its argument.
* @return The return value of functor's call operator applied to the downcast
* accessor pointer.
**/
template <typename FunctorT>
auto InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
ValueAccessor *accessor,
const FunctorT &functor) {
if (accessor->isTupleIdSequenceAdapter()) {
return InvokeOnTupleIdSequenceAdapterValueAccessor(accessor, functor);
} else {
return InvokeOnValueAccessorNotAdapter(accessor, functor);
}
}
/**
* @brief Invoke a generic functor (or lambda) on a ValueAccessor that is
* downcast to its actual concrete type.
* @note This is the most general version of this function, and is suitable for
* use with ANY ValueAccessor. Other functions in this file are more
* specific and may be used when more a priori information about the
* ValueAccessor is known to generate more compact, faster-compiling
* code.
* @note The only situation where ANY type of ValueAccessor is possible is
* bulk-inserting into StorageBlock(s) via an InsertDestination. An
* OrderedTupleIdSequenceAdapterValueAccessor will not be used in any
* other situation, so it is at least safe to use
* InvokeOnValueAccessorMaybeTupleIdSequenceAdapter() everywhere else.
* Depending on the context, it may also be safe to use
* InvokeOnValueAccessorNotAdapter() for even more compact code.
*
* @param accessor A pointer to a ValueAccessor that will be downcast to its
* concrete type so that inline methods can be used.
* @param functor A generic functor or lambda that has a templated call
* operator taking a single argument. The call operator will be invoked
* with the downcast accessor (as a mutable pointer) as its argument.
* @return The return value of functor's call operator applied to the downcast
* accessor pointer.
**/
template <typename FunctorT>
auto InvokeOnAnyValueAccessor(
ValueAccessor *accessor,
const FunctorT &functor) {
if (accessor->isTupleIdSequenceAdapter()) {
return InvokeOnTupleIdSequenceAdapterValueAccessor(accessor, functor);
} else if (accessor->isOrderedTupleIdSequenceAdapter()) {
return InvokeOnOrderedTupleIdSequenceAdapterValueAccessor(accessor, functor);
} else {
return InvokeOnValueAccessorNotAdapter(accessor, functor);
}
}
/** @} */
} // namespace quickstep
#endif // QUICKSTEP_STORAGE_VALUE_ACCESSOR_UTIL_HPP_