blob: 3bf3f17e53ccce4330ea8ee15240b2842b915734 [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_CATALOG_INDEX_SCHEME_HPP_
#define QUICKSTEP_CATALOG_INDEX_SCHEME_HPP_
#include <algorithm>
#include <cstddef>
#include <string>
#include <unordered_map>
#include <vector>
#include "catalog/Catalog.pb.h"
#include "storage/StorageBlockLayout.pb.h"
#include "utility/Macros.hpp"
#include "glog/logging.h"
namespace quickstep {
/** \addtogroup Catalog
* @{
*/
/**
* @brief The Index Scheme class which stores the information about
* various indicies defined for a particular relation.
**/
class IndexScheme {
public:
typedef std::unordered_map<std::string, IndexSubBlockDescription>::const_iterator const_iterator;
/**
* @brief Constructor.
**/
IndexScheme() {
}
/**
* @brief Reconstruct an Index Scheme from its serialized
* Protocol Buffer form.
*
* @param proto The Protocol Buffer serialization of a Index Scheme,
* previously produced by getProto().
* @return The deserialied index scheme object.
**/
static IndexScheme* ReconstructFromProto(const serialization::IndexScheme &proto);
/**
* @brief Check whether a serialization::IndexScheme is fully-formed and
* all parts are valid.
*
* @param proto A serialized Protocol Buffer representation of a
* IndexScheme, originally generated by getProto().
* @return Whether proto is fully-formed and valid.
**/
static bool ProtoIsValid(const serialization::IndexScheme &proto);
/**
* @brief Serialize the Index Scheme as Protocol Buffer.
*
* @return The Protocol Buffer representation of Index Scheme.
**/
serialization::IndexScheme getProto() const;
/**
* @brief Get the number of indices for the relation.
*
* @return The number of indices defined for the relation.
**/
inline std::size_t getNumIndices() const {
return index_map_.size();
}
/**
* @brief Check whether an index with the given exists or not.
*
* @param index_name Name of the index to be checked.
* @return Whether the index exists or not.
**/
bool hasIndexWithName(const std::string &index_name) const {
return index_map_.find(index_name) != index_map_.end();
}
/**
* @brief Check whether an index with the given description
* containing the same attribute id and index type
* exists or not in the index map.
*
* @param index_descripton Index Description to check against.
* @return Whether a similar index description was already defined or not.
**/
bool hasIndexWithDescription(const IndexSubBlockDescription &index_description_checked) const {
// Iterate through every index description corresponding to each key in the index map.
for (auto cit = index_map_.cbegin(); cit != index_map_.cend(); ++cit) {
const IndexSubBlockDescription &index_description_expected = cit->second;
// Check if the stored description matches the given description.
if (areIndexDescriptionsSame(index_description_expected, index_description_checked)) {
return true;
}
}
return false;
}
/**
* @brief Check whether two index descriptions are same or not.
* Two index descriptions are same if they have any matching
* attributes ids and same index type.
*
* @param description_expected First index description.
* @param description_checked Second index description.
* @return Whether the two index_descriptions are similar or not.
**/
bool areIndexDescriptionsSame(const IndexSubBlockDescription &description_expected,
const IndexSubBlockDescription &description_checked) const {
if (description_expected.sub_block_type() != description_checked.sub_block_type()) {
return false;
}
// Serialize and sort the two protobuf index descriptions and compare.
std::string serialized_description_expected, serialized_description_checked;
description_expected.SerializeToString(&serialized_description_expected);
description_checked.SerializeToString(&serialized_description_checked);
std::sort(serialized_description_expected.begin(), serialized_description_expected.end());
std::sort(serialized_description_checked.begin(), serialized_description_checked.end());
return (serialized_description_expected.compare(serialized_description_checked) == 0);
}
/**
* @brief Get an iterator at beginning of the index map.
*
* @return An iterator at beginning of the index map.
**/
inline const_iterator begin() const {
return index_map_.begin();
}
/**
* @brief Get an iterator at one-past-the-end of the index map.
*
* @return An iterator one-past-the-end of the index map.
**/
inline const_iterator end() const {
return index_map_.end();
}
/**
* @brief Adds a new index entry to the index map.
* @warning Must call before hasIndexWithName() and hasIndexWithDescription().
* @note This method assumes that the caller has already acquired the
* necessary locks before invoking it.
*
* @param index_name The name of index to add (key).
* @param index_description The index description for this index (value).
**/
bool addIndexMapEntry(const std::string &index_name,
IndexSubBlockDescription &&index_description) { // NOLINT(whitespace/operators)
if (index_map_.find(index_name) != index_map_.end()) {
return false; // index_name is already present!
}
// Value for this index_map key is the index description provided.
index_map_.emplace(index_name, std::move(index_description));
return true;
}
private:
// A map of index names to their index description.
std::unordered_map<std::string, IndexSubBlockDescription> index_map_;
DISALLOW_COPY_AND_ASSIGN(IndexScheme);
};
/** @} */
} // namespace quickstep
#endif // QUICKSTEP_CATALOG_INDEX_SCHEME_HPP_