135 lines
4.0 KiB
C++
135 lines
4.0 KiB
C++
#ifndef OSRM_ENGINE_DATAFACADE_FACTORY_HPP
|
|
#define OSRM_ENGINE_DATAFACADE_FACTORY_HPP
|
|
|
|
#include "extractor/class_data.hpp"
|
|
#include "extractor/profile_properties.hpp"
|
|
|
|
#include "engine/algorithm.hpp"
|
|
#include "engine/api/base_parameters.hpp"
|
|
#include "engine/api/tile_parameters.hpp"
|
|
|
|
#include "util/integer_range.hpp"
|
|
|
|
#include "storage/shared_datatype.hpp"
|
|
|
|
#include <array>
|
|
#include <memory>
|
|
#include <unordered_map>
|
|
|
|
namespace osrm
|
|
{
|
|
namespace engine
|
|
{
|
|
// This class selects the right facade for
|
|
template <template <typename A> class FacadeT, typename AlgorithmT> class DataFacadeFactory
|
|
{
|
|
static constexpr auto has_exclude_flags = routing_algorithms::HasExcludeFlags<AlgorithmT>{};
|
|
|
|
public:
|
|
using Facade = FacadeT<AlgorithmT>;
|
|
DataFacadeFactory() = default;
|
|
|
|
template <typename AllocatorT>
|
|
DataFacadeFactory(std::shared_ptr<AllocatorT> allocator)
|
|
: DataFacadeFactory(allocator, has_exclude_flags)
|
|
{
|
|
}
|
|
|
|
template <typename ParameterT> std::shared_ptr<const Facade> Get(const ParameterT ¶ms) const
|
|
{
|
|
return Get(params, has_exclude_flags);
|
|
}
|
|
|
|
private:
|
|
// Algorithm with exclude flags
|
|
template <typename AllocatorT>
|
|
DataFacadeFactory(std::shared_ptr<AllocatorT> allocator, std::true_type)
|
|
{
|
|
for (const auto index : util::irange<std::size_t>(0, facades.size()))
|
|
{
|
|
facades[index] = std::make_shared<const Facade>(allocator, index);
|
|
}
|
|
|
|
properties = allocator->GetLayout().template GetBlockPtr<extractor::ProfileProperties>(
|
|
allocator->GetMemory(), "/common/properties");
|
|
|
|
for (const auto index : util::irange<std::size_t>(0, properties->class_names.size()))
|
|
{
|
|
const std::string name = properties->GetClassName(index);
|
|
if (!name.empty())
|
|
{
|
|
name_to_class[name] = extractor::getClassData(index);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Algorithm without exclude flags
|
|
template <typename AllocatorT>
|
|
DataFacadeFactory(std::shared_ptr<AllocatorT> allocator, std::false_type)
|
|
{
|
|
facades[0] = std::make_shared<const Facade>(allocator, 0);
|
|
}
|
|
|
|
std::shared_ptr<const Facade> Get(const api::TileParameters &, std::false_type) const
|
|
{
|
|
return facades[0];
|
|
}
|
|
|
|
// Default for non-exclude flags: return only facade
|
|
std::shared_ptr<const Facade> Get(const api::BaseParameters ¶ms, std::false_type) const
|
|
{
|
|
if (!params.exclude.empty())
|
|
{
|
|
return {};
|
|
}
|
|
|
|
return facades[0];
|
|
}
|
|
|
|
// TileParameters don't drive from BaseParameters and generally don't have use for exclude flags
|
|
std::shared_ptr<const Facade> Get(const api::TileParameters &, std::true_type) const
|
|
{
|
|
return facades[0];
|
|
}
|
|
|
|
// Selection logic for finding the corresponding datafacade for the given parameters
|
|
std::shared_ptr<const Facade> Get(const api::BaseParameters ¶ms, std::true_type) const
|
|
{
|
|
if (params.exclude.empty())
|
|
return facades[0];
|
|
|
|
extractor::ClassData mask = 0;
|
|
for (const auto &name : params.exclude)
|
|
{
|
|
auto class_mask_iter = name_to_class.find(name);
|
|
if (class_mask_iter == name_to_class.end())
|
|
{
|
|
return {};
|
|
}
|
|
else
|
|
{
|
|
mask |= class_mask_iter->second;
|
|
}
|
|
}
|
|
|
|
auto exclude_iter = std::find(
|
|
properties->excludable_classes.begin(), properties->excludable_classes.end(), mask);
|
|
if (exclude_iter != properties->excludable_classes.end())
|
|
{
|
|
auto exclude_index =
|
|
std::distance(properties->excludable_classes.begin(), exclude_iter);
|
|
return facades[exclude_index];
|
|
}
|
|
|
|
return {};
|
|
}
|
|
|
|
std::array<std::shared_ptr<const Facade>, extractor::MAX_EXCLUDABLE_CLASSES> facades;
|
|
std::unordered_map<std::string, extractor::ClassData> name_to_class;
|
|
const extractor::ProfileProperties *properties = nullptr;
|
|
};
|
|
}
|
|
}
|
|
|
|
#endif
|