| /** |
| * 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_STORAGE_PACKED_ROW_STORE_TUPLE_STORAGE_SUB_BLOCK_HPP_ |
| #define QUICKSTEP_STORAGE_PACKED_ROW_STORE_TUPLE_STORAGE_SUB_BLOCK_HPP_ |
| |
| #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; |
| |
| QUICKSTEP_DECLARE_SUB_BLOCK_TYPE_REGISTERED(PackedRowStoreTupleStorageSubBlock); |
| |
| /** \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 { |
| public: |
| 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; |
| } |
| |
| private: |
| 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_; |
| |
| DISALLOW_COPY_AND_ASSIGN(PackedRowStoreTupleStorageSubBlock); |
| }; |
| |
| /** @} */ |
| |
| } // namespace quickstep |
| |
| #endif // QUICKSTEP_STORAGE_PACKED_ROW_STORE_TUPLE_STORAGE_SUB_BLOCK_HPP_ |