blob: aeff2e1316119a9d03b23c15c861dd360b659072 [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_COMPRESSED_PACKED_ROW_STORE_VALUE_ACCESSOR_HPP_
#define QUICKSTEP_STORAGE_COMPRESSED_PACKED_ROW_STORE_VALUE_ACCESSOR_HPP_
#include <cstddef>
#include <cstdint>
#include <vector>
#include "catalog/CatalogRelationSchema.hpp"
#include "catalog/CatalogTypedefs.hpp"
#include "compression/CompressionDictionaryLite.hpp"
#include "storage/StorageBlockInfo.hpp"
#include "storage/StorageBlockLayout.pb.h"
#include "storage/ValueAccessor.hpp"
#include "types/Type.hpp"
#include "types/TypedValue.hpp"
#include "utility/BitVector.hpp"
#include "utility/Macros.hpp"
#include "utility/PtrMap.hpp"
namespace quickstep {
class CompressedPackedRowStoreTupleStorageSubBlock;
class CompressedPackedRowStoreValueAccessorHelper {
public:
CompressedPackedRowStoreValueAccessorHelper(
const CatalogRelationSchema &relation,
const tuple_id num_tuples,
const std::size_t tuple_length_bytes,
const std::vector<std::size_t> &attribute_offsets,
const CompressedBlockInfo &compression_info,
const std::vector<bool> &dictionary_coded_attributes,
const std::vector<bool> &truncated_attributes,
const std::vector<bool> &truncated_attribute_is_int,
const PtrMap<attribute_id, CompressionDictionaryLite> &dictionaries,
const void *tuple_storage,
const BitVector<false> *null_bitmap,
const attribute_id num_uncompressed_attributes_with_nulls,
const std::vector<attribute_id> &null_bitmap_attribute_offsets)
: relation_(relation),
num_tuples_(num_tuples),
tuple_length_bytes_(tuple_length_bytes),
attribute_offsets_(attribute_offsets),
compression_info_(compression_info),
dictionary_coded_attributes_(dictionary_coded_attributes),
truncated_attributes_(truncated_attributes),
truncated_attribute_is_int_(truncated_attribute_is_int),
dictionaries_(dictionaries),
tuple_storage_(tuple_storage),
null_bitmap_(null_bitmap),
num_uncompressed_attributes_with_nulls_(num_uncompressed_attributes_with_nulls),
null_bitmap_attribute_offsets_(null_bitmap_attribute_offsets) {
}
inline tuple_id numPackedTuples() const {
return num_tuples_;
}
/**
* @brief Returns whether this accessor has a fast strided ColumnAccessor available
* that can be used to optimize memory access in a tight loop iteration
* over the underlying storage block.
*
* @return true if fast ColumnAccessor is supported, otherwise false.
*/
inline bool isColumnAccessorSupported() const {
return false;
}
/**
* @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 current_tuple_position A constant reference to the tuple position in the containing
* ValueAccessor. This reference value is shared between the containing ValueAccessor &
* a ColumnAccessor. However, a ColumnAccessor *CANNOT* modify this tuple position.
* @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 tuple_id &current_tuple_position,
const attribute_id attr_id) const {
// Return nullptr because this value accessor does not support column accessor yet.
return nullptr;
}
template <bool check_null>
inline const void* getAttributeValue(const tuple_id tuple,
const attribute_id attr) const {
if (dictionary_coded_attributes_[attr]) {
return dictionaries_.atUnchecked(attr).getUntypedValueForCode<check_null>(
getCode(tuple, attr));
} else if (truncated_attributes_[attr]) {
if (truncated_attribute_is_int_[attr]) {
int_buffer_ = getCode(tuple, attr);
return &int_buffer_;
} else {
long_buffer_ = getCode(tuple, attr);
return &long_buffer_;
}
} else {
return getAttributePtr<check_null>(tuple, attr);
}
}
inline TypedValue getAttributeValueTyped(const tuple_id tuple,
const attribute_id attr) const {
if (dictionary_coded_attributes_[attr]) {
return dictionaries_.atUnchecked(attr).getTypedValueForCode(
getCode(tuple, attr));
} else if (truncated_attributes_[attr]) {
if (truncated_attribute_is_int_[attr]) {
return TypedValue(static_cast<int>(getCode(tuple, attr)));
} else {
return TypedValue(static_cast<std::int64_t>(getCode(tuple, attr)));
}
} else {
const Type &attr_type = relation_.getAttributeById(attr)->getType();
const void *untyped_value = getAttributePtr<true>(tuple, attr);
return (untyped_value == nullptr)
? attr_type.makeNullValue()
: attr_type.makeValue(untyped_value, attr_type.maximumByteLength());
}
}
private:
template <bool check_null>
inline const void* getAttributePtr(const tuple_id tid,
const attribute_id attr_id) const {
if (check_null
&& compression_info_.uncompressed_attribute_has_nulls(attr_id)
&& null_bitmap_->getBit(tid * num_uncompressed_attributes_with_nulls_
+ null_bitmap_attribute_offsets_[attr_id])) {
return nullptr;
} else {
return static_cast<const char*>(tuple_storage_)
+ tid * tuple_length_bytes_
+ attribute_offsets_[attr_id];
}
}
inline std::uint32_t getCode(const tuple_id tid,
const attribute_id attr_id) const {
const void *code_location = getAttributePtr<false>(tid, attr_id);
switch (compression_info_.attribute_size(attr_id)) {
case 1:
return *static_cast<const std::uint8_t*>(code_location);
case 2:
return *static_cast<const std::uint16_t*>(code_location);
case 4:
return *static_cast<const std::uint32_t*>(code_location);
default:
FATAL_ERROR("Unexpected byte-length (not 1, 2, or 4) for compressed "
"attribute ID " << attr_id
<< " in CompressedPackedRowStoreValueAccessorHelper::getCode()");
}
}
const CatalogRelationSchema &relation_;
const tuple_id num_tuples_;
const std::size_t tuple_length_bytes_;
const std::vector<std::size_t> &attribute_offsets_;
const CompressedBlockInfo &compression_info_;
const std::vector<bool> &dictionary_coded_attributes_;
const std::vector<bool> &truncated_attributes_;
const std::vector<bool> &truncated_attribute_is_int_;
const PtrMap<attribute_id, CompressionDictionaryLite> &dictionaries_;
const void *tuple_storage_;
const BitVector<false> *null_bitmap_;
const attribute_id num_uncompressed_attributes_with_nulls_;
const std::vector<attribute_id> &null_bitmap_attribute_offsets_;
mutable int int_buffer_;
mutable std::int64_t long_buffer_;
DISALLOW_COPY_AND_ASSIGN(CompressedPackedRowStoreValueAccessorHelper);
};
typedef PackedTupleStorageSubBlockValueAccessor<
CompressedPackedRowStoreTupleStorageSubBlock,
CompressedPackedRowStoreValueAccessorHelper,
ValueAccessor::Implementation::kCompressedPackedRowStore>
CompressedPackedRowStoreValueAccessor;
} // namespace quickstep
#endif // QUICKSTEP_STORAGE_COMPRESSED_PACKED_ROW_STORE_VALUE_ACCESSOR_HPP_