1
0
Fork 0
mirror of https://github.com/systemed/tilemaker synced 2025-02-22 06:24:08 +01:00
tilemaker/include/vtzero/index.hpp
2023-12-28 21:31:01 +00:00

264 lines
8.1 KiB
C++

#ifndef VTZERO_INDEX_HPP
#define VTZERO_INDEX_HPP
/*****************************************************************************
vtzero - Tiny and fast vector tile decoder and encoder in C++.
This file is from https://github.com/mapbox/vtzero where you can find more
documentation.
*****************************************************************************/
/**
* @file index.hpp
*
* @brief Contains classes for indexing the key/value tables inside layers.
*/
#include "builder.hpp"
#include "types.hpp"
#include <array>
#include <cstdint>
#include <vector>
namespace vtzero {
/**
* Used to store the mapping between property keys and the index value
* in the table stored in a layer.
*
* @tparam TMap The map class to use (std::map, std::unordered_map or
* something compatible).
*/
template <template <typename...> class TMap>
class key_index {
layer_builder& m_builder;
TMap<std::string, index_value> m_index;
public:
/**
* Construct index.
*
* @param builder The layer we are building containing the key table
* we are creating the index for.
*/
explicit key_index(layer_builder& builder) :
m_builder(builder) {
}
/**
* Get the index value for the specified key. If the key was not in
* the table, it will be added.
*
* @param key The key to store.
* @returns The index value of they key.
*/
index_value operator()(const data_view key) {
std::string text(key);
const auto it = m_index.find(text);
if (it == m_index.end()) {
const auto idx = m_builder.add_key_without_dup_check(key);
m_index.emplace(std::move(text), idx);
return idx;
}
return it->second;
}
}; // class key_index
/**
* Used to store the mapping between property values and the index value
* in the table stored in a layer. Stores the values in their original
* form (as type TExternal) which is more efficient than the way
* value_index_internal does it, but you need an instance of this class
* for each value type you use.
*
* @tparam TInternal The type used in the vector tile to encode the value.
* Must be one of string/float/double/int/uint/sint/bool_value_type.
* @tparam TExternal The type for the value used by the user of this class.
* @tparam TMap The map class to use (std::map, std::unordered_map or
* something compatible).
*/
template <typename TInternal, typename TExternal, template <typename...> class TMap>
class value_index {
layer_builder& m_builder;
TMap<TExternal, index_value> m_index;
public:
/**
* Construct index.
*
* @param builder The layer we are building containing the value
* table we are creating the index for.
*/
explicit value_index(layer_builder& builder) :
m_builder(builder) {
}
/**
* Get the index value for the specified value. If the value was not in
* the table, it will be added.
*
* @param value The value to store.
* @returns The index value of they value.
*/
index_value operator()(const TExternal& value) {
const auto it = m_index.find(value);
if (it == m_index.end()) {
const auto idx = m_builder.add_value_without_dup_check(encoded_property_value{TInternal{value}});
m_index.emplace(value, idx);
return idx;
}
return it->second;
}
}; // class value_index
/**
* Used to store the mapping between bool property values and the index
* value in the table stored in a layer.
*
* This is the most efficient index if you know that your property values
* are bools.
*/
class value_index_bool {
layer_builder& m_builder;
std::array<index_value, 2> m_index;
public:
/**
* Construct index.
*
* @param builder The layer we are building containing the value
* table we are creating the index for.
*/
explicit value_index_bool(layer_builder& builder) :
m_builder(builder) {
}
/**
* Get the index value for the specified value. If the value was not in
* the table, it will be added.
*
* @param value The value to store.
* @returns The index value of they value.
*/
index_value operator()(const bool value) {
auto& idx = m_index[static_cast<std::size_t>(value)]; // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index)
if (!idx.valid()) {
idx = m_builder.add_value_without_dup_check(encoded_property_value{value});
}
return idx;
}
}; // class value_index_bool
/**
* Used to store the mapping between small unsigned int property values and
* the index value in the table stored in a layer.
*
* This is the most efficient index if you know that your property values
* are densly used small unsigned integers. This is usually the case for
* enums.
*
* Interally a simple vector<index_value> is used and the value is used
* as is to look up the index value in the vector.
*/
class value_index_small_uint {
layer_builder& m_builder;
std::vector<index_value> m_index;
public:
/**
* Construct index.
*
* @param builder The layer we are building containing the value
* table we are creating the index for.
*/
explicit value_index_small_uint(layer_builder& builder) :
m_builder(builder) {
}
/**
* Get the index value for the specified value. If the value was not in
* the table, it will be added.
*
* @param value The value to store.
* @returns The index value of they value.
*/
index_value operator()(const uint16_t value) {
if (value >= m_index.size()) {
m_index.resize(value + 1);
}
if (!m_index[value].valid()) {
m_index[value] = m_builder.add_value_without_dup_check(encoded_property_value{value});
}
return m_index[value];
}
}; // class value_index_small_uint
/**
* Used to store the mapping between property values and the index value
* in the table stored in a layer. Stores the values in the already
* encoded form. This is simpler to use than the value_index class, but
* has a higher overhead.
*
* @tparam TMap The map class to use (std::map, std::unordered_map or
* something compatible).
*/
template <template <typename...> class TMap>
class value_index_internal {
layer_builder& m_builder;
TMap<encoded_property_value, index_value> m_index;
public:
/**
* Construct index.
*
* @param builder The layer we are building containing the value
* table we are creating the index for.
*/
explicit value_index_internal(layer_builder& builder) :
m_builder(builder) {
}
/**
* Get the index value for the specified value. If the value was not in
* the table, it will be added.
*
* @param value The value to store.
* @returns The index value of they value.
*/
index_value operator()(const encoded_property_value& value) {
const auto it = m_index.find(value);
if (it == m_index.end()) {
const auto idx = m_builder.add_value_without_dup_check(value);
m_index.emplace(value, idx);
return idx;
}
return it->second;
}
}; // class value_index_internal
} // namespace vtzero
#endif // VTZERO_INDEX_HPP