osrm-backend/include/engine/datafacade_factory.hpp
Kajari Ghosh 4563d44180 set up for computing durations while unpacking them
copy dummy cache over

implement retrievePackedPathFromSearchSpace

calculate packed_path_from_source_to_middle

debugging the retrievePackedPathFromSearchSpace function implementation

adding in packed_path_from_source_to_middle

cache is partway working

unpack path and get duration that way

the computeDurationForEdge method

comment out cache

clean up the code

move vector creation and allocation to outside of loop

hack to not return vectors on facade.GetUncompressedForwardDurations and facade.GetUncompressedReverseDurations

clean up hack

add exclude_index to cache key

clearing cache with timestamp

rebase against vectors->range pr

swapped out unordered_map cache with a boost_lru implementation

calculation for cache size

cleaned up comment about cache size calculations

unit tests

cache uses unsigned char for exclude index

clean up cache and unit tests
2018-04-20 10:01:39 -04:00

161 lines
5.4 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, unsigned timestamp)
: DataFacadeFactory(allocator, has_exclude_flags, timestamp)
{
BOOST_ASSERT_MSG(facades.size() >= 1, "At least one datafacade is needed");
}
template <typename ParameterT> std::shared_ptr<const Facade> Get(const ParameterT &params) const
{
return Get(params, has_exclude_flags);
}
private:
// Algorithm with exclude flags
template <typename AllocatorT>
DataFacadeFactory(std::shared_ptr<AllocatorT> allocator, std::true_type, unsigned timestamp)
{
const auto &index = allocator->GetIndex();
properties = index.template GetBlockPtr<extractor::ProfileProperties>("/common/properties");
const auto &metric_name = properties->GetWeightName();
std::vector<std::string> exclude_prefixes;
auto exclude_path = std::string("/") + routing_algorithms::identifier<AlgorithmT>() +
std::string("/metrics/") + metric_name + "/exclude/";
index.List(exclude_path, std::back_inserter(exclude_prefixes));
facades.resize(exclude_prefixes.size());
if (facades.empty())
{
throw util::exception(std::string("Could not find any metrics for ") +
routing_algorithms::name<AlgorithmT>() +
" in the data. Did you load the right dataset?");
}
for (const auto &exclude_prefix : exclude_prefixes)
{
auto index_begin = exclude_prefix.find_last_of("/");
BOOST_ASSERT_MSG(index_begin != std::string::npos,
"The exclude prefix needs to be a valid data path.");
std::size_t index =
std::stoi(exclude_prefix.substr(index_begin + 1, exclude_prefix.size()));
BOOST_ASSERT(index >= 0 && index < facades.size());
facades[index] =
std::make_shared<const Facade>(allocator, metric_name, index, timestamp);
}
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, unsigned timestamp)
{
const auto &index = allocator->GetIndex();
properties = index.template GetBlockPtr<extractor::ProfileProperties>("/common/properties");
const auto &metric_name = properties->GetWeightName();
facades.push_back(std::make_shared<const Facade>(allocator, metric_name, 0, timestamp));
}
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 &params, 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 &params, 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::vector<std::shared_ptr<const Facade>> facades;
std::unordered_map<std::string, extractor::ClassData> name_to_class;
const extractor::ProfileProperties *properties = nullptr;
};
}
}
#endif