blob: 0e66de6545eff77ad08ad7882ab33028ecb58e15 [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
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* See the License for the specific language governing permissions and
* limitations under the License.
#include <cstddef>
#include <unordered_map>
#include <vector>
#include "catalog/CatalogTypedefs.hpp"
#include "compression/CompressionDictionaryBuilder.hpp"
#include "storage/StorageBlockInfo.hpp"
#include "storage/StorageBlockLayout.pb.h"
#include "types/containers/Tuple.hpp"
#include "utility/BitVector.hpp"
#include "utility/Macros.hpp"
#include "utility/PtrMap.hpp"
#include "utility/PtrVector.hpp"
namespace quickstep {
class CatalogRelationSchema;
class TypedValue;
/** \addtogroup Storage
* @{
* @brief A helper class which temporarily stores tuples during batch-insertion
* and builds the physical contents of either a
* CompressedPackedRowStoreTupleStorageSubBlock or a
* CompressedColumnStoreTupleStorageSubBlock, automatically selecting
* most efficient coding for each compressed column (dictionary coding,
* truncation, or none).
class CompressedBlockBuilder {
* @brief Constructor.
* @param relation The relation which the compressed block being built
* belongs to.
* @param description The description for the TupleStorageSubBlock being
* built. The description must be valid and specify either
* sub_block_type.
* @param block_size The size in bytes of the TupleStorageSubBlock being
* built.
CompressedBlockBuilder(const CatalogRelationSchema &relation,
const TupleStorageSubBlockDescription &description,
const std::size_t block_size);
* @brief Destructor. A CompressedBlockBuilder should be deleted after the
* block is done being built to free any temporary memory.
~CompressedBlockBuilder() {
* @brief Check if an attribute may be compressed in the TupleStorageSubBlock
* ultimately build by this CompressedBlockBuilder.
* @note Even if this method returns true, the attribute specified might
* still be uncompressed when the block is built if compression fails
* to save any space.
* @param attr_id The ID of the attribute to check for possible compression.
* @return true if the attribute specified by attr_id might be compressed
* in a TupleStorageSubBlock built by this CompressedBlockBuilder,
* false if no compression will be attempted.
bool attributeMayBeCompressed(const attribute_id attr_id) const {
return dictionary_builders_.find(attr_id) != dictionary_builders_.end();
* @brief Add a Tuple to the block being built.
* @param tuple The Tuple to add. It will be copied.
* @return True if the tuple was successfully added, false if attempting to
* add the tuple failed because there would not be enough space to
* store it in the block being constructed. Typically,
* buildCompressedPackedRowStoreTupleStorageSubBlock() or
* buildCompressedColumnStoreTupleStorageSubBlock() would be called
* to actually construct the physical block after the first time this
* method returns false.
bool addTuple(const Tuple &tuple);
* @brief Similar to addTuple(), but takes ownership of an existing Tuple
* without copying it.
* @note Even if this method returns false, tuple will still be deleted by
* this CompressedBlockBuilder.
* @param tuple The Tuple to add.
* @return True if tuple was successfully added, false if out of space. See
* addTuple() for additional details.
bool takeTuple(Tuple *tuple) {
return addTupleInternal(tuple);
* @brief Get the number of Tuples held by this CompressedBlockBuilder for
* eventual inclusion in the compressed block being built.
* @return The number of tuples in this CompressedBlockBuilder.
inline std::size_t numTuples() const {
return tuples_.size();
* @brief Get the bare-minimum number of bytes needed to store just the
* metadata of a compressed block under construction, without any
* actual tuples.
* @return The minimum required memory for any TupleStorageSubBlock built
* by this CompressedBlockBuilder.
inline std::size_t getMinimumRequiredBlockSize() const {
return sizeof(tuple_id) + sizeof(int) + compression_info_.ByteSize();
* @brief Build a physical CompressedPackedRowStoreTupleStorageSubBlock with
* the tuples in this CompressedStorageSubBlock, automatically using
* the most-efficient compression method for each compressed column.
* @param sub_block_memory The physical memory location where the block will
* be stored. Must be at least as large as the block_size given to the
* constructor.
void buildCompressedPackedRowStoreTupleStorageSubBlock(void *sub_block_memory);
* @brief Build a physical CompressedColumnStoreTupleStorageSubBlock with
* the tuples in this CompressedStorageSubBlock, automatically using
* the most-efficient compression method for each compressed column.
* @param sub_block_memory The physical memory location where the block will
* be stored. Must be at least as large as the block_size given to the
* constructor.
void buildCompressedColumnStoreTupleStorageSubBlock(void *sub_block_memory);
bool addTupleInternal(Tuple *candidate_tuple);
std::size_t computeRequiredStorage(const std::size_t num_tuples) const;
std::size_t computeTruncatedByteLengthForAttribute(const attribute_id attr_id) const;
void rollbackLastInsert(
const std::vector<CompressionDictionaryBuilder*> &modified_dictionaries,
const std::unordered_map<attribute_id, const TypedValue*> &previous_maximum_integers,
std::unordered_map<attribute_id, bool> &&previous_null_present);
std::size_t buildTupleStorageSubBlockHeader(void *sub_block_memory);
void buildNullBitmapMap(void *sub_block_memory,
PtrMap<attribute_id, BitVector<false>> *null_bitmaps) const;
void buildDictionaryCompressedColumnStripe(const attribute_id attr_id,
const CompressionDictionaryBuilder &builder,
void *stripe_location) const;
void buildTruncationCompressedColumnStripe(const attribute_id attr_id,
const bool attr_is_long,
void *stripe_location) const;
void buildUncompressedColumnStripe(const attribute_id attr_id,
void *stripe_location) const;
void buildNullableUncompressedColumnStripe(const attribute_id attr_id,
void *stripe_location,
BitVector<false> *null_bitmap) const;
const CatalogRelationSchema &relation_;
const std::size_t block_size_;
// Real value for CompressedColumnStore, -1 for CompressedPackedRowStore:
attribute_id sort_attribute_id_;
PtrVector<Tuple> tuples_;
bool sort_attribute_nullable_;
std::vector<Tuple*> tuples_with_non_null_sort_value_;
std::vector<Tuple*> tuples_with_null_sort_value_;
CompressedBlockInfo compression_info_;
PtrMap<attribute_id, CompressionDictionaryBuilder> dictionary_builders_;
std::unordered_map<attribute_id, const TypedValue*> maximum_integers_;
std::unordered_map<attribute_id, bool> null_present_;
/** @} */
} // namespace quickstep