Skip to content

Commit

Permalink
Add datafacade factory to select avoid flags
Browse files Browse the repository at this point in the history
  • Loading branch information
TheMarex authored and Patrick Niklaus committed Aug 21, 2017
1 parent c8b142a commit 21686ee
Show file tree
Hide file tree
Showing 14 changed files with 183 additions and 71 deletions.
6 changes: 4 additions & 2 deletions include/engine/api/base_parameters.hpp
Expand Up @@ -68,6 +68,7 @@ struct BaseParameters
std::vector<boost::optional<double>> radiuses;
std::vector<boost::optional<Bearing>> bearings;
std::vector<boost::optional<Approach>> approaches;
std::vector<std::string> avoid;

// Adds hints to response which can be included in subsequent requests, see `hints` above.
bool generate_hints = true;
Expand All @@ -77,9 +78,10 @@ struct BaseParameters
std::vector<boost::optional<double>> radiuses_ = {},
std::vector<boost::optional<Bearing>> bearings_ = {},
std::vector<boost::optional<Approach>> approaches_ = {},
bool generate_hints_ = true)
bool generate_hints_ = true,
std::vector<std::string> avoid = {})
: coordinates(coordinates_), hints(hints_), radiuses(radiuses_), bearings(bearings_),
approaches(approaches_), generate_hints(generate_hints_)
approaches(approaches_), avoid(std::move(avoid)), generate_hints(generate_hints_)
{
}

Expand Down
17 changes: 0 additions & 17 deletions include/engine/api/route_parameters.hpp
Expand Up @@ -87,24 +87,8 @@ struct RouteParameters : public BaseParameters
const GeometriesType geometries_,
const OverviewType overview_,
const boost::optional<bool> continue_straight_,
std::vector<std::string> avoid_,
Args... args_)
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
number_of_alternatives{alternatives_ ? 1u : 0u}, annotations{false},
annotations_type{AnnotationsType::None}, geometries{geometries_}, overview{overview_},
continue_straight{continue_straight_}, avoid{std::move(avoid_)}
// Once we perfectly-forward `args` (see #2990) this constructor can delegate to the one below.
{
}

// Without avoid flags
template <typename... Args>
RouteParameters(const bool steps_,
const bool alternatives_,
const GeometriesType geometries_,
const OverviewType overview_,
const boost::optional<bool> continue_straight_,
Args... args_)
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
number_of_alternatives{alternatives_ ? 1u : 0u}, annotations{false},
annotations_type{AnnotationsType::None}, geometries{geometries_}, overview{overview_},
Expand Down Expand Up @@ -154,7 +138,6 @@ struct RouteParameters : public BaseParameters
GeometriesType geometries = GeometriesType::Polyline;
OverviewType overview = OverviewType::Simplified;
boost::optional<bool> continue_straight;
std::vector<std::string> avoid;

bool IsValid() const
{
Expand Down
14 changes: 8 additions & 6 deletions include/engine/data_watchdog.hpp
Expand Up @@ -3,6 +3,7 @@

#include "engine/datafacade/contiguous_internalmem_datafacade.hpp"
#include "engine/datafacade/shared_memory_allocator.hpp"
#include "engine/datafacade_factory.hpp"

#include "storage/shared_datatype.hpp"
#include "storage/shared_memory.hpp"
Expand Down Expand Up @@ -36,8 +37,8 @@ template <typename AlgorithmT> class DataWatchdog final
{
boost::interprocess::scoped_lock<mutex_type> current_region_lock(barrier.get_mutex());

facade = std::make_shared<const FacadeT>(
std::make_unique<datafacade::SharedMemoryAllocator>(barrier.data().region));
facade_factory = DataFacadeFactory<const FacadeT>(
std::make_shared<datafacade::SharedMemoryAllocator>(barrier.data().region));
timestamp = barrier.data().timestamp;
}

Expand All @@ -51,7 +52,8 @@ template <typename AlgorithmT> class DataWatchdog final
watcher.join();
}

std::shared_ptr<const FacadeT> Get() const { return facade; }
std::shared_ptr<const FacadeT> Get(const api::BaseParameters &params) const { return facade_factory.Get(params); }
std::shared_ptr<const FacadeT> Get(const api::TileParameters &params) const { return facade_factory.Get(params); }

