blob: 9a208dc00123e38fb7cef0ff911fba1540714000 [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 <memory>
#include <unordered_map>
#include <vector>
#include "expressions/predicate/PredicateCost.hpp"
#include "storage/SubBlockTypeRegistryMacros.hpp"
#include "storage/TupleStorageSubBlock.hpp"
#include "types/TypedValue.hpp"
#include "utility/BitVector.hpp"
#include "utility/Macros.hpp"
namespace quickstep {
class CatalogRelationSchema;
class ComparisonPredicate;
class TupleStorageSubBlockDescription;
class ValueAccessor;
/** \addtogroup Storage
* @{
* @brief An implementation of TupleStorageSubBlock as a packed row-store (i.e.
* an array of fixed-length values with no holes).
* @warning This implementation does NOT support variable-length attributes. It
* is an error to attempt to construct a
* PackedRowStoreTupleStorageSubBlock for a relation with any
* variable-length attributes.
class PackedRowStoreTupleStorageSubBlock: public TupleStorageSubBlock {
PackedRowStoreTupleStorageSubBlock(const CatalogRelationSchema &relation,
const TupleStorageSubBlockDescription &description,
const bool new_block,
void *sub_block_memory,
const std::size_t sub_block_memory_size);
~PackedRowStoreTupleStorageSubBlock() override {
* @brief Determine whether a TupleStorageSubBlockDescription is valid for
* this type of TupleStorageSubBlock.
* @param relation The relation a tuple store described by description would
* belong to.
* @param description A description of the parameters for this type of
* TupleStorageSubBlock, which will be checked for validity.
* @return Whether description is well-formed and valid for this type of
* TupleStorageSubBlock belonging to relation (i.e. whether a
* TupleStorageSubBlock of this type, belonging to relation, can be
* constructed according to description).
static bool DescriptionIsValid(const CatalogRelationSchema &relation,
const TupleStorageSubBlockDescription &description);
* @brief Estimate the average number of bytes (including any applicable
* overhead) used to store a single tuple in this type of
* TupleStorageSubBlock. Used by StorageBlockLayout::finalize() to
* divide block memory amongst sub-blocks.
* @warning description must be valid. DescriptionIsValid() should be called
* first if necessary.
* @param relation The relation tuples belong to.
* @param description A description of the parameters for this type of
* TupleStorageSubBlock.
* @return The average/ammortized number of bytes used to store a single
* tuple of relation in a TupleStorageSubBlock of this type described
* by description.
static std::size_t EstimateBytesPerTuple(const CatalogRelationSchema &relation,
const TupleStorageSubBlockDescription &description);
bool supportsUntypedGetAttributeValue(const attribute_id attr) const override {
return true;
bool supportsAdHocInsert() const override {
return true;
bool adHocInsertIsEfficient() const override {
return true;
TupleStorageSubBlockType getTupleStorageSubBlockType() const override {
return kPackedRowStore;
bool isEmpty() const override {
return (header_->num_tuples == 0);
bool isPacked() const override {
return true;
tuple_id getMaxTupleID() const override {
return header_->num_tuples - 1;
bool hasTupleWithID(const tuple_id tuple) const override {
return ((tuple >=0) && (tuple < header_->num_tuples));
InsertResult insertTuple(const Tuple &tuple) override {
if (null_bitmap_.get() == nullptr) {
return insertTupleImpl<false>(tuple);
} else {
return insertTupleImpl<true>(tuple);
inline bool insertTupleInBatch(const Tuple &tuple) override {
const InsertResult result = insertTuple(tuple);
return (result.inserted_id >= 0);
tuple_id bulkInsertTuples(ValueAccessor *accessor) override;
tuple_id bulkInsertTuplesWithRemappedAttributes(
const std::vector<attribute_id> &attribute_map,
ValueAccessor *accessor) override;
const void* getAttributeValue(const tuple_id tuple,
const attribute_id attr) const override;
TypedValue getAttributeValueTyped(const tuple_id tuple,
const attribute_id attr) const override;
ValueAccessor* createValueAccessor(
const TupleIdSequence *sequence = nullptr) const override;
bool canSetAttributeValuesInPlaceTyped(
const tuple_id tuple,
const std::unordered_map<attribute_id, TypedValue> &new_values) const override {
return true;
void setAttributeValueInPlaceTyped(const tuple_id tuple,
const attribute_id attr,
const TypedValue &value) override;
bool deleteTuple(const tuple_id tuple) override;
bool bulkDeleteTuples(TupleIdSequence *tuples) override;
predicate_cost_t estimatePredicateEvaluationCost(
const ComparisonPredicate &predicate) const override {
return predicate_cost::kRowScan;
void rebuild() override {
bool isInsertOrderPreserving() const override {
return true;
struct PackedRowStoreHeader {
tuple_id num_tuples;
// If 'nullable_attrs' is true, extra branches are enabled to deal with NULLs
// and set bits in '*null_bitmap_' appropriately. If no attributes of the
// relation are nullable, then 'nullable_attrs' is false and this function
// has a simpler and faster implementation with no NULL-checking.
template <bool nullable_attrs>
InsertResult insertTupleImpl(const Tuple &tuple);
// Similar to insertTupleImpl(), the 'nullable_attrs' template parameter
// distinguishes between a version of this function that includes a check for
// space in '*null_bitmap_' and a simpler version that skips the check for
// relations that have no nullable attributes (and therefore no NULL-bitmap).
template <bool nullable_attrs>
bool hasSpaceToInsert(const tuple_id num_tuples) const;
PackedRowStoreHeader *header_;
std::unique_ptr<BitVector<false>> null_bitmap_;
std::size_t null_bitmap_bytes_;
void *tuple_storage_;
/** @} */
} // namespace quickstep