blob: 0c92072cf3e3bcc0a2fdf5e162c1bfb3047685f1 [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_TESTS_MOCK_TUPLE_STORAGE_SUB_BLOCK_HPP_
#define QUICKSTEP_STORAGE_TESTS_MOCK_TUPLE_STORAGE_SUB_BLOCK_HPP_
#include <unordered_map>
#include <vector>
#include "catalog/CatalogRelation.hpp"
#include "storage/StorageBlockLayout.pb.h"
#include "storage/TupleIdSequence.hpp"
#include "storage/TupleStorageSubBlock.hpp"
#include "types/TypedValue.hpp"
#include "types/containers/Tuple.hpp"
#include "utility/Macros.hpp"
#include "utility/PtrVector.hpp"
namespace quickstep {
/** \addtogroup Storage
* @{
*/
/**
* @brief A mock memory-only TupleStorageSubBlock which can be used for testing
* purposes.
**/
class MockTupleStorageSubBlock : public TupleStorageSubBlock {
public:
explicit MockTupleStorageSubBlock(const CatalogRelation &relation)
: TupleStorageSubBlock(relation,
TupleStorageSubBlockDescription::default_instance(),
true,
NULL,
0),
packed_(true) {
}
~MockTupleStorageSubBlock() {
}
TupleStorageSubBlockType getTupleStorageSubBlockType() const override {
FATAL_ERROR("getTupleStorageSubBlockType() is unimplemented in MockTupleStorageSubBlock.");
}
bool supportsUntypedGetAttributeValue(const attribute_id attr) const override {
return true;
}
bool supportsAdHocInsert() const override {
return true;
}
bool adHocInsertIsEfficient() const override {
return true;
}
bool isEmpty() const override {
return tuples_.emptyNullCheck();
}
bool isPacked() const override {
return packed_;
}
tuple_id getMaxTupleID() const override {
if (packed_) {
return tuples_.size() - 1;
} else {
for (tuple_id tid = tuples_.size() -1; tid >= 0; --tid) {
if (!tuples_.elementIsNull(tid)) {
return tid;
}
}
return -1;
}
}
bool hasTupleWithID(const tuple_id tuple) const override {
if ((tuple >= 0) && (static_cast<PtrVector<Tuple, true>::size_type>(tuple) < tuples_.size())) {
return !tuples_.elementIsNull(tuple);
} else {
return false;
}
}
/**
* @brief Add a Tuple to this MockTupleStorageSubBlock, taking ownership of
* the Tuple in the process. Use this instead of insertTuple() when
* testing.
*
* @param tuple A tuple which this MockTupleStorageSubBlock takes ownership
* of.
* @return tuple's ID in this MockTupleStorageSubBlock.
**/
tuple_id addTupleMock(Tuple *tuple) {
paranoidInsertTypeCheck(*tuple);
tuples_.push_back(tuple);
return tuples_.size() - 1;
}
InsertResult insertTuple(const Tuple &tuple) override {
FATAL_ERROR("insertTuple() is unimplemented in MockTupleStorageSubBlock.");
}
bool insertTupleInBatch(const Tuple &tuple) override {
FATAL_ERROR("insertTupleInBatch() is unimplemented in MockTupleStorageSubBlock.");
}
tuple_id bulkInsertTuples(ValueAccessor *accessor) override {
FATAL_ERROR("bulkInsertTuples() is unimplemented in MockTupleStorageSubBlock.");
}
tuple_id bulkInsertTuplesWithRemappedAttributes(
const std::vector<attribute_id> &attribute_map,
ValueAccessor *accessor) override {
FATAL_ERROR("bulkInsertTuplesWithRemappedAttributes() is unimplemented in MockTupleStorageSubBlock.");
}
const void* getAttributeValue(const tuple_id tuple, const attribute_id attr) const override {
DEBUG_ASSERT(hasTupleWithID(tuple));
DEBUG_ASSERT(relation_.hasAttributeWithId(attr));
if (tuples_.at(tuple).getAttributeValue(attr).isNull()) {
return NULL;
} else {
return tuples_.at(tuple).getAttributeValue(attr).getDataPtr();
}
}
TypedValue getAttributeValueTyped(const tuple_id tuple, const attribute_id attr) const override {
DEBUG_ASSERT(hasTupleWithID(tuple));
DEBUG_ASSERT(relation_.hasAttributeWithId(attr));
return tuples_.at(tuple).getAttributeValue(attr).makeReferenceToThis();
}
ValueAccessor* createValueAccessor(const TupleIdSequence *sequence = nullptr) const override {
FATAL_ERROR("createValueAccessor() is unimplemented in MockTupleStorageSubBlock.");
}
bool canSetAttributeValuesInPlaceTyped(
const tuple_id tuple,
const std::unordered_map<attribute_id, TypedValue> &new_values) const override {
return false;
}
void setAttributeValueInPlaceTyped(const tuple_id tuple,
const attribute_id attr,
const TypedValue &value) override {
FATAL_ERROR("setAttributeValueInPlaceTyped() is unimplemented in MockTupleStorageSubBlock.");
}
bool deleteTuple(const tuple_id tuple) override {
DEBUG_ASSERT(hasTupleWithID(tuple));
tuples_.deleteElement(tuple);
packed_ = false;
return false;
}
bool bulkDeleteTuples(TupleIdSequence *tuples) override {
for (TupleIdSequence::const_iterator it = tuples->begin();
it != tuples->end();
++it) {
deleteTuple(*it);
}
return false;
}
predicate_cost_t estimatePredicateEvaluationCost(
const ComparisonPredicate &predicate) const override {
return predicate_cost::kRowScan;
}
void rebuild() override {
}
bool isInsertOrderPreserving() const override {
return false;
}
private:
PtrVector<Tuple, true> tuples_;
bool packed_;
DISALLOW_COPY_AND_ASSIGN(MockTupleStorageSubBlock);
};
/** @} */
} // namespace quickstep
#endif // QUICKSTEP_STORAGE_TESTS_MOCK_TUPLE_STORAGE_SUB_BLOCK_HPP_