private:
void Run()
Expand All @@ -68,8 +70,8 @@ template <typename AlgorithmT> class DataWatchdog final
if (timestamp != barrier.data().timestamp)
{
auto region = barrier.data().region;
facade = std::make_shared<const FacadeT>(
std::make_unique<datafacade::SharedMemoryAllocator>(region));
facade_factory = DataFacadeFactory<const FacadeT>(
std::make_shared<datafacade::SharedMemoryAllocator>(region));
timestamp = barrier.data().timestamp;
util::Log() << "updated facade to region " << region << " with timestamp "
<< timestamp;
Expand All @@ -83,7 +85,7 @@ template <typename AlgorithmT> class DataWatchdog final
std::thread watcher;
bool active;
unsigned timestamp;
std::shared_ptr<const FacadeT> facade;
DataFacadeFactory<const FacadeT> facade_factory;
};
}
}
Expand Down
65 changes: 43 additions & 22 deletions include/engine/datafacade/contiguous_internalmem_datafacade.hpp
Expand Up @@ -212,6 +212,7 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
using SharedGeospatialQuery = GeospatialQuery<SharedRTree, BaseDataFacade>;
using RTreeNode = SharedRTree::TreeNode;

extractor::ClassData avoid_mask;
std::string m_timestamp;
extractor::ProfileProperties *m_profile_properties;
extractor::Datasources *m_datasources;
Expand Down Expand Up @@ -246,10 +247,12 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
// allocator that keeps the allocation data
std::shared_ptr<ContiguousBlockAllocator> allocator;

void InitializeProfilePropertiesPointer(storage::DataLayout &data_layout, char *memory_block)
void InitializeProfilePropertiesPointer(storage::DataLayout &data_layout, char *memory_block, const std::size_t avoid_index)
{
m_profile_properties = data_layout.GetBlockPtr<extractor::ProfileProperties>(
memory_block, storage::DataLayout::PROPERTIES);

avoid_mask = m_profile_properties->avoidable_classes[avoid_index];
}

void InitializeTimestampPointer(storage::DataLayout &data_layout, char *memory_block)
Expand Down Expand Up @@ -539,7 +542,7 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
m_entry_class_table = std::move(entry_class_table);
}

void InitializeInternalPointers(storage::DataLayout &data_layout, char *memory_block)
void InitializeInternalPointers(storage::DataLayout &data_layout, char *memory_block, const std::size_t avoid_index)
{
InitializeChecksumPointer(data_layout, memory_block);
InitializeNodeInformationPointers(data_layout, memory_block);
Expand All @@ -550,18 +553,18 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
InitializeTimestampPointer(data_layout, memory_block);
InitializeNamePointers(data_layout, memory_block);
InitializeTurnLaneDescriptionsPointers(data_layout, memory_block);
InitializeProfilePropertiesPointer(data_layout, memory_block);
InitializeProfilePropertiesPointer(data_layout, memory_block, avoid_index);
InitializeRTreePointers(data_layout, memory_block);
InitializeIntersectionClassPointers(data_layout, memory_block);
}

public:
// allows switching between process_memory/shared_memory datafacade, based on the type of
// allocator
ContiguousInternalMemoryDataFacadeBase(std::shared_ptr<ContiguousBlockAllocator> allocator_)
ContiguousInternalMemoryDataFacadeBase(std::shared_ptr<ContiguousBlockAllocator> allocator_, const std::size_t avoid_index)
: allocator(std::move(allocator_))
{
InitializeInternalPointers(allocator->GetLayout(), allocator->GetMemory());
InitializeInternalPointers(allocator->GetLayout(), allocator->GetMemory(), avoid_index);
}

// node and edge information access
Expand Down Expand Up @@ -802,6 +805,11 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
return edge_based_node_data.GetClassData(id);
}

bool AvoidNode(const NodeID id) const override final
{
return (edge_based_node_data.GetClassData(id) & avoid_mask) > 0;
}

std::vector<std::string> GetClasses(const extractor::ClassData class_data) const override final
{
auto indexes = extractor::getClassIndexes(class_data);
Expand Down Expand Up @@ -916,6 +924,7 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
{
return m_profile_properties->left_hand_driving;
}

};

