Implements Zero-Copy String Views onto Contiguous Memory, resolves #3265.
- http://www.boost.org/doc/libs/1_61_0/libs/utility/doc/html/string_ref.html - http://en.cppreference.com/w/cpp/string/basic_string_view
This commit is contained in:
parent
b1f1c26703
commit
c277b95f03
@ -51,12 +51,13 @@ class BaseAPI
|
||||
if (parameters.generate_hints)
|
||||
{
|
||||
return json::makeWaypoint(phantom.location,
|
||||
facade.GetNameForID(phantom.name_id),
|
||||
facade.GetNameForID(phantom.name_id).to_string(),
|
||||
Hint{phantom, facade.GetCheckSum()});
|
||||
}
|
||||
else
|
||||
{
|
||||
return json::makeWaypoint(phantom.location, facade.GetNameForID(phantom.name_id));
|
||||
return json::makeWaypoint(phantom.location,
|
||||
facade.GetNameForID(phantom.name_id).to_string());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,7 @@ class ContiguousInternalMemoryDataFacade : public BaseDataFacade
|
||||
util::ShM<util::Coordinate, true>::vector m_coordinate_list;
|
||||
util::PackedVector<OSMNodeID, true> m_osmnodeid_list;
|
||||
util::ShM<GeometryID, true>::vector m_via_geometry_list;
|
||||
util::ShM<unsigned, true>::vector m_name_ID_list;
|
||||
util::ShM<NameID, true>::vector m_name_ID_list;
|
||||
util::ShM<LaneDataID, true>::vector m_lane_data_id;
|
||||
util::ShM<extractor::guidance::TurnInstruction, true>::vector m_turn_instruction_list;
|
||||
util::ShM<extractor::TravelMode, true>::vector m_travel_mode_list;
|
||||
@ -89,7 +89,7 @@ class ContiguousInternalMemoryDataFacade : public BaseDataFacade
|
||||
util::ShM<EdgeWeight, true>::vector m_geometry_fwd_weight_list;
|
||||
util::ShM<EdgeWeight, true>::vector m_geometry_rev_weight_list;
|
||||
util::ShM<bool, true>::vector m_is_core_node;
|
||||
util::ShM<uint8_t, true>::vector m_datasource_list;
|
||||
util::ShM<DatasourceID, true>::vector m_datasource_list;
|
||||
util::ShM<std::uint32_t, true>::vector m_lane_description_offsets;
|
||||
util::ShM<extractor::guidance::TurnLaneType::Mask, true>::vector m_lane_description_masks;
|
||||
|
||||
@ -231,8 +231,8 @@ class ContiguousInternalMemoryDataFacade : public BaseDataFacade
|
||||
m_turn_instruction_list = std::move(turn_instruction_list);
|
||||
|
||||
const auto name_id_list_ptr =
|
||||
data_layout.GetBlockPtr<unsigned>(memory_block, storage::DataLayout::NAME_ID_LIST);
|
||||
util::ShM<unsigned, true>::vector name_id_list(
|
||||
data_layout.GetBlockPtr<NameID>(memory_block, storage::DataLayout::NAME_ID_LIST);
|
||||
util::ShM<NameID, true>::vector name_id_list(
|
||||
name_id_list_ptr, data_layout.num_entries[storage::DataLayout::NAME_ID_LIST]);
|
||||
m_name_ID_list = std::move(name_id_list);
|
||||
|
||||
@ -340,9 +340,9 @@ class ContiguousInternalMemoryDataFacade : public BaseDataFacade
|
||||
data_layout.num_entries[storage::DataLayout::GEOMETRIES_REV_WEIGHT_LIST]);
|
||||
m_geometry_rev_weight_list = std::move(geometry_rev_weight_list);
|
||||
|
||||
auto datasources_list_ptr =
|
||||
data_layout.GetBlockPtr<uint8_t>(memory_block, storage::DataLayout::DATASOURCES_LIST);
|
||||
util::ShM<uint8_t, true>::vector datasources_list(
|
||||
auto datasources_list_ptr = data_layout.GetBlockPtr<DatasourceID>(
|
||||
memory_block, storage::DataLayout::DATASOURCES_LIST);
|
||||
util::ShM<DatasourceID, true>::vector datasources_list(
|
||||
datasources_list_ptr, data_layout.num_entries[storage::DataLayout::DATASOURCES_LIST]);
|
||||
m_datasource_list = std::move(datasources_list);
|
||||
|
||||
@ -482,7 +482,7 @@ class ContiguousInternalMemoryDataFacade : public BaseDataFacade
|
||||
return m_coordinate_list[id];
|
||||
}
|
||||
|
||||
OSMNodeID GetOSMNodeIDOfNode(const unsigned id) const override final
|
||||
OSMNodeID GetOSMNodeIDOfNode(const NodeID id) const override final
|
||||
{
|
||||
return m_osmnodeid_list.at(id);
|
||||
}
|
||||
@ -583,18 +583,18 @@ class ContiguousInternalMemoryDataFacade : public BaseDataFacade
|
||||
return result_weights;
|
||||
}
|
||||
|
||||
virtual GeometryID GetGeometryIndexForEdgeID(const unsigned id) const override final
|
||||
virtual GeometryID GetGeometryIndexForEdgeID(const EdgeID id) const override final
|
||||
{
|
||||
return m_via_geometry_list.at(id);
|
||||
}
|
||||
|
||||
extractor::guidance::TurnInstruction
|
||||
GetTurnInstructionForEdgeID(const unsigned id) const override final
|
||||
GetTurnInstructionForEdgeID(const EdgeID id) const override final
|
||||
{
|
||||
return m_turn_instruction_list.at(id);
|
||||
}
|
||||
|
||||
extractor::TravelMode GetTravelModeForEdgeID(const unsigned id) const override final
|
||||
extractor::TravelMode GetTravelModeForEdgeID(const EdgeID id) const override final
|
||||
{
|
||||
return m_travel_mode_list.at(id);
|
||||
}
|
||||
@ -716,56 +716,59 @@ class ContiguousInternalMemoryDataFacade : public BaseDataFacade
|
||||
|
||||
unsigned GetCheckSum() const override final { return m_check_sum; }
|
||||
|
||||
unsigned GetNameIndexFromEdgeID(const unsigned id) const override final
|
||||
NameID GetNameIndexFromEdgeID(const EdgeID id) const override final
|
||||
{
|
||||
return m_name_ID_list.at(id);
|
||||
}
|
||||
|
||||
std::string GetNameForID(const unsigned name_id) const override final
|
||||
StringView GetNameForID(const NameID id) const override final
|
||||
{
|
||||
if (std::numeric_limits<unsigned>::max() == name_id)
|
||||
if (std::numeric_limits<NameID>::max() == id)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
auto range = m_name_table->GetRange(name_id);
|
||||
|
||||
std::string result;
|
||||
result.reserve(range.size());
|
||||
if (range.begin() != range.end())
|
||||
auto range = m_name_table->GetRange(id);
|
||||
|
||||
if (range.begin() == range.end())
|
||||
{
|
||||
result.resize(range.back() - range.front() + 1);
|
||||
std::copy(m_names_char_list.begin() + range.front(),
|
||||
m_names_char_list.begin() + range.back() + 1,
|
||||
result.begin());
|
||||
return "";
|
||||
}
|
||||
return result;
|
||||
|
||||
auto first = m_names_char_list.begin() + range.front();
|
||||
auto last = m_names_char_list.begin() + range.back() + 1u;
|
||||
// These iterators are useless: they're InputIterators onto a contiguous block of memory.
|
||||
// Deref to get to the first element, then Addressof to get the memory address of the it.
|
||||
const std::size_t len = &*last - &*first;
|
||||
|
||||
return StringView{&*first, len};
|
||||
}
|
||||
|
||||
std::string GetRefForID(const unsigned name_id) const override final
|
||||
StringView GetRefForID(const NameID id) const override final
|
||||
{
|
||||
// We store the ref after the name, destination and pronunciation of a street.
|
||||
// We do this to get around the street length limit of 255 which would hit
|
||||
// if we concatenate these. Order (see extractor_callbacks):
|
||||
// name (0), destination (1), pronunciation (2), ref (3)
|
||||
return GetNameForID(name_id + 3);
|
||||
return GetNameForID(id + 3);
|
||||
}
|
||||
|
||||
std::string GetPronunciationForID(const unsigned name_id) const override final
|
||||
StringView GetPronunciationForID(const NameID id) const override final
|
||||
{
|
||||
// We store the pronunciation after the name and destination of a street.
|
||||
// We do this to get around the street length limit of 255 which would hit
|
||||
// if we concatenate these. Order (see extractor_callbacks):
|
||||
// name (0), destination (1), pronunciation (2), ref (3)
|
||||
return GetNameForID(name_id + 2);
|
||||
return GetNameForID(id + 2);
|
||||
}
|
||||
|
||||
std::string GetDestinationsForID(const unsigned name_id) const override final
|
||||
StringView GetDestinationsForID(const NameID id) const override final
|
||||
{
|
||||
// We store the destination after the name of a street.
|
||||
// We do this to get around the street length limit of 255 which would hit
|
||||
// if we concatenate these. Order (see extractor_callbacks):
|
||||
// name (0), destination (1), pronunciation (2), ref (3)
|
||||
return GetNameForID(name_id + 1);
|
||||
return GetNameForID(id + 1);
|
||||
}
|
||||
|
||||
bool IsCoreNode(const NodeID id) const override final
|
||||
@ -782,7 +785,7 @@ class ContiguousInternalMemoryDataFacade : public BaseDataFacade
|
||||
|
||||
// Returns the data source ids that were used to supply the edge
|
||||
// weights.
|
||||
virtual std::vector<uint8_t>
|
||||
virtual std::vector<DatasourceID>
|
||||
GetUncompressedForwardDatasources(const EdgeID id) const override final
|
||||
{
|
||||
/*
|
||||
@ -797,7 +800,7 @@ class ContiguousInternalMemoryDataFacade : public BaseDataFacade
|
||||
const unsigned begin = m_geometry_indices.at(id) + 1;
|
||||
const unsigned end = m_geometry_indices.at(id + 1);
|
||||
|
||||
std::vector<uint8_t> result_datasources;
|
||||
std::vector<DatasourceID> result_datasources;
|
||||
result_datasources.resize(end - begin);
|
||||
|
||||
// If there was no datasource info, return an array of 0's.
|
||||
@ -820,7 +823,7 @@ class ContiguousInternalMemoryDataFacade : public BaseDataFacade
|
||||
|
||||
// Returns the data source ids that were used to supply the edge
|
||||
// weights.
|
||||
virtual std::vector<uint8_t>
|
||||
virtual std::vector<DatasourceID>
|
||||
GetUncompressedReverseDatasources(const EdgeID id) const override final
|
||||
{
|
||||
/*
|
||||
@ -835,7 +838,7 @@ class ContiguousInternalMemoryDataFacade : public BaseDataFacade
|
||||
const unsigned begin = m_geometry_indices.at(id);
|
||||
const unsigned end = m_geometry_indices.at(id + 1) - 1;
|
||||
|
||||
std::vector<uint8_t> result_datasources;
|
||||
std::vector<DatasourceID> result_datasources;
|
||||
result_datasources.resize(end - begin);
|
||||
|
||||
// If there was no datasource info, return an array of 0's.
|
||||
@ -856,19 +859,19 @@ class ContiguousInternalMemoryDataFacade : public BaseDataFacade
|
||||
return result_datasources;
|
||||
}
|
||||
|
||||
virtual std::string GetDatasourceName(const uint8_t datasource_name_id) const override final
|
||||
StringView GetDatasourceName(const DatasourceID id) const override final
|
||||
{
|
||||
BOOST_ASSERT(m_datasource_name_offsets.size() >= 1);
|
||||
BOOST_ASSERT(m_datasource_name_offsets.size() > datasource_name_id);
|
||||
BOOST_ASSERT(m_datasource_name_offsets.size() > id);
|
||||
|
||||
std::string result;
|
||||
result.reserve(m_datasource_name_lengths[datasource_name_id]);
|
||||
std::copy(m_datasource_name_data.begin() + m_datasource_name_offsets[datasource_name_id],
|
||||
m_datasource_name_data.begin() + m_datasource_name_offsets[datasource_name_id] +
|
||||
m_datasource_name_lengths[datasource_name_id],
|
||||
std::back_inserter(result));
|
||||
auto first = m_datasource_name_data.begin() + m_datasource_name_offsets[id];
|
||||
auto last = m_datasource_name_data.begin() + m_datasource_name_offsets[id] +
|
||||
m_datasource_name_lengths[id];
|
||||
// These iterators are useless: they're InputIterators onto a contiguous block of memory.
|
||||
// Deref to get to the first element, then Addressof to get the memory address of the it.
|
||||
const std::size_t len = &*last - &*first;
|
||||
|
||||
return result;
|
||||
return StringView{&*first, len};
|
||||
}
|
||||
|
||||
std::string GetTimestamp() const override final { return m_timestamp; }
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
#include "util/integer_range.hpp"
|
||||
#include "util/string_util.hpp"
|
||||
#include "util/string_view.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include "osrm/coordinate.hpp"
|
||||
@ -34,6 +35,7 @@ namespace engine
|
||||
namespace datafacade
|
||||
{
|
||||
|
||||
using StringView = util::StringView;
|
||||
using EdgeRange = util::range<EdgeID>;
|
||||
|
||||
class BaseDataFacade
|
||||
@ -74,10 +76,10 @@ class BaseDataFacade
|
||||
const std::function<bool(EdgeData)> filter) const = 0;
|
||||
|
||||
// node and edge information access
|
||||
virtual util::Coordinate GetCoordinateOfNode(const unsigned id) const = 0;
|
||||
virtual OSMNodeID GetOSMNodeIDOfNode(const unsigned id) const = 0;
|
||||
virtual util::Coordinate GetCoordinateOfNode(const NodeID id) const = 0;
|
||||
virtual OSMNodeID GetOSMNodeIDOfNode(const NodeID id) const = 0;
|
||||
|
||||
virtual GeometryID GetGeometryIndexForEdgeID(const unsigned id) const = 0;
|
||||
virtual GeometryID GetGeometryIndexForEdgeID(const EdgeID id) const = 0;
|
||||
|
||||
virtual std::vector<NodeID> GetUncompressedForwardGeometry(const EdgeID id) const = 0;
|
||||
|
||||
@ -91,16 +93,16 @@ class BaseDataFacade
|
||||
|
||||
// Returns the data source ids that were used to supply the edge
|
||||
// weights. Will return an empty array when only the base profile is used.
|
||||
virtual std::vector<uint8_t> GetUncompressedForwardDatasources(const EdgeID id) const = 0;
|
||||
virtual std::vector<uint8_t> GetUncompressedReverseDatasources(const EdgeID id) const = 0;
|
||||
virtual std::vector<DatasourceID> GetUncompressedForwardDatasources(const EdgeID id) const = 0;
|
||||
virtual std::vector<DatasourceID> GetUncompressedReverseDatasources(const EdgeID id) const = 0;
|
||||
|
||||
// Gets the name of a datasource
|
||||
virtual std::string GetDatasourceName(const uint8_t datasource_name_id) const = 0;
|
||||
virtual StringView GetDatasourceName(const DatasourceID id) const = 0;
|
||||
|
||||
virtual extractor::guidance::TurnInstruction
|
||||
GetTurnInstructionForEdgeID(const unsigned id) const = 0;
|
||||
GetTurnInstructionForEdgeID(const EdgeID id) const = 0;
|
||||
|
||||
virtual extractor::TravelMode GetTravelModeForEdgeID(const unsigned id) const = 0;
|
||||
virtual extractor::TravelMode GetTravelModeForEdgeID(const EdgeID id) const = 0;
|
||||
|
||||
virtual std::vector<RTreeLeaf> GetEdgesInBox(const util::Coordinate south_west,
|
||||
const util::Coordinate north_east) const = 0;
|
||||
@ -157,15 +159,15 @@ class BaseDataFacade
|
||||
|
||||
virtual bool IsCoreNode(const NodeID id) const = 0;
|
||||
|
||||
virtual unsigned GetNameIndexFromEdgeID(const unsigned id) const = 0;
|
||||
virtual NameID GetNameIndexFromEdgeID(const EdgeID id) const = 0;
|
||||
|
||||
virtual std::string GetNameForID(const unsigned name_id) const = 0;
|
||||
virtual StringView GetNameForID(const NameID id) const = 0;
|
||||
|
||||
virtual std::string GetRefForID(const unsigned name_id) const = 0;
|
||||
virtual StringView GetRefForID(const NameID id) const = 0;
|
||||
|
||||
virtual std::string GetPronunciationForID(const unsigned name_id) const = 0;
|
||||
virtual StringView GetPronunciationForID(const NameID id) const = 0;
|
||||
|
||||
virtual std::string GetDestinationsForID(const unsigned name_id) const = 0;
|
||||
virtual StringView GetDestinationsForID(const NameID id) const = 0;
|
||||
|
||||
virtual std::size_t GetCoreSize() const = 0;
|
||||
|
||||
|
@ -186,11 +186,11 @@ inline RouteLeg assembleLeg(const datafacade::BaseDataFacade &facade,
|
||||
const auto name_id_to_string = [&](const NameID name_id) {
|
||||
const auto name = facade.GetNameForID(name_id);
|
||||
if (!name.empty())
|
||||
return name;
|
||||
return name.to_string();
|
||||
else
|
||||
{
|
||||
const auto ref = facade.GetRefForID(name_id);
|
||||
return ref;
|
||||
return ref.to_string();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -105,10 +105,10 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
const auto distance = leg_geometry.segment_distances[segment_index];
|
||||
|
||||
steps.push_back(RouteStep{step_name_id,
|
||||
std::move(name),
|
||||
std::move(ref),
|
||||
std::move(pronunciation),
|
||||
std::move(destinations),
|
||||
name.to_string(),
|
||||
ref.to_string(),
|
||||
pronunciation.to_string(),
|
||||
destinations.to_string(),
|
||||
NO_ROTARY_NAME,
|
||||
NO_ROTARY_NAME,
|
||||
segment_duration / 10.0,
|
||||
@ -179,10 +179,10 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
const int duration = segment_duration + target_duration;
|
||||
BOOST_ASSERT(duration >= 0);
|
||||
steps.push_back(RouteStep{step_name_id,
|
||||
facade.GetNameForID(step_name_id),
|
||||
facade.GetRefForID(step_name_id),
|
||||
facade.GetPronunciationForID(step_name_id),
|
||||
facade.GetDestinationsForID(step_name_id),
|
||||
facade.GetNameForID(step_name_id).to_string(),
|
||||
facade.GetRefForID(step_name_id).to_string(),
|
||||
facade.GetPronunciationForID(step_name_id).to_string(),
|
||||
facade.GetDestinationsForID(step_name_id).to_string(),
|
||||
NO_ROTARY_NAME,
|
||||
NO_ROTARY_NAME,
|
||||
duration / 10.,
|
||||
@ -206,10 +206,10 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
BOOST_ASSERT(duration >= 0);
|
||||
|
||||
steps.push_back(RouteStep{source_node.name_id,
|
||||
facade.GetNameForID(source_node.name_id),
|
||||
facade.GetRefForID(source_node.name_id),
|
||||
facade.GetPronunciationForID(source_node.name_id),
|
||||
facade.GetDestinationsForID(source_node.name_id),
|
||||
facade.GetNameForID(source_node.name_id).to_string(),
|
||||
facade.GetRefForID(source_node.name_id).to_string(),
|
||||
facade.GetPronunciationForID(source_node.name_id).to_string(),
|
||||
facade.GetDestinationsForID(source_node.name_id).to_string(),
|
||||
NO_ROTARY_NAME,
|
||||
NO_ROTARY_NAME,
|
||||
duration / 10.,
|
||||
@ -243,10 +243,10 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
|
||||
BOOST_ASSERT(!leg_geometry.locations.empty());
|
||||
steps.push_back(RouteStep{target_node.name_id,
|
||||
facade.GetNameForID(target_node.name_id),
|
||||
facade.GetRefForID(target_node.name_id),
|
||||
facade.GetPronunciationForID(target_node.name_id),
|
||||
facade.GetDestinationsForID(target_node.name_id),
|
||||
facade.GetNameForID(target_node.name_id).to_string(),
|
||||
facade.GetRefForID(target_node.name_id).to_string(),
|
||||
facade.GetPronunciationForID(target_node.name_id).to_string(),
|
||||
facade.GetDestinationsForID(target_node.name_id).to_string(),
|
||||
NO_ROTARY_NAME,
|
||||
NO_ROTARY_NAME,
|
||||
ZERO_DURATION,
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "util/string_view.hpp"
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
@ -21,9 +23,20 @@ class SuffixTable final
|
||||
|
||||
// check whether a string is part of the know suffix list
|
||||
bool isSuffix(const std::string &possible_suffix) const;
|
||||
bool isSuffix(util::StringView possible_suffix) const;
|
||||
|
||||
private:
|
||||
std::unordered_set<std::string> suffix_set;
|
||||
// Store lower-cased strings in SuffixTable and a set of StringViews for quick membership
|
||||
// checks.
|
||||
//
|
||||
// Why not uset<StringView>? StringView is non-owning, the vector<string> holds the string
|
||||
// contents, the set<StringView> only holds [first,last) pointers into the vector.
|
||||
//
|
||||
// Then why not simply uset<string>? Because membership tests against StringView keys would
|
||||
// require us to first convert StringViews into strings (allocation), do the membership,
|
||||
// and destroy the StringView again.
|
||||
std::vector<std::string> suffixes;
|
||||
std::unordered_set<util::StringView> suffix_set;
|
||||
};
|
||||
|
||||
} /* namespace extractor */
|
||||
|
@ -159,13 +159,14 @@ inline bool requiresNameAnnounced(const NameID from_name_id,
|
||||
if (from_name_id == to_name_id)
|
||||
return false;
|
||||
else
|
||||
return requiresNameAnnounced(name_table.GetNameForID(from_name_id),
|
||||
name_table.GetRefForID(from_name_id),
|
||||
name_table.GetPronunciationForID(from_name_id),
|
||||
name_table.GetNameForID(to_name_id),
|
||||
name_table.GetRefForID(to_name_id),
|
||||
name_table.GetPronunciationForID(to_name_id),
|
||||
return requiresNameAnnounced(name_table.GetNameForID(from_name_id).to_string(),
|
||||
name_table.GetRefForID(from_name_id).to_string(),
|
||||
name_table.GetPronunciationForID(from_name_id).to_string(),
|
||||
name_table.GetNameForID(to_name_id).to_string(),
|
||||
name_table.GetRefForID(to_name_id).to_string(),
|
||||
name_table.GetPronunciationForID(to_name_id).to_string(),
|
||||
suffix_table);
|
||||
// FIXME: converts StringViews to strings since the name change heuristics mutates in place
|
||||
}
|
||||
|
||||
inline bool requiresNameAnnounced(const NameID from_name_id,
|
||||
@ -175,12 +176,13 @@ inline bool requiresNameAnnounced(const NameID from_name_id,
|
||||
if (from_name_id == to_name_id)
|
||||
return false;
|
||||
else
|
||||
return requiresNameAnnounced(name_table.GetNameForID(from_name_id),
|
||||
name_table.GetRefForID(from_name_id),
|
||||
name_table.GetPronunciationForID(from_name_id),
|
||||
name_table.GetNameForID(to_name_id),
|
||||
name_table.GetRefForID(to_name_id),
|
||||
name_table.GetPronunciationForID(to_name_id));
|
||||
return requiresNameAnnounced(name_table.GetNameForID(from_name_id).to_string(),
|
||||
name_table.GetRefForID(from_name_id).to_string(),
|
||||
name_table.GetPronunciationForID(from_name_id).to_string(),
|
||||
name_table.GetNameForID(to_name_id).to_string(),
|
||||
name_table.GetRefForID(to_name_id).to_string(),
|
||||
name_table.GetPronunciationForID(to_name_id).to_string());
|
||||
// FIXME: converts StringViews to strings since the name change heuristics mutates in place
|
||||
}
|
||||
|
||||
} // namespace guidance
|
||||
|
@ -3,6 +3,8 @@
|
||||
|
||||
#include "util/range_table.hpp"
|
||||
#include "util/shared_memory_vector_wrapper.hpp"
|
||||
#include "util/string_view.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
@ -28,9 +30,9 @@ class NameTable
|
||||
// The following functions are a subset of what is available.
|
||||
// See the data facades for they provide full access to this serialized string data.
|
||||
// (at time of writing this: get{Name,Ref,Pronunciation,Destinations}ForID(name_id);)
|
||||
std::string GetNameForID(const unsigned name_id) const;
|
||||
std::string GetRefForID(const unsigned name_id) const;
|
||||
std::string GetPronunciationForID(const unsigned name_id) const;
|
||||
util::StringView GetNameForID(const NameID id) const;
|
||||
util::StringView GetRefForID(const NameID id) const;
|
||||
util::StringView GetPronunciationForID(const NameID id) const;
|
||||
};
|
||||
} // namespace util
|
||||
} // namespace osrm
|
||||
|
34
include/util/string_view.hpp
Normal file
34
include/util/string_view.hpp
Normal file
@ -0,0 +1,34 @@
|
||||
#ifndef OSRM_STRING_VIEW_HPP
|
||||
#define OSRM_STRING_VIEW_HPP
|
||||
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace util
|
||||
{
|
||||
// Convenience typedef: boost::string_ref, boost::string_view or C++17's string_view
|
||||
using StringView = boost::string_ref;
|
||||
|
||||
} // namespace util
|
||||
} // namespace osrm
|
||||
|
||||
// Specializing hash<> for user-defined type in std namespace, this is standard conforming.
|
||||
namespace std
|
||||
{
|
||||
template <> struct hash<::osrm::util::StringView> final
|
||||
{
|
||||
std::size_t operator()(::osrm::util::StringView v) const noexcept
|
||||
{
|
||||
// Bring into scope and call un-qualified for ADL:
|
||||
// remember we want to be able to switch impl. above.
|
||||
using std::begin;
|
||||
using std::end;
|
||||
|
||||
return boost::hash_range(begin(v), end(v));
|
||||
}
|
||||
};
|
||||
} // namespace std
|
||||
|
||||
#endif /* OSRM_STRING_VIEW_HPP */
|
@ -3,6 +3,7 @@
|
||||
#include "engine/plugins/plugin_base.hpp"
|
||||
|
||||
#include "util/coordinate_calculation.hpp"
|
||||
#include "util/string_view.hpp"
|
||||
#include "util/vector_tile.hpp"
|
||||
#include "util/web_mercator.hpp"
|
||||
|
||||
@ -287,8 +288,8 @@ Status TilePlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDat
|
||||
std::unordered_map<int, std::size_t> line_int_offsets;
|
||||
|
||||
// Same idea for street names - one lookup table for names for all features
|
||||
std::vector<std::string> names;
|
||||
std::unordered_map<std::string, std::size_t> name_offsets;
|
||||
std::vector<util::StringView> names;
|
||||
std::unordered_map<util::StringView, std::size_t> name_offsets;
|
||||
|
||||
// And again for integer values used by points.
|
||||
std::vector<int> used_point_ints;
|
||||
@ -714,14 +715,15 @@ Status TilePlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDat
|
||||
reverse_datasource_vector[reverse_datasource_vector.size() -
|
||||
edge.fwd_segment_position - 1];
|
||||
|
||||
std::string name = facade->GetNameForID(edge.name_id);
|
||||
auto name = facade->GetNameForID(edge.name_id);
|
||||
|
||||
const auto name_offset = [&name, &names, &name_offsets]() {
|
||||
auto iter = name_offsets.find(name);
|
||||
if (iter == name_offsets.end())
|
||||
{
|
||||
auto offset = names.size();
|
||||
name_offsets[name] = offset;
|
||||
names.push_back(std::move(name));
|
||||
names.push_back(name);
|
||||
return offset;
|
||||
}
|
||||
return iter->second;
|
||||
@ -873,7 +875,7 @@ Status TilePlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDat
|
||||
util::vector_tile::VARIANT_TAG);
|
||||
// Attribute value 1 == string type
|
||||
values_writer.add_string(util::vector_tile::VARIANT_TYPE_STRING,
|
||||
facade->GetDatasourceName(i));
|
||||
facade->GetDatasourceName(i).to_string());
|
||||
}
|
||||
for (auto value : used_line_ints)
|
||||
{
|
||||
@ -892,7 +894,8 @@ Status TilePlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDat
|
||||
protozero::pbf_writer values_writer(line_layer_writer,
|
||||
util::vector_tile::VARIANT_TAG);
|
||||
// Attribute value 1 == string type
|
||||
values_writer.add_string(util::vector_tile::VARIANT_TYPE_STRING, name);
|
||||
values_writer.add_string(
|
||||
util::vector_tile::VARIANT_TYPE_STRING, name.data(), name.size());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,9 @@
|
||||
#include "extractor/suffix_table.hpp"
|
||||
|
||||
#include "extractor/scripting_environment.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
namespace osrm
|
||||
@ -11,13 +13,22 @@ namespace extractor
|
||||
|
||||
SuffixTable::SuffixTable(ScriptingEnvironment &scripting_environment)
|
||||
{
|
||||
std::vector<std::string> suffixes_vector = scripting_environment.GetNameSuffixList();
|
||||
for (auto &suffix : suffixes_vector)
|
||||
suffixes = scripting_environment.GetNameSuffixList();
|
||||
|
||||
for (auto &suffix : suffixes)
|
||||
boost::algorithm::to_lower(suffix);
|
||||
suffix_set.insert(std::begin(suffixes_vector), std::end(suffixes_vector));
|
||||
|
||||
auto into = std::inserter(suffix_set, end(suffix_set));
|
||||
auto to_view = [](const auto &s) { return util::StringView{s}; };
|
||||
std::transform(begin(suffixes), end(suffixes), into, to_view);
|
||||
}
|
||||
|
||||
bool SuffixTable::isSuffix(const std::string &possible_suffix) const
|
||||
{
|
||||
return isSuffix(util::StringView{possible_suffix});
|
||||
}
|
||||
|
||||
bool SuffixTable::isSuffix(util::StringView possible_suffix) const
|
||||
{
|
||||
return suffix_set.count(possible_suffix) > 0;
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
#include "util/name_table.hpp"
|
||||
#include "storage/io.hpp"
|
||||
#include "util/exception.hpp"
|
||||
#include "util/log.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
@ -18,11 +19,9 @@ NameTable::NameTable(const std::string &filename)
|
||||
storage::io::FileReader name_stream_file_reader(filename,
|
||||
storage::io::FileReader::HasNoFingerprint);
|
||||
|
||||
// name_stream >> m_name_table;
|
||||
|
||||
m_name_table.ReadARangeTable(name_stream_file_reader);
|
||||
|
||||
unsigned number_of_chars = name_stream_file_reader.ReadElementCount32();
|
||||
const auto number_of_chars = name_stream_file_reader.ReadElementCount32();
|
||||
|
||||
m_names_char_list.resize(number_of_chars + 1); //+1 gives sentinel element
|
||||
m_names_char_list.back() = 0;
|
||||
@ -37,58 +36,59 @@ NameTable::NameTable(const std::string &filename)
|
||||
}
|
||||
}
|
||||
|
||||
std::string NameTable::GetNameForID(const unsigned name_id) const
|
||||
StringView NameTable::GetNameForID(const NameID id) const
|
||||
{
|
||||
if (std::numeric_limits<unsigned>::max() == name_id)
|
||||
if (std::numeric_limits<NameID>::max() == id)
|
||||
{
|
||||
return "";
|
||||
return {};
|
||||
}
|
||||
auto range = m_name_table.GetRange(name_id);
|
||||
|
||||
std::string result;
|
||||
result.reserve(range.size());
|
||||
if (range.begin() != range.end())
|
||||
auto range = m_name_table.GetRange(id);
|
||||
|
||||
if (range.begin() == range.end())
|
||||
{
|
||||
result.resize(range.back() - range.front() + 1);
|
||||
std::copy(m_names_char_list.begin() + range.front(),
|
||||
m_names_char_list.begin() + range.back() + 1,
|
||||
result.begin());
|
||||
return {};
|
||||
}
|
||||
return result;
|
||||
|
||||
auto first = begin(m_names_char_list) + range.front();
|
||||
auto last = begin(m_names_char_list) + range.back() + 1;
|
||||
const std::size_t len = last - first;
|
||||
|
||||
return StringView{&*first, len};
|
||||
}
|
||||
|
||||
std::string NameTable::GetRefForID(const unsigned name_id) const
|
||||
StringView NameTable::GetRefForID(const NameID id) const
|
||||
{
|
||||
// Way string data is stored in blocks based on `name_id` as follows:
|
||||
// Way string data is stored in blocks based on `id` as follows:
|
||||
//
|
||||
// | name | destination | pronunciation | ref |
|
||||
// ^ ^
|
||||
// [range)
|
||||
// ^ name_id + 3
|
||||
// ^ id + 3
|
||||
//
|
||||
// `name_id + offset` gives us the range of chars.
|
||||
// `id + offset` gives us the range of chars.
|
||||
//
|
||||
// Offset 0 is name, 1 is destination, 2 is pronunciation, 3 is ref.
|
||||
// See datafacades and extractor callbacks for details.
|
||||
const constexpr auto OFFSET_REF = 3u;
|
||||
return GetNameForID(name_id + OFFSET_REF);
|
||||
return GetNameForID(id + OFFSET_REF);
|
||||
}
|
||||
|
||||
std::string NameTable::GetPronunciationForID(const unsigned name_id) const
|
||||
StringView NameTable::GetPronunciationForID(const NameID id) const
|
||||
{
|
||||
// Way string data is stored in blocks based on `name_id` as follows:
|
||||
// Way string data is stored in blocks based on `id` as follows:
|
||||
//
|
||||
// | name | destination | pronunciation | ref |
|
||||
// ^ ^
|
||||
// [range)
|
||||
// ^ name_id + 2
|
||||
// ^ id + 2
|
||||
//
|
||||
// `name_id + offset` gives us the range of chars.
|
||||
// `id + offset` gives us the range of chars.
|
||||
//
|
||||
// Offset 0 is name, 1 is destination, 2 is pronunciation, 3 is ref.
|
||||
// See datafacades and extractor callbacks for details.
|
||||
const constexpr auto OFFSET_PRONUNCIATION = 2u;
|
||||
return GetNameForID(name_id + OFFSET_PRONUNCIATION);
|
||||
return GetNameForID(id + OFFSET_PRONUNCIATION);
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
|
@ -19,6 +19,8 @@ namespace test
|
||||
|
||||
class MockDataFacade final : public engine::datafacade::BaseDataFacade
|
||||
{
|
||||
using StringView = util::StringView;
|
||||
|
||||
private:
|
||||
EdgeData foo;
|
||||
|
||||
@ -56,13 +58,13 @@ class MockDataFacade final : public engine::datafacade::BaseDataFacade
|
||||
{
|
||||
return SPECIAL_EDGEID;
|
||||
}
|
||||
util::Coordinate GetCoordinateOfNode(const unsigned /* id */) const override
|
||||
util::Coordinate GetCoordinateOfNode(const NodeID /* id */) const override
|
||||
{
|
||||
return {util::FixedLongitude{0}, util::FixedLatitude{0}};
|
||||
}
|
||||
OSMNodeID GetOSMNodeIDOfNode(const unsigned /* id */) const override { return OSMNodeID{0}; }
|
||||
bool EdgeIsCompressed(const unsigned /* id */) const { return false; }
|
||||
GeometryID GetGeometryIndexForEdgeID(const unsigned /* id */) const override
|
||||
OSMNodeID GetOSMNodeIDOfNode(const NodeID /* id */) const override { return OSMNodeID{0}; }
|
||||
bool EdgeIsCompressed(const EdgeID /* id */) const { return false; }
|
||||
GeometryID GetGeometryIndexForEdgeID(const EdgeID /* id */) const override
|
||||
{
|
||||
return GeometryID{SPECIAL_GEOMETRYID, false};
|
||||
}
|
||||
@ -88,24 +90,23 @@ class MockDataFacade final : public engine::datafacade::BaseDataFacade
|
||||
result_weights[0] = 1;
|
||||
return result_weights;
|
||||
}
|
||||
std::vector<uint8_t> GetUncompressedForwardDatasources(const EdgeID /*id*/) const override
|
||||
std::vector<DatasourceID> GetUncompressedForwardDatasources(const EdgeID /*id*/) const override
|
||||
{
|
||||
return {};
|
||||
}
|
||||
std::vector<uint8_t> GetUncompressedReverseDatasources(const EdgeID /*id*/) const override
|
||||
std::vector<DatasourceID> GetUncompressedReverseDatasources(const EdgeID /*id*/) const override
|
||||
{
|
||||
return {};
|
||||
}
|
||||
std::string GetDatasourceName(const uint8_t /*datasource_name_id*/) const override
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
StringView GetDatasourceName(const DatasourceID) const override final { return {}; }
|
||||
|
||||
extractor::guidance::TurnInstruction
|
||||
GetTurnInstructionForEdgeID(const unsigned /* id */) const override
|
||||
GetTurnInstructionForEdgeID(const EdgeID /* id */) const override
|
||||
{
|
||||
return extractor::guidance::TurnInstruction::NO_TURN();
|
||||
}
|
||||
extractor::TravelMode GetTravelModeForEdgeID(const unsigned /* id */) const override
|
||||
extractor::TravelMode GetTravelModeForEdgeID(const EdgeID /* id */) const override
|
||||
{
|
||||
return TRAVEL_MODE_INACCESSIBLE;
|
||||
}
|
||||
@ -198,11 +199,14 @@ class MockDataFacade final : public engine::datafacade::BaseDataFacade
|
||||
|
||||
unsigned GetCheckSum() const override { return 0; }
|
||||
bool IsCoreNode(const NodeID /* id */) const override { return false; }
|
||||
unsigned GetNameIndexFromEdgeID(const unsigned /* id */) const override { return 0; }
|
||||
std::string GetNameForID(const unsigned /* name_id */) const override { return ""; }
|
||||
std::string GetRefForID(const unsigned /* name_id */) const override { return ""; }
|
||||
std::string GetPronunciationForID(const unsigned /* name_id */) const override { return ""; }
|
||||
std::string GetDestinationsForID(const unsigned /* name_id */) const override { return ""; }
|
||||
|
||||
NameID GetNameIndexFromEdgeID(const EdgeID /* id */) const override { return 0; }
|
||||
|
||||
StringView GetNameForID(const NameID) const override final { return {}; }
|
||||
StringView GetRefForID(const NameID) const override final { return {}; }
|
||||
StringView GetPronunciationForID(const NameID) const override final { return {}; }
|
||||
StringView GetDestinationsForID(const NameID) const override final { return {}; }
|
||||
|
||||
std::size_t GetCoreSize() const override { return 0; }
|
||||
std::string GetTimestamp() const override { return ""; }
|
||||
bool GetContinueStraightDefault() const override { return true; }
|
||||
|
Loading…
Reference in New Issue
Block a user