template <typename AlgorithmT> class ContiguousInternalMemoryDataFacade;
Expand All @@ -926,8 +935,9 @@ class ContiguousInternalMemoryDataFacade<CH>
public ContiguousInternalMemoryAlgorithmDataFacade<CH>
{
public:
ContiguousInternalMemoryDataFacade(std::shared_ptr<ContiguousBlockAllocator> allocator)
: ContiguousInternalMemoryDataFacadeBase(allocator),
ContiguousInternalMemoryDataFacade(std::shared_ptr<ContiguousBlockAllocator> allocator,
const std::size_t avoid_index)
: ContiguousInternalMemoryDataFacadeBase(allocator, avoid_index),
ContiguousInternalMemoryAlgorithmDataFacade<CH>(allocator)

{
Expand All @@ -940,8 +950,9 @@ class ContiguousInternalMemoryDataFacade<CoreCH> final
public ContiguousInternalMemoryAlgorithmDataFacade<CoreCH>
{
public:
ContiguousInternalMemoryDataFacade(std::shared_ptr<ContiguousBlockAllocator> allocator)
: ContiguousInternalMemoryDataFacade<CH>(allocator),
ContiguousInternalMemoryDataFacade(std::shared_ptr<ContiguousBlockAllocator> allocator,
const std::size_t avoid_index)
: ContiguousInternalMemoryDataFacade<CH>(allocator, avoid_index),
ContiguousInternalMemoryAlgorithmDataFacade<CoreCH>(allocator)

{
Expand All @@ -959,14 +970,23 @@ template <> class ContiguousInternalMemoryAlgorithmDataFacade<MLD> : public Algo

QueryGraph query_graph;

void InitializeInternalPointers(storage::DataLayout &data_layout, char *memory_block)
void InitializeInternalPointers(storage::DataLayout &data_layout,
char *memory_block,
const std::size_t avoid_index)
{
InitializeMLDDataPointers(data_layout, memory_block);
InitializeMLDDataPointers(data_layout, memory_block, avoid_index);
InitializeGraphPointer(data_layout, memory_block);
}

void InitializeMLDDataPointers(storage::DataLayout &data_layout, char *memory_block)
void InitializeMLDDataPointers(storage::DataLayout &data_layout,
char *memory_block,
const std::size_t avoid_index)
{
const auto weights_block_id = static_cast<storage::DataLayout::BlockID>(
storage::DataLayout::MLD_CELL_WEIGHTS_0 + avoid_index);
const auto durations_block_id = static_cast<storage::DataLayout::BlockID>(
storage::DataLayout::MLD_CELL_DURATIONS_0 + avoid_index);

if (data_layout.GetBlockSize(storage::DataLayout::MLD_PARTITION) > 0)
{
BOOST_ASSERT(data_layout.GetBlockSize(storage::DataLayout::MLD_LEVEL_DATA) > 0);
Expand All @@ -992,15 +1012,15 @@ template <> class ContiguousInternalMemoryAlgorithmDataFacade<MLD> : public Algo
partition::MultiLevelPartitionView{level_data, partition, cell_to_children};
}

if (data_layout.GetBlockSize(storage::DataLayout::MLD_CELL_WEIGHTS_0) > 0)
if (data_layout.GetBlockSize(weights_block_id) > 0)
{
BOOST_ASSERT(data_layout.GetBlockSize(storage::DataLayout::MLD_CELLS) > 0);
BOOST_ASSERT(data_layout.GetBlockSize(storage::DataLayout::MLD_CELL_LEVEL_OFFSETS) > 0);

auto mld_cell_weights_ptr = data_layout.GetBlockPtr<EdgeWeight>(
memory_block, storage::DataLayout::MLD_CELL_WEIGHTS_0);
auto mld_cell_durations_ptr = data_layout.GetBlockPtr<EdgeDuration>(
memory_block, storage::DataLayout::MLD_CELL_DURATIONS_0);
auto mld_cell_weights_ptr =
data_layout.GetBlockPtr<EdgeWeight>(memory_block, weights_block_id);
auto mld_cell_durations_ptr =
data_layout.GetBlockPtr<EdgeDuration>(memory_block, durations_block_id);
auto mld_source_boundary_ptr = data_layout.GetBlockPtr<NodeID>(
memory_block, storage::DataLayout::MLD_CELL_SOURCE_BOUNDARY);
auto mld_destination_boundary_ptr = data_layout.GetBlockPtr<NodeID>(
Expand Down Expand Up @@ -1072,10 +1092,10 @@ template <> class ContiguousInternalMemoryAlgorithmDataFacade<MLD> : public Algo

public:
ContiguousInternalMemoryAlgorithmDataFacade(
std::shared_ptr<ContiguousBlockAllocator> allocator_)
std::shared_ptr<ContiguousBlockAllocator> allocator_, const std::size_t avoid_index)
: allocator(std::move(allocator_))
{
InitializeInternalPointers(allocator->GetLayout(), allocator->GetMemory());
InitializeInternalPointers(allocator->GetLayout(), allocator->GetMemory(), avoid_index);
}

const partition::MultiLevelPartitionView &GetMultiLevelPartition() const override
Expand Down Expand Up @@ -1130,9 +1150,10 @@ class ContiguousInternalMemoryDataFacade<MLD> final
{
private:
public:
ContiguousInternalMemoryDataFacade(std::shared_ptr<ContiguousBlockAllocator> allocator)
: ContiguousInternalMemoryDataFacadeBase(allocator),
ContiguousInternalMemoryAlgorithmDataFacade<MLD>(allocator)
ContiguousInternalMemoryDataFacade(std::shared_ptr<ContiguousBlockAllocator> allocator,
const std::size_t avoid_index)
: ContiguousInternalMemoryDataFacadeBase(allocator, avoid_index),
ContiguousInternalMemoryAlgorithmDataFacade<MLD>(allocator, avoid_index)

{
}
Expand Down
2 changes: 2 additions & 0 deletions include/engine/datafacade/datafacade_base.hpp
Expand Up @@ -94,6 +94,8 @@ class BaseDataFacade

virtual extractor::ClassData GetClassData(const NodeID id) const = 0;

virtual bool AvoidNode(const NodeID id) const = 0;

virtual std::vector<std::string> GetClasses(const extractor::ClassData class_data) const = 0;

virtual std::vector<RTreeLeaf> GetEdgesInBox(const util::Coordinate south_west,
Expand Down
88 changes: 88 additions & 0 deletions include/engine/datafacade_factory.hpp
@@ -0,0 +1,88 @@
#ifndef OSRM_ENGINE_DATAFACADE_FACTORY_HPP
#define OSRM_ENGINE_DATAFACADE_FACTORY_HPP

#include "extractor/class_data.hpp"
#include "extractor/profile_properties.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 <typename FacadeT> class DataFacadeFactory
{
public:
DataFacadeFactory() = default;

template <typename AllocatorT> DataFacadeFactory(std::shared_ptr<AllocatorT> allocator)
{
for (const auto index : util::irange<std::size_t>(0, facades.size()))
{
facades[index] = std::make_shared<FacadeT>(allocator, index);
}

properties = allocator->GetLayout().template GetBlockPtr<extractor::ProfileProperties>(
allocator->GetMemory(), storage::DataLayout::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);
}
}
}

std::shared_ptr<FacadeT> Get(const api::TileParameters &) const
{
return facades[0];
}

std::shared_ptr<FacadeT> Get(const api::BaseParameters &params) const
{
if (params.avoid.empty())
return facades[0];

extractor::ClassData mask = 0;
for (const auto &name : params.avoid)
{
auto class_mask_iter = name_to_class.find(name);
if (class_mask_iter != name_to_class.end())
{
mask |= class_mask_iter->second;
}
}

auto avoid_iter = std::find(
properties->avoidable_classes.begin(), properties->avoidable_classes.end(), mask);
if (avoid_iter != properties->avoidable_classes.end())
{
auto avoid_index = std::distance(properties->avoidable_classes.begin(), avoid_iter);
return facades[avoid_index];
}

// FIXME We need proper error handling here
return {};
}

private:
std::array<std::shared_ptr<FacadeT>, extractor::MAX_AVOIDABLE_CLASSES> facades;
std::unordered_map<std::string, extractor::ClassData> name_to_class;
const extractor::ProfileProperties *properties = nullptr;
};
}
}

#endif

0 comments on commit 21686ee

Please sign in to comment.