diff --git a/generator/maxspeeds_builder.cpp b/generator/maxspeeds_builder.cpp index 3d1a1e6ac..03da39dc7 100644 --- a/generator/maxspeeds_builder.cpp +++ b/generator/maxspeeds_builder.cpp @@ -421,9 +421,7 @@ public: auto const s = m_avgSpeeds[ind][type].m_speed; if (s > 0) return s; - auto const * p = kHighwayBasedSpeeds.Find(type); - CHECK(p, ()); - return p->GetSpeed(inCity).m_weight; + return kHighwayBasedSpeeds.at(type).GetSpeed(inCity).m_weight; }; // These speeds: Primary, Secondary, Tertiary, Residential have the biggest routing quality impact. diff --git a/libs/base/CMakeLists.txt b/libs/base/CMakeLists.txt index cd36429ce..ebe546932 100644 --- a/libs/base/CMakeLists.txt +++ b/libs/base/CMakeLists.txt @@ -65,8 +65,6 @@ set(SRC set_operations.hpp shared_buffer_manager.cpp shared_buffer_manager.hpp - small_map.hpp - small_set.hpp src_point.cpp src_point.hpp stats.hpp diff --git a/libs/base/base_tests/CMakeLists.txt b/libs/base/base_tests/CMakeLists.txt index a052d0a19..b3937de70 100644 --- a/libs/base/base_tests/CMakeLists.txt +++ b/libs/base/base_tests/CMakeLists.txt @@ -33,7 +33,6 @@ set(SRC regexp_test.cpp rolling_hash_test.cpp scope_guard_test.cpp - small_set_test.cpp stl_helpers_tests.cpp string_utils_test.cpp suffix_array_tests.cpp diff --git a/libs/base/base_tests/small_set_test.cpp b/libs/base/base_tests/small_set_test.cpp deleted file mode 100644 index 951091397..000000000 --- a/libs/base/base_tests/small_set_test.cpp +++ /dev/null @@ -1,270 +0,0 @@ -#include "testing/testing.hpp" - -#include "base/small_map.hpp" -#include "base/small_set.hpp" -#include "base/timer.hpp" - -#include -#include -#include -#include - -#include "3party/ankerl/unordered_dense.h" - -namespace small_set_test -{ -using namespace base; - -UNIT_TEST(SmallSet_Smoke) -{ - SmallSet<300> set; - TEST_EQUAL(set.Size(), 0, ()); - for (uint64_t i = 0; i < 300; ++i) - TEST(!set.Contains(i), ()); - - set.Insert(0); - TEST_EQUAL(set.Size(), 1, ()); - TEST(set.Contains(0), ()); - - set.Insert(0); - TEST_EQUAL(set.Size(), 1, ()); - TEST(set.Contains(0), ()); - - set.Insert(5); - TEST_EQUAL(set.Size(), 2, ()); - TEST(set.Contains(0), ()); - TEST(set.Contains(5), ()); - - set.Insert(64); - TEST_EQUAL(set.Size(), 3, ()); - TEST(set.Contains(0), ()); - TEST(set.Contains(5), ()); - TEST(set.Contains(64), ()); - - { - auto cur = set.begin(); - auto end = set.end(); - for (uint64_t i : {0, 5, 64}) - { - TEST(cur != end, ()); - TEST_EQUAL(*cur, i, ()); - ++cur; - } - TEST(cur == end, ()); - } - - set.Remove(5); - TEST_EQUAL(set.Size(), 2, ()); - TEST(set.Contains(0), ()); - TEST(!set.Contains(5), ()); - TEST(set.Contains(64), ()); - - set.Insert(297); - set.Insert(298); - set.Insert(299); - TEST_EQUAL(set.Size(), 5, ()); - - { - std::vector const actual(set.begin(), set.end()); - std::vector const expected = {0, 64, 297, 298, 299}; - TEST_EQUAL(actual, expected, ()); - } - - TEST_EQUAL(set.Size(), std::distance(set.begin(), set.end()), ()); -} - -bool BenchmarkTimeLessOrNear(uint64_t l, uint64_t r, double relativeTolerance) -{ - return (l < r) || ((l - r) / static_cast(l) < relativeTolerance); -} - -#ifndef DEBUG -std::vector GenerateIndices(uint32_t min, uint32_t max) -{ - std::vector res; - - std::uniform_int_distribution randDist(min, max); - std::random_device randDevice; - std::mt19937 randEngine(randDevice()); - - for (size_t i = 0; i < 10000000; ++i) - res.push_back(randDist(randEngine)); - - return res; -} - -UNIT_TEST(SmallMap_Benchmark1) -{ - // 1. Init maps. - // Dataset is similar to routing::VehicleModel. - ankerl::unordered_dense::map uMap = { - {1, true}, {2, false}, {4, false}, {6, true}, {7, true}, {8, true}, {12, false}, - {15, false}, {26, true}, {30, false}, {36, false}, {43, false}, {54, false}, {57, true}, - {58, true}, {65, true}, {69, true}, {90, true}, {95, false}, {119, false}, {167, true}, - {176, false}, {259, true}, {272, false}, {994, true}, {1054, false}}; - - base::SmallMap sMap(uMap.begin(), uMap.end()); - - // 2. Generate indices. - std::vector indices = GenerateIndices(1, 1054); - - uint64_t t1, t2; - uint32_t sum1 = 0, sum2 = 0; - - // 3. Run unordered_map. - { - base::HighResTimer timer; - for (auto i : indices) - sum1 += (uMap.find(i) != uMap.end() ? 1 : 0); - t1 = timer.ElapsedMilliseconds(); - } - - // 4. Run SmallMap. - { - base::HighResTimer timer; - for (auto i : indices) - sum2 += (sMap.Find(i) ? 1 : 0); - t2 = timer.ElapsedMilliseconds(); - } - - TEST_EQUAL(sum1, sum2, ()); - // At this moment, we have rare t2 > t1 on Linux CI. - TEST(BenchmarkTimeLessOrNear(t2, t1, 0.3), (t2, t1)); - LOG(LINFO, ("unordered_map time =", t1, "SmallMap time =", t2)); -} - -UNIT_TEST(SmallMap_Benchmark2) -{ - using namespace std; - - uint32_t i = 0; - // Dataset is similar to routing::VehicleModelFactory. - ankerl::unordered_dense::map> uMap = { - {"", make_shared(i++)}, - {"Australia", make_shared(i++)}, - {"Austria", make_shared(i++)}, - {"Belarus", make_shared(i++)}, - {"Belgium", make_shared(i++)}, - {"Brazil", make_shared(i++)}, - {"Denmark", make_shared(i++)}, - {"France", make_shared(i++)}, - {"Finland", make_shared(i++)}, - {"Germany", make_shared(i++)}, - {"Hungary", make_shared(i++)}, - {"Iceland", make_shared(i++)}, - {"Netherlands", make_shared(i++)}, - {"Norway", make_shared(i++)}, - {"Oman", make_shared(i++)}, - {"Poland", make_shared(i++)}, - {"Romania", make_shared(i++)}, - {"Russian Federation", make_shared(i++)}, - {"Slovakia", make_shared(i++)}, - {"Spain", make_shared(i++)}, - {"Switzerland", make_shared(i++)}, - {"Turkey", make_shared(i++)}, - {"Ukraine", make_shared(i++)}, - {"United Kingdom", make_shared(i++)}, - {"United States of America", make_shared(i++)}, - }; - - base::SmallMap> sMap(uMap.begin(), uMap.end()); - - // 2. Generate indices. - std::vector keys; - for (auto const & e : uMap) - { - keys.push_back(e.first); - keys.push_back(e.first + "_Foo"); - keys.push_back(e.first + "_Bar"); - keys.push_back(e.first + "_Bazz"); - } - std::vector indices = GenerateIndices(0, keys.size() - 1); - - uint64_t t1, t2; - uint32_t sum1 = 0, sum2 = 0; - - // 3. Run unordered_map. - { - base::HighResTimer timer; - for (auto i : indices) - { - auto const it = uMap.find(keys[i]); - if (it != uMap.end()) - sum1 += *it->second; - } - t1 = timer.ElapsedMilliseconds(); - } - - // 4. Run SmallMap. - { - base::HighResTimer timer; - for (auto i : indices) - { - auto const * p = sMap.Find(keys[i]); - if (p) - sum2 += **p; - } - t2 = timer.ElapsedMilliseconds(); - } - - TEST_EQUAL(sum1, sum2, ()); - // std::hash(std::string) is better than std::less(std::string) - TEST_LESS(t1, t2, ()); - LOG(LINFO, ("unordered_map time =", t1, "SmallMap time =", t2)); -} - -// Small 4 elements sample doesn't work for new (gcc11+, clang14+) toolchain. -/* -UNIT_TEST(SmallMap_Benchmark3) -{ - // Dataset is similar to routing::VehicleModel.m_surfaceFactors. - ankerl::unordered_dense::map uMap = { - {1, 0}, {10, 1}, {100, 2}, {1000, 3}, - }; - - base::SmallMap sMap(uMap.begin(), uMap.end()); - base::SmallMapBase sbMap(uMap.begin(), uMap.end()); - - std::vector indices = GenerateIndices(0, 3); - // Missing key queries are even worse for the std map. - std::vector keys; - for (auto const & e : uMap) - keys.push_back(e.first); - - uint64_t t1, t2, t3; - uint32_t sum1 = 0, sum2 = 0, sum3 = 0; - - // 3. Run unordered_map. - { - base::HighResTimer timer; - for (auto i : indices) - sum1 += uMap.find(keys[i])->second; - t1 = timer.ElapsedMilliseconds(); - } - - // 4. Run SmallMap. - { - base::HighResTimer timer; - for (auto i : indices) - sum2 += *sMap.Find(keys[i]); - t2 = timer.ElapsedMilliseconds(); - } - - // 5. Run SmallMapBase. - { - base::HighResTimer timer; - for (auto i : indices) - sum3 += *sbMap.Find(keys[i]); - t3 = timer.ElapsedMilliseconds(); - } - - TEST_EQUAL(sum1, sum2, ()); - TEST_EQUAL(sum1, sum3, ()); - TEST_LESS(t2, t1, ()); - TEST(BenchmarkTimeLessOrNear(t3, t2, 0.05), (t3, t2)); - LOG(LINFO, ("unordered_map time =", t1, "SmallMap time =", t2, "SmallMapBase time =", t3)); -} -*/ -#endif - -} // namespace small_set_test diff --git a/libs/base/small_map.hpp b/libs/base/small_map.hpp deleted file mode 100644 index 16e6c747d..000000000 --- a/libs/base/small_map.hpp +++ /dev/null @@ -1,100 +0,0 @@ -#pragma once - -#include "assert.hpp" - -#include - -namespace base -{ - -/// Consider using as a replacement of unordered_map (map) when: -/// - very small amount of elements (<8) -template -class SmallMapBase -{ -public: - using ValueType = std::pair; - - SmallMapBase() = default; - SmallMapBase(std::initializer_list init) : m_map(std::move(init)) {} - template - SmallMapBase(Iter beg, Iter end) : m_map(beg, end) - {} - - bool operator==(SmallMapBase const & rhs) const { return m_map == rhs.m_map; } - - void Reserve(size_t count) { m_map.reserve(count); } - void Insert(Key k, Value v) { m_map.emplace_back(std::move(k), std::move(v)); } - - Value const * Find(Key const & k) const - { - for (auto const & e : m_map) - if (e.first == k) - return &e.second; - return nullptr; - } - - size_t size() const { return m_map.size(); } - auto begin() const { return m_map.begin(); } - auto end() const { return m_map.end(); } - -protected: - /// @todo buffer_vector is not suitable now, because Key/Value is not default constructible. - std::vector m_map; -}; - -/// Consider using as a replacement of unordered_map (map) when: -/// - initialize and don't modify -/// - relatively small amount of elements (8-128) -template -class SmallMap : public SmallMapBase -{ - using BaseT = SmallMapBase; - -public: - using ValueType = typename BaseT::ValueType; - - SmallMap() = default; - SmallMap(std::initializer_list init) : BaseT(std::move(init)) { FinishBuilding(); } - template - SmallMap(Iter beg, Iter end) : BaseT(beg, end) - { - FinishBuilding(); - } - - void FinishBuilding() - { - auto & theMap = this->m_map; - std::sort(theMap.begin(), theMap.end(), [](ValueType const & l, ValueType const & r) { return l.first < r.first; }); - } - - Value const * Find(Key const & k) const - { - auto const & theMap = this->m_map; - auto const it = std::lower_bound(theMap.cbegin(), theMap.cend(), k, - [](ValueType const & l, Key const & r) { return l.first < r; }); - - if (it != theMap.cend() && it->first == k) - return &(it->second); - return nullptr; - } - - void Replace(Key const & k, Value v) - { - auto & theMap = this->m_map; - auto it = std::lower_bound(theMap.begin(), theMap.end(), k, - [](ValueType const & l, Key const & r) { return l.first < r; }); - - ASSERT(it != theMap.end() && it->first == k, ()); - it->second = std::move(v); - } - - Value const & Get(Key const & k) const - { - Value const * v = Find(k); - ASSERT(v, ()); - return *v; - } -}; - -} // namespace base diff --git a/libs/base/small_set.hpp b/libs/base/small_set.hpp deleted file mode 100644 index dc37b25db..000000000 --- a/libs/base/small_set.hpp +++ /dev/null @@ -1,220 +0,0 @@ -#pragma once - -#include "base/assert.hpp" -#include "base/bits.hpp" - -#include -#include -#include -#include - -namespace base -{ -// A set of nonnegative integers less than |UpperBound|. -// -// Requires UpperBound + O(1) bits of memory. All operations except -// Clear() and iteration are O(1). Clear() and iteration require -// O(UpperBound) steps. -// -// *NOTE* This class *IS NOT* thread safe. -template -class SmallSet -{ -public: - static uint64_t constexpr kNumBlocks = (UpperBound + 63) / 64; - static_assert(kNumBlocks > 0); - - class Iterator - { - public: - using difference_type = uint64_t; - using value_type = uint64_t; - using pointer = void; - using reference = uint64_t; - using iterator_category = std::forward_iterator_tag; - - Iterator(uint64_t const * blocks, uint64_t current_block_index) - : m_blocks(blocks) - , m_current_block_index(current_block_index) - , m_current_block(0) - { - ASSERT_LESS_OR_EQUAL(current_block_index, kNumBlocks, ()); - if (current_block_index < kNumBlocks) - m_current_block = m_blocks[current_block_index]; - SkipZeroes(); - } - - bool operator==(Iterator const & rhs) const - { - return m_blocks == rhs.m_blocks && m_current_block_index == rhs.m_current_block_index && - m_current_block == rhs.m_current_block; - } - - bool operator!=(Iterator const & rhs) const { return !(*this == rhs); } - - uint64_t operator*() const - { - ASSERT_NOT_EQUAL(m_current_block, 0, ()); - auto const bit = m_current_block & -m_current_block; - return bits::FloorLog(bit) + m_current_block_index * 64; - } - - Iterator const & operator++() - { - ASSERT(m_current_block_index < kNumBlocks, ()); - ASSERT_NOT_EQUAL(m_current_block, 0, ()); - m_current_block = m_current_block & (m_current_block - 1); - SkipZeroes(); - return *this; - } - - private: - void SkipZeroes() - { - ASSERT_LESS_OR_EQUAL(m_current_block_index, kNumBlocks, ()); - - if (m_current_block != 0 || m_current_block_index == kNumBlocks) - return; - - do - ++m_current_block_index; - while (m_current_block_index < kNumBlocks && m_blocks[m_current_block_index] == 0); - if (m_current_block_index < kNumBlocks) - m_current_block = m_blocks[m_current_block_index]; - else - m_current_block = 0; - } - - uint64_t const * m_blocks; - uint64_t m_current_block_index; - uint64_t m_current_block; - }; - -#define DEFINE_BLOCK_OFFSET(value) \ - uint64_t const block = value / 64; \ - uint64_t const offset = value % 64 - - // This invalidates all iterators except end(). - void Insert(uint64_t value) - { - ASSERT_LESS(value, UpperBound, ()); - - DEFINE_BLOCK_OFFSET(value); - auto const bit = kOne << offset; - m_size += (m_blocks[block] & bit) == 0; - m_blocks[block] |= bit; - } - - // This invalidates all iterators except end(). - void Remove(uint64_t value) - { - ASSERT_LESS(value, UpperBound, ()); - - DEFINE_BLOCK_OFFSET(value); - auto const bit = kOne << offset; - m_size -= (m_blocks[block] & bit) != 0; - m_blocks[block] &= ~bit; - } - - bool Contains(uint64_t value) const - { - ASSERT_LESS(value, UpperBound, ()); - - DEFINE_BLOCK_OFFSET(value); - return m_blocks[block] & (kOne << offset); - } - -#undef DEFINE_BLOCK_OFFSET - - uint64_t Size() const { return m_size; } - - // This invalidates all iterators except end(). - void Clear() - { - std::fill(std::begin(m_blocks), std::end(m_blocks), static_cast(0)); - m_size = 0; - } - - Iterator begin() const { return Iterator(m_blocks, 0); } - Iterator cbegin() const { return Iterator(m_blocks, 0); } - - Iterator end() const { return Iterator(m_blocks, kNumBlocks); } - Iterator cend() const { return Iterator(m_blocks, kNumBlocks); } - -private: - static uint64_t constexpr kOne = 1; - - uint64_t m_blocks[kNumBlocks] = {}; - uint64_t m_size = 0; -}; - -// static -template -uint64_t constexpr SmallSet::kNumBlocks; - -// static -template -uint64_t constexpr SmallSet::kOne; - -template -std::string DebugPrint(SmallSet const & set) -{ - std::ostringstream os; - os << "SmallSet<" << UpperBound << "> [" << set.Size() << ": "; - for (auto const & v : set) - os << v << " "; - os << "]"; - return os.str(); -} - -// This is a delegate for SmallSet<>, that checks the validity of -// argument in Insert(), Remove() and Contains() methods and does -// nothing when the argument is not valid. -template -class SafeSmallSet -{ -public: - using Set = SmallSet; - using Iterator = typename Set::Iterator; - - void Insert(uint64_t value) - { - if (IsValid(value)) - m_set.Insert(value); - } - - void Remove(uint64_t value) - { - if (IsValid(value)) - m_set.Remove(value); - } - - bool Contains(uint64_t value) const { return IsValid(value) && m_set.Contains(value); } - - uint64_t Size() const { return m_set.Size(); } - - void Clear() { m_set.Clear(); } - - Iterator begin() const { return m_set.begin(); } - Iterator cbegin() const { return m_set.cbegin(); } - - Iterator end() const { return m_set.end(); } - Iterator cend() const { return m_set.cend(); } - -private: - bool IsValid(uint64_t value) const { return value < UpperBound; } - - Set m_set; -}; - -template -std::string DebugPrint(SafeSmallSet const & set) -{ - std::ostringstream os; - os << "SafeSmallSet<" << UpperBound << "> [" << set.Size() << ": "; - for (auto const v : set) - os << v << " "; - os << "]"; - return os.str(); -} -} // namespace base diff --git a/libs/drape_frontend/apply_feature_functors.cpp b/libs/drape_frontend/apply_feature_functors.cpp index 8b7b18fa0..d715dd859 100644 --- a/libs/drape_frontend/apply_feature_functors.cpp +++ b/libs/drape_frontend/apply_feature_functors.cpp @@ -28,7 +28,6 @@ #include "drape/utils/projection.hpp" #include "base/logging.hpp" -#include "base/small_map.hpp" #include "base/stl_helpers.hpp" #include @@ -37,6 +36,8 @@ #include #include +#include "3party/skarupke/flat_hash_map.hpp" + namespace df { dp::Color ToDrapeColor(uint32_t src) @@ -271,7 +272,7 @@ dp::Color GetRoadShieldColor(dp::Color const & baseColor, ftypes::RoadShield con { using ftypes::RoadShieldType; - static base::SmallMapBase kColors = { + static ska::flat_hash_map const kColors = { {RoadShieldType::Generic_White, kRoadShieldWhiteBackgroundColor}, {RoadShieldType::Generic_Green, kRoadShieldGreenBackgroundColor}, {RoadShieldType::Generic_Blue, kRoadShieldBlueBackgroundColor}, @@ -294,8 +295,9 @@ dp::Color GetRoadShieldColor(dp::Color const & baseColor, ftypes::RoadShield con {RoadShieldType::Generic_Pill_Orange_Bordered, kRoadShieldOrangeBackgroundColor}, {RoadShieldType::UK_Highway, kRoadShieldGreenBackgroundColor}}; - if (auto const * cl = kColors.Find(shield.m_type); cl) - return df::GetColorConstant(*cl); + auto const it = kColors.find(shield.m_type); + if (it != kColors.cend()) + return df::GetColorConstant(it->second); return baseColor; } @@ -304,7 +306,7 @@ dp::Color GetRoadShieldTextColor(dp::Color const & baseColor, ftypes::RoadShield { using ftypes::RoadShieldType; - static base::SmallMapBase kColors = { + static ska::flat_hash_map const kColors = { {RoadShieldType::Generic_White, kRoadShieldBlackTextColor}, {RoadShieldType::Generic_Green, kRoadShieldWhiteTextColor}, {RoadShieldType::Generic_Blue, kRoadShieldWhiteTextColor}, @@ -336,8 +338,9 @@ dp::Color GetRoadShieldTextColor(dp::Color const & baseColor, ftypes::RoadShield {RoadShieldType::Hungary_Green, kRoadShieldWhiteTextColor}, {RoadShieldType::Hungary_Blue, kRoadShieldWhiteTextColor}}; - if (auto const * cl = kColors.Find(shield.m_type); cl) - return df::GetColorConstant(*cl); + auto const it = kColors.find(shield.m_type); + if (it != kColors.cend()) + return df::GetColorConstant(it->second); return baseColor; } diff --git a/libs/editor/new_feature_categories.cpp b/libs/editor/new_feature_categories.cpp index ae220d8d0..cbd848afa 100644 --- a/libs/editor/new_feature_categories.cpp +++ b/libs/editor/new_feature_categories.cpp @@ -20,6 +20,7 @@ NewFeatureCategories::NewFeatureCategories(editor::EditorConfig const & config) } m_types.emplace_back(clType); } + m_addedLangs.reserve(CategoriesHolder::kLocaleMapping.size() + 1); } NewFeatureCategories::NewFeatureCategories(NewFeatureCategories && other) noexcept @@ -37,14 +38,14 @@ void NewFeatureCategories::AddLanguage(std::string lang) lang = "en"; langCode = CategoriesHolder::kEnglishCode; } - if (m_addedLangs.Contains(langCode)) + if (m_addedLangs.contains(langCode)) return; auto const & c = classif(); for (auto const & type : m_types) m_index.AddCategoryByTypeAndLang(c.GetTypeByReadableObjectName(type), langCode); - m_addedLangs.Insert(langCode); + m_addedLangs.insert(langCode); } NewFeatureCategories::TypeNames NewFeatureCategories::Search(std::string const & query) const diff --git a/libs/editor/new_feature_categories.hpp b/libs/editor/new_feature_categories.hpp index b691685ce..17d63f2a6 100644 --- a/libs/editor/new_feature_categories.hpp +++ b/libs/editor/new_feature_categories.hpp @@ -6,11 +6,12 @@ #include "indexer/categories_index.hpp" #include "base/macros.hpp" -#include "base/small_set.hpp" #include #include +#include "3party/ankerl/unordered_dense.h" + namespace osm { // This class holds an index of categories that can be set for a newly added feature. @@ -43,7 +44,7 @@ public: TypeNames const & GetAllCreatableTypeNames() const { return m_types; } private: - using Langs = base::SmallSet; + using Langs = ankerl::unordered_dense::set; indexer::CategoriesIndex m_index; Langs m_addedLangs; diff --git a/libs/indexer/ftypes_matcher.cpp b/libs/indexer/ftypes_matcher.cpp index 35f51e9f3..61a5ccf7c 100644 --- a/libs/indexer/ftypes_matcher.cpp +++ b/libs/indexer/ftypes_matcher.cpp @@ -339,20 +339,21 @@ IsWayChecker::IsWayChecker() {"unclassified", Minors}, }; - m_ranks.Reserve(std::size(types)); + m_ranks.reserve(std::size(types)); for (auto const & e : types) { uint32_t const type = c.GetTypeByPath({"highway", e.first}); m_types.push_back(type); - m_ranks.Insert(type, e.second); + m_ranks.insert({type, e.second}); } } IsWayChecker::SearchRank IsWayChecker::GetSearchRank(uint32_t type) const { ftype::TruncValue(type, 2); - if (auto const * res = m_ranks.Find(type)) - return *res; + auto const it = m_ranks.find(type); + if (it != m_ranks.cend()) + return it->second; return Default; } diff --git a/libs/indexer/ftypes_matcher.hpp b/libs/indexer/ftypes_matcher.hpp index a5689de48..040ede909 100644 --- a/libs/indexer/ftypes_matcher.hpp +++ b/libs/indexer/ftypes_matcher.hpp @@ -3,13 +3,16 @@ #include "indexer/feature_data.hpp" #include "indexer/feature_utils.hpp" -#include "base/small_map.hpp" #include "base/stl_helpers.hpp" +#include + #include #include #include +#include "3party/skarupke/flat_hash_map.hpp" + #define DECLARE_CHECKER_INSTANCE(CheckerType) \ static CheckerType const & Instance() \ { \ @@ -193,7 +196,7 @@ public: SearchRank GetSearchRank(uint32_t type) const; private: - base::SmallMap m_ranks; + ska::flat_hash_map> m_ranks; }; class IsStreetOrSquareChecker : public BaseChecker diff --git a/libs/routing/routing_options.cpp b/libs/routing/routing_options.cpp index af0ab010a..f5e0f554f 100644 --- a/libs/routing/routing_options.cpp +++ b/libs/routing/routing_options.cpp @@ -75,19 +75,18 @@ RoutingOptionsClassifier::RoutingOptionsClassifier() {{"psurface", "paved_good"}, RoutingOptions::Road::Paved}, {{"psurface", "paved_bad"}, RoutingOptions::Road::Paved}}; - m_data.Reserve(std::size(types)); + m_data.reserve(std::size(types)); for (auto const & data : types) - m_data.Insert(c.GetTypeByPath(data.first), data.second); - m_data.FinishBuilding(); + m_data.insert({c.GetTypeByPath(data.first), data.second}); } optional RoutingOptionsClassifier::Get(uint32_t type) const { ftype::TruncValue(type, 2); // in case of highway-motorway-bridge - auto const * res = m_data.Find(type); - if (res) - return *res; + auto const it = m_data.find(type); + if (it != m_data.cend()) + return it->second; return {}; } diff --git a/libs/routing/routing_options.hpp b/libs/routing/routing_options.hpp index 8c510f3af..4f40b3207 100644 --- a/libs/routing/routing_options.hpp +++ b/libs/routing/routing_options.hpp @@ -1,11 +1,13 @@ #pragma once -#include "base/small_map.hpp" +#include #include #include #include +#include "3party/skarupke/flat_hash_map.hpp" + namespace routing { class RoutingOptions @@ -51,7 +53,7 @@ public: static RoutingOptionsClassifier const & Instance(); private: - base::SmallMap m_data; + ska::flat_hash_map> m_data; }; RoutingOptions::Road ChooseMainRoutingOptionRoad(RoutingOptions options, bool isCarRouter); diff --git a/libs/routing_common/bicycle_model.cpp b/libs/routing_common/bicycle_model.cpp index e016b8051..209b5308f 100644 --- a/libs/routing_common/bicycle_model.cpp +++ b/libs/routing_common/bicycle_model.cpp @@ -108,7 +108,7 @@ VehicleModel::LimitsInitList NoTrunk() HighwayBasedSpeeds NormalPedestrianSpeed() { HighwayBasedSpeeds res = kDefaultSpeeds; - res.Replace(HighwayType::HighwayPedestrian, InOutCitySpeedKMpH(kSpeedOnFootwayKMpH)); + res[HighwayType::HighwayPedestrian] = InOutCitySpeedKMpH(kSpeedOnFootwayKMpH); return res; } @@ -125,15 +125,15 @@ HighwayBasedSpeeds NormalPedestrianAndFootwaySpeed() { HighwayBasedSpeeds res = kDefaultSpeeds; InOutCitySpeedKMpH const footSpeed(kSpeedOnFootwayKMpH); - res.Replace(HighwayType::HighwayPedestrian, footSpeed); - res.Replace(HighwayType::HighwayFootway, footSpeed); + res[HighwayType::HighwayPedestrian] = footSpeed; + res[HighwayType::HighwayFootway] = footSpeed; return res; } HighwayBasedSpeeds DismountPathSpeed() { HighwayBasedSpeeds res = kDefaultSpeeds; - res.Replace(HighwayType::HighwayPath, InOutCitySpeedKMpH(kSpeedDismountKMpH)); + res[HighwayType::HighwayPath] = InOutCitySpeedKMpH(kSpeedDismountKMpH); return res; } @@ -143,15 +143,15 @@ HighwayBasedSpeeds PreferFootwaysToRoads() // Decrease secondary/tertiary weight speed (-20% from default). InOutCitySpeedKMpH roadSpeed = InOutCitySpeedKMpH(SpeedKMpH(11.0, 17.0), SpeedKMpH(16.0, 19.0)); - res.Replace(HighwayType::HighwaySecondary, roadSpeed); - res.Replace(HighwayType::HighwaySecondaryLink, roadSpeed); - res.Replace(HighwayType::HighwayTertiary, roadSpeed); - res.Replace(HighwayType::HighwayTertiaryLink, roadSpeed); + res[HighwayType::HighwaySecondary] = roadSpeed; + res[HighwayType::HighwaySecondaryLink] = roadSpeed; + res[HighwayType::HighwayTertiary] = roadSpeed; + res[HighwayType::HighwayTertiaryLink] = roadSpeed; // Increase footway speed to make bigger than other roads (+20% from default roads). InOutCitySpeedKMpH footSpeed = InOutCitySpeedKMpH(SpeedKMpH(17.0, 12.0), SpeedKMpH(20.0, 15.0)); - res.Replace(HighwayType::HighwayPedestrian, footSpeed); - res.Replace(HighwayType::HighwayFootway, footSpeed); + res[HighwayType::HighwayPedestrian] = footSpeed; + res[HighwayType::HighwayFootway] = footSpeed; return res; } @@ -205,7 +205,7 @@ BicycleModel::BicycleModel(VehicleModel::LimitsInitList const & limits, HighwayB m_onedirBicycleType = cl.GetTypeByPath({"hwtag", "onedir_bicycle"}); // Assign 90% of max cycleway speed for bicycle=yes to keep choosing most preferred cycleway. - auto const yesSpeed = kDefaultSpeeds.Get(HighwayType::HighwayCycleway).m_inCity * 0.9; + auto const yesSpeed = kDefaultSpeeds.at(HighwayType::HighwayCycleway).m_inCity * 0.9; AddAdditionalRoadTypes(cl, {{std::move(hwtagYesBicycle), InOutCitySpeedKMpH(yesSpeed)}}); // Update max speed with possible ferry transfer and bicycle speed downhill. @@ -265,40 +265,39 @@ BicycleModelFactory::BicycleModelFactory(CountryParentNameGetterFn const & count : VehicleModelFactory(countryParentNameGetterFn) { using namespace bicycle_model; - using std::make_shared; // Names must be the same with country names from countries.txt - m_models[""] = make_shared(kDefaultOptions); + m_models[""] = std::make_shared(kDefaultOptions); - m_models["Australia"] = make_shared(AllAllowed(), NormalPedestrianAndFootwaySpeed()); - m_models["Austria"] = make_shared(NoTrunk(), DismountPathSpeed()); + m_models["Australia"] = std::make_shared(AllAllowed(), NormalPedestrianAndFootwaySpeed()); + m_models["Austria"] = std::make_shared(NoTrunk(), DismountPathSpeed()); // Belarus law demands to use footways for bicycles where possible. - m_models["Belarus"] = make_shared(kDefaultOptions, PreferFootwaysToRoads()); - m_models["Belgium"] = make_shared(NoTrunk(), NormalPedestrianSpeed()); - m_models["Brazil"] = make_shared(AllAllowed()); - m_models["Denmark"] = make_shared(NoTrunk()); - m_models["France"] = make_shared(NoTrunk(), NormalPedestrianSpeed()); - m_models["Finland"] = make_shared(kDefaultOptions, NormalPedestrianSpeed()); - m_models["Hungary"] = make_shared(NoTrunk()); - m_models["Iceland"] = make_shared(AllAllowed(), NormalPedestrianAndFootwaySpeed()); - m_models["Ireland"] = make_shared(AllAllowed()); - m_models["Italy"] = make_shared(kDefaultOptions, NormalPedestrianSpeed()); - m_models["Netherlands"] = make_shared(NoTrunk()); - m_models["Norway"] = make_shared(AllAllowed(), NormalPedestrianAndFootwaySpeed()); - m_models["Oman"] = make_shared(AllAllowed()); - m_models["Philippines"] = make_shared(AllAllowed(), NormalPedestrianSpeed()); - m_models["Poland"] = make_shared(NoTrunk()); - m_models["Romania"] = make_shared(AllAllowed()); + m_models["Belarus"] = std::make_shared(kDefaultOptions, PreferFootwaysToRoads()); + m_models["Belgium"] = std::make_shared(NoTrunk(), NormalPedestrianSpeed()); + m_models["Brazil"] = std::make_shared(AllAllowed()); + m_models["Denmark"] = std::make_shared(NoTrunk()); + m_models["France"] = std::make_shared(NoTrunk(), NormalPedestrianSpeed()); + m_models["Finland"] = std::make_shared(kDefaultOptions, NormalPedestrianSpeed()); + m_models["Hungary"] = std::make_shared(NoTrunk()); + m_models["Iceland"] = std::make_shared(AllAllowed(), NormalPedestrianAndFootwaySpeed()); + m_models["Ireland"] = std::make_shared(AllAllowed()); + m_models["Italy"] = std::make_shared(kDefaultOptions, NormalPedestrianSpeed()); + m_models["Netherlands"] = std::make_shared(NoTrunk()); + m_models["Norway"] = std::make_shared(AllAllowed(), NormalPedestrianAndFootwaySpeed()); + m_models["Oman"] = std::make_shared(AllAllowed()); + m_models["Philippines"] = std::make_shared(AllAllowed(), NormalPedestrianSpeed()); + m_models["Poland"] = std::make_shared(NoTrunk()); + m_models["Romania"] = std::make_shared(AllAllowed()); // Note. Despite the fact that according to // https://wiki.openstreetmap.org/wiki/OSM_tags_for_routing/Access-Restrictions passing through service and // living_street with a bicycle is prohibited it's allowed according to Russian traffic rules. - m_models["Russian Federation"] = make_shared(kDefaultOptions, NormalPedestrianAndFootwaySpeed()); - m_models["Slovakia"] = make_shared(NoTrunk()); - m_models["Spain"] = make_shared(NoTrunk(), NormalPedestrianSpeed()); - m_models["Sweden"] = make_shared(kDefaultOptions, NormalPedestrianSpeed()); - m_models["Switzerland"] = make_shared(NoTrunk(), NormalPedestrianAndFootwaySpeed()); - m_models["Ukraine"] = make_shared(UkraineOptions()); - m_models["United Kingdom"] = make_shared(AllAllowed()); - m_models["United States of America"] = make_shared(AllAllowed(), NormalPedestrianSpeed()); + m_models["Russian Federation"] = std::make_shared(kDefaultOptions, NormalPedestrianAndFootwaySpeed()); + m_models["Slovakia"] = std::make_shared(NoTrunk()); + m_models["Spain"] = std::make_shared(NoTrunk(), NormalPedestrianSpeed()); + m_models["Sweden"] = std::make_shared(kDefaultOptions, NormalPedestrianSpeed()); + m_models["Switzerland"] = std::make_shared(NoTrunk(), NormalPedestrianAndFootwaySpeed()); + m_models["Ukraine"] = std::make_shared(UkraineOptions()); + m_models["United Kingdom"] = std::make_shared(AllAllowed()); + m_models["United States of America"] = std::make_shared(AllAllowed(), NormalPedestrianSpeed()); } } // namespace routing diff --git a/libs/routing_common/car_model.cpp b/libs/routing_common/car_model.cpp index 1f7e17c16..aaa405cec 100644 --- a/libs/routing_common/car_model.cpp +++ b/libs/routing_common/car_model.cpp @@ -97,7 +97,7 @@ CarModel::CarModel(VehicleModel::LimitsInitList const & roadLimits) m_yesType = cl.GetTypeByPath(hwtagYesCar); // Set small track speed if highway is not in kHighwayBasedSpeeds (path, pedestrian), but marked as yescar. - AddAdditionalRoadTypes(cl, {{std::move(hwtagYesCar), kHighwayBasedSpeeds.Get(HighwayType::HighwayTrack)}}); + AddAdditionalRoadTypes(cl, {{std::move(hwtagYesCar), kHighwayBasedSpeeds.at(HighwayType::HighwayTrack)}}); // Set max possible (reasonable) car speed. See EdgeEstimator::CalcHeuristic. SpeedKMpH constexpr kMaxCarSpeedKMpH(200.0); diff --git a/libs/routing_common/pedestrian_model.cpp b/libs/routing_common/pedestrian_model.cpp index d0ae676b5..a31554bf4 100644 --- a/libs/routing_common/pedestrian_model.cpp +++ b/libs/routing_common/pedestrian_model.cpp @@ -125,8 +125,8 @@ HighwayBasedSpeeds IncreasePrimary() { /// @todo Probably, should make Primary = Secondary = 4. HighwayBasedSpeeds res = pedestrian_model::kDefaultSpeeds; - res.Replace(HighwayType::HighwayPrimary, InOutCitySpeedKMpH(SpeedKMpH(3.0, 5.0))); - res.Replace(HighwayType::HighwayPrimaryLink, InOutCitySpeedKMpH(SpeedKMpH(3.0, 5.0))); + res[HighwayType::HighwayPrimary] = InOutCitySpeedKMpH(SpeedKMpH(3.0, 5.0)); + res[HighwayType::HighwayPrimaryLink] = InOutCitySpeedKMpH(SpeedKMpH(3.0, 5.0)); return res; } @@ -163,7 +163,7 @@ PedestrianModel::PedestrianModel(VehicleModel::LimitsInitList const & limits, Hi m_noType = cl.GetTypeByPath({"hwtag", "nofoot"}); m_yesType = cl.GetTypeByPath(hwtagYesFoot); - AddAdditionalRoadTypes(cl, {{std::move(hwtagYesFoot), kDefaultSpeeds.Get(HighwayType::HighwayLivingStreet)}}); + AddAdditionalRoadTypes(cl, {{std::move(hwtagYesFoot), kDefaultSpeeds.at(HighwayType::HighwayLivingStreet)}}); // Update max pedestrian speed with possible ferry transfer. See EdgeEstimator::CalcHeuristic. SpeedKMpH constexpr kMaxPedestrianSpeedKMpH(60.0); @@ -194,38 +194,37 @@ PedestrianModelFactory::PedestrianModelFactory(CountryParentNameGetterFn const & : VehicleModelFactory(countryParentNameGetterFn) { using namespace pedestrian_model; - using std::make_shared; // Names must be the same with country names from countries.txt - m_models[""] = make_shared(kDefaultOptions); + m_models[""] = std::make_shared(kDefaultOptions); - m_models["Australia"] = make_shared(AllAllowed()); - m_models["Austria"] = make_shared(NoTrunk()); - m_models["Belarus"] = make_shared(YesCycleway()); - m_models["Belgium"] = make_shared(YesCycleway(YesBridleway(NoTrunk()))); - m_models["Brazil"] = make_shared(YesBridleway()); - m_models["Denmark"] = make_shared(YesCycleway(NoTrunk())); - m_models["France"] = make_shared(NoTrunk()); - m_models["Finland"] = make_shared(YesCycleway()); - m_models["Georgia"] = make_shared(AllAllowed(), IncreasePrimary()); - m_models["Greece"] = make_shared(YesCycleway(YesBridleway(NoTrunk()))); - m_models["Hungary"] = make_shared(NoTrunk()); - m_models["Iceland"] = make_shared(AllAllowed()); - m_models["Ireland"] = make_shared(AllAllowed()); - m_models["Netherlands"] = make_shared(YesCycleway(NoTrunk())); - m_models["Norway"] = make_shared(AllAllowed()); - m_models["Oman"] = make_shared(AllAllowed()); - m_models["Philippines"] = make_shared(AllAllowed()); - m_models["Poland"] = make_shared(YesBridleway(NoTrunk())); - m_models["Romania"] = make_shared(YesBridleway()); - m_models["Russian Federation"] = make_shared(YesCycleway()); - m_models["Slovakia"] = make_shared(NoTrunk()); - m_models["Spain"] = make_shared(NoTrunk()); - m_models["Sweden"] = make_shared(AllAllowed()); - m_models["Switzerland"] = make_shared(NoTrunk()); - m_models["Turkey"] = make_shared(AllAllowed(), IncreasePrimary()); - m_models["Ukraine"] = make_shared(NoTrunk()); - m_models["United Kingdom"] = make_shared(AllAllowed()); - m_models["United States of America"] = make_shared(AllAllowed()); + m_models["Australia"] = std::make_shared(AllAllowed()); + m_models["Austria"] = std::make_shared(NoTrunk()); + m_models["Belarus"] = std::make_shared(YesCycleway()); + m_models["Belgium"] = std::make_shared(YesCycleway(YesBridleway(NoTrunk()))); + m_models["Brazil"] = std::make_shared(YesBridleway()); + m_models["Denmark"] = std::make_shared(YesCycleway(NoTrunk())); + m_models["France"] = std::make_shared(NoTrunk()); + m_models["Finland"] = std::make_shared(YesCycleway()); + m_models["Georgia"] = std::make_shared(AllAllowed(), IncreasePrimary()); + m_models["Greece"] = std::make_shared(YesCycleway(YesBridleway(NoTrunk()))); + m_models["Hungary"] = std::make_shared(NoTrunk()); + m_models["Iceland"] = std::make_shared(AllAllowed()); + m_models["Ireland"] = std::make_shared(AllAllowed()); + m_models["Netherlands"] = std::make_shared(YesCycleway(NoTrunk())); + m_models["Norway"] = std::make_shared(AllAllowed()); + m_models["Oman"] = std::make_shared(AllAllowed()); + m_models["Philippines"] = std::make_shared(AllAllowed()); + m_models["Poland"] = std::make_shared(YesBridleway(NoTrunk())); + m_models["Romania"] = std::make_shared(YesBridleway()); + m_models["Russian Federation"] = std::make_shared(YesCycleway()); + m_models["Slovakia"] = std::make_shared(NoTrunk()); + m_models["Spain"] = std::make_shared(NoTrunk()); + m_models["Sweden"] = std::make_shared(AllAllowed()); + m_models["Switzerland"] = std::make_shared(NoTrunk()); + m_models["Turkey"] = std::make_shared(AllAllowed(), IncreasePrimary()); + m_models["Ukraine"] = std::make_shared(NoTrunk()); + m_models["United Kingdom"] = std::make_shared(AllAllowed()); + m_models["United States of America"] = std::make_shared(AllAllowed()); } } // namespace routing diff --git a/libs/routing_common/vehicle_model.cpp b/libs/routing_common/vehicle_model.cpp index b7fad0cd2..d74a6f713 100644 --- a/libs/routing_common/vehicle_model.cpp +++ b/libs/routing_common/vehicle_model.cpp @@ -33,19 +33,18 @@ VehicleModel::VehicleModel(Classificator const & classif, LimitsInitList const & : m_highwayBasedInfo(info) , m_onewayType(ftypes::IsOneWayChecker::Instance().GetType()) { - m_roadTypes.Reserve(featureTypeLimits.size()); + m_roadTypes.reserve(featureTypeLimits.size()); for (auto const & v : featureTypeLimits) { - auto const * speed = info.m_speeds.Find(v.m_type); - ASSERT(speed, ("Can't found speed for", v.m_type)); + auto const it = info.m_speeds.find(v.m_type); + ASSERT_EQUAL(it, info.m_speeds.cend(), ("Can't found speed for", v.m_type)); - m_maxModelSpeed = Max(m_maxModelSpeed, *speed); + m_maxModelSpeed = Max(m_maxModelSpeed, it->second); - m_roadTypes.Insert(classif.GetTypeForIndex(static_cast(v.m_type)), v.m_isPassThroughAllowed); + m_roadTypes.insert({classif.GetTypeForIndex(static_cast(v.m_type)), v.m_isPassThroughAllowed}); } - m_roadTypes.FinishBuilding(); - m_surfaceFactors.Reserve(featureTypeSurface.size()); + m_surfaceFactors.reserve(featureTypeSurface.size()); for (auto const & v : featureTypeSurface) { auto const & speedFactor = v.m_factor; @@ -53,7 +52,7 @@ VehicleModel::VehicleModel(Classificator const & classif, LimitsInitList const & ASSERT_LESS_OR_EQUAL(speedFactor.m_eta, 1.0, ()); ASSERT_GREATER(speedFactor.m_weight, 0.0, ()); ASSERT_GREATER(speedFactor.m_eta, 0.0, ()); - m_surfaceFactors.Insert(classif.GetTypeByPath(v.m_type), speedFactor); + m_surfaceFactors.insert({classif.GetTypeByPath(v.m_type), speedFactor}); if (v.m_type[1] == "paved_bad") m_minSurfaceFactorForMaxspeed = speedFactor; @@ -65,9 +64,9 @@ void VehicleModel::AddAdditionalRoadTypes(Classificator const & classif, Additio for (auto const & r : roads) { uint32_t const type = classif.GetTypeByPath(r.m_type); - if (m_roadTypes.Find(type) == nullptr) + if (m_roadTypes.find(type) == m_roadTypes.cend()) { - m_addRoadTypes.Insert(type, r.m_speed); + m_addRoadTypes.insert({type, r.m_speed}); m_maxModelSpeed = Max(m_maxModelSpeed, r.m_speed); } } @@ -95,17 +94,16 @@ double VehicleModel::GetMaxWeightSpeed() const optional VehicleModel::GetHighwayType(uint32_t type) const { - auto const * value = m_roadTypes.Find(type); - if (value) + if (m_roadTypes.find(type) != m_roadTypes.cend()) return static_cast(classif().GetIndexForType(type)); return {}; } void VehicleModel::GetSurfaceFactor(uint32_t type, SpeedFactor & factor) const { - auto const * surface = m_surfaceFactors.Find(type); - if (surface) - factor = Pick(factor, *surface); + auto const it = m_surfaceFactors.find(type); + if (it != m_surfaceFactors.cend()) + factor = Pick(factor, it->second); ASSERT_LESS_OR_EQUAL(factor.m_weight, 1.0, ()); ASSERT_LESS_OR_EQUAL(factor.m_eta, 1.0, ()); @@ -115,12 +113,12 @@ void VehicleModel::GetSurfaceFactor(uint32_t type, SpeedFactor & factor) const void VehicleModel::GetAdditionalRoadSpeed(uint32_t type, bool isCityRoad, optional & speed) const { - auto const * s = m_addRoadTypes.Find(type); - if (s) + auto const it = m_addRoadTypes.find(type); + if (it != m_addRoadTypes.cend()) { // Now we have only 1 additional type "yes" for all models. ASSERT(!speed, ()); - speed = isCityRoad ? s->m_inCity : s->m_outCity; + speed = isCityRoad ? it->second.m_inCity : it->second.m_outCity; } } @@ -157,9 +155,9 @@ SpeedKMpH VehicleModel::GetTypeSpeedImpl(FeatureTypes const & types, SpeedParams } else { - auto const * s = m_highwayBasedInfo.m_speeds.Find(*hwType); - ASSERT(s, ("Key:", *hwType, "is not found.")); - speed = s->GetSpeed(isCityRoad); + auto const it = m_highwayBasedInfo.m_speeds.find(*hwType); + ASSERT_EQUAL(it, m_highwayBasedInfo.m_speeds.cend(), ("Key:", *hwType, "is not found.")); + speed = it->second.GetSpeed(isCityRoad); if (isCar) { @@ -183,9 +181,9 @@ SpeedKMpH VehicleModel::GetTypeSpeedImpl(FeatureTypes const & types, SpeedParams } auto const typeKey = *hwType; - auto const * factor = m_highwayBasedInfo.m_factors.Find(typeKey); - ASSERT(factor, ("Key:", typeKey, "is not found.")); - auto const & f = factor->GetFactor(isCityRoad); + auto const it = m_highwayBasedInfo.m_factors.find(typeKey); + ASSERT_EQUAL(it, m_highwayBasedInfo.m_factors.cend(), ("Key:", typeKey, "is not found.")); + auto const & f = it->second.GetFactor(isCityRoad); speed.m_weight *= f.m_weight; speed.m_eta *= f.m_eta; } @@ -218,12 +216,12 @@ bool VehicleModel::IsPassThroughAllowed(FeatureTypes const & types) const ftype::TruncValue(t, 2); // Additional types (like ferry) are always pass-through now. - if (m_addRoadTypes.Find(t)) + if (m_addRoadTypes.find(t) != m_addRoadTypes.cend()) return true; - bool const * allow = m_roadTypes.Find(t); - if (allow && *allow) - return true; + auto const it = m_roadTypes.find(t); + if (it != m_roadTypes.cend()) + return it->second; } return false; @@ -232,7 +230,7 @@ bool VehicleModel::IsPassThroughAllowed(FeatureTypes const & types) const bool VehicleModel::IsRoadType(uint32_t type) const { ftype::TruncValue(type, 2); - return m_addRoadTypes.Find(type) || m_roadTypes.Find(type); + return m_addRoadTypes.find(type) != m_addRoadTypes.cend() || m_roadTypes.find(type) != m_roadTypes.cend(); } bool VehicleModel::IsRoadImpl(FeatureTypes const & types) const diff --git a/libs/routing_common/vehicle_model.hpp b/libs/routing_common/vehicle_model.hpp index 3d4fc95ac..523d07a52 100644 --- a/libs/routing_common/vehicle_model.hpp +++ b/libs/routing_common/vehicle_model.hpp @@ -4,7 +4,7 @@ #include "indexer/feature_data.hpp" -#include "base/small_map.hpp" +#include #include #include @@ -15,6 +15,7 @@ #include #include "3party/ankerl/unordered_dense.h" +#include "3party/skarupke/flat_hash_map.hpp" class Classificator; class FeatureType; @@ -60,8 +61,8 @@ enum class HighwayType : uint16_t RouteShuttleTrain = 1054, }; -using HighwayBasedFactors = base::SmallMap; -using HighwayBasedSpeeds = base::SmallMap; +using HighwayBasedFactors = ska::flat_hash_map>; +using HighwayBasedSpeeds = ska::flat_hash_map>; /// \brief Params for calculation of an approximate speed on a feature. struct SpeedParams @@ -330,13 +331,13 @@ private: uint32_t m_onewayType; // HW type -> allow pass through. - base::SmallMap m_roadTypes; + ska::flat_hash_map> m_roadTypes; // Mapping surface types psurface={paved_good/paved_bad/unpaved_good/unpaved_bad} to surface speed factors. - base::SmallMapBase m_surfaceFactors; + ska::flat_hash_map> m_surfaceFactors; SpeedFactor m_minSurfaceFactorForMaxspeed; /// @todo Do we really need a separate map here or can merge with the m_roadTypes map? - base::SmallMapBase m_addRoadTypes; + ska::flat_hash_map> m_addRoadTypes; }; class VehicleModelFactory : public VehicleModelFactoryInterface diff --git a/libs/search/common.hpp b/libs/search/common.hpp index 1e7799483..cfa268508 100644 --- a/libs/search/common.hpp +++ b/libs/search/common.hpp @@ -3,9 +3,10 @@ #include "indexer/categories_holder.hpp" #include "base/buffer_vector.hpp" -#include "base/small_set.hpp" #include "base/string_utils.hpp" +#include "3party/ankerl/unordered_dense.h" + namespace search { // The prefix is stored separately. @@ -13,7 +14,7 @@ namespace search // the prefix and non-prefix tokens. using QueryTokens = buffer_vector; -using Locales = base::SafeSmallSet; +using Locales = ankerl::unordered_dense::set; /// Upper bound for max count of tokens for indexing and scoring. size_t constexpr kMaxNumTokens = 32; diff --git a/libs/search/processor.cpp b/libs/search/processor.cpp index 77b44e523..d9b39f5cb 100644 --- a/libs/search/processor.cpp +++ b/libs/search/processor.cpp @@ -495,11 +495,11 @@ Locales Processor::GetCategoryLocales() const Locales result; // Prepare array of processing locales. English locale is always present for category matching. - result.Insert(static_cast(enLocaleCode)); + result.insert(static_cast(enLocaleCode)); if (m_currentLocaleCode != -1) - result.Insert(static_cast(m_currentLocaleCode)); + result.insert(static_cast(m_currentLocaleCode)); if (m_inputLocaleCode != -1) - result.Insert(static_cast(m_inputLocaleCode)); + result.insert(static_cast(m_inputLocaleCode)); return result; } @@ -829,7 +829,7 @@ void Processor::InitParams(QueryParams & params) const for (size_t i = 0; i < params.GetNumTokens(); ++i) base::SortUnique(params.GetTypeIndices(i)); - m_keywordsScorer.ForEachLanguage([¶ms](int8_t lang) { params.GetLangs().Insert(static_cast(lang)); }); + m_keywordsScorer.ForEachLanguage([¶ms](int8_t lang) { params.GetLangs().insert(static_cast(lang)); }); } void Processor::InitGeocoder(Geocoder::Params & geocoderParams, SearchParams const & searchParams) diff --git a/libs/search/query_params.cpp b/libs/search/query_params.cpp index e3c2deb5e..6692572b5 100644 --- a/libs/search/query_params.cpp +++ b/libs/search/query_params.cpp @@ -1542,7 +1542,7 @@ void QueryParams::Clear() m_hasPrefix = false; m_isCommonToken.clear(); m_typeIndices.clear(); - m_langs.Clear(); + m_langs.clear(); } bool QueryParams::IsCategorySynonym(size_t i) const @@ -1637,7 +1637,7 @@ string DebugPrint(QueryParams const & params) ostringstream os; os << boolalpha << "QueryParams " << "{ m_tokens: " << ::DebugPrint(params.m_tokens) << ", m_prefixToken: " << DebugPrint(params.m_prefixToken) - << ", m_typeIndices: " << ::DebugPrint(params.m_typeIndices) << ", m_langs: " << DebugPrint(params.m_langs) + << ", m_typeIndices: " << ::DebugPrint(params.m_typeIndices) << ", m_langs: " << ::DebugPrint(params.m_langs) << ", m_isCommonToken: " << ::DebugPrint(params.m_isCommonToken) << " }"; return os.str(); } diff --git a/libs/search/query_params.hpp b/libs/search/query_params.hpp index 85d1a9519..c53d1ead5 100644 --- a/libs/search/query_params.hpp +++ b/libs/search/query_params.hpp @@ -3,13 +3,14 @@ #include "coding/string_utf8_multilang.hpp" #include "base/assert.hpp" -#include "base/small_set.hpp" #include "base/string_utils.hpp" #include #include #include +#include "3party/ankerl/unordered_dense.h" + namespace search { class TokenRange; @@ -19,7 +20,7 @@ class QueryParams public: using String = strings::UniString; using TypeIndices = std::vector; - using Langs = base::SafeSmallSet; + using Langs = ankerl::unordered_dense::set; class Token { @@ -127,7 +128,7 @@ public: Langs & GetLangs() { return m_langs; } Langs const & GetLangs() const { return m_langs; } - bool LangExists(int8_t lang) const { return m_langs.Contains(lang); } + bool LangExists(int8_t lang) const { return m_langs.contains(lang); } void SetCategorialRequest(bool isCategorial) { m_isCategorialRequest = isCategorial; } bool IsCategorialRequest() const { return m_isCategorialRequest; } @@ -147,5 +148,10 @@ private: std::vector m_typeIndices; Langs m_langs; + + inline std::string DebugPrint(Langs const & v) + { + return DebugPrintSequence(v.cbegin(), v.cend()); + } }; } // namespace search diff --git a/libs/search/search_tests/locality_scorer_test.cpp b/libs/search/search_tests/locality_scorer_test.cpp index 69e19b217..ef138da1b 100644 --- a/libs/search/search_tests/locality_scorer_test.cpp +++ b/libs/search/search_tests/locality_scorer_test.cpp @@ -22,6 +22,7 @@ #include #include "3party/ankerl/unordered_dense.h" +#include "3party/skarupke/flat_hash_map.hpp" namespace locality_scorer_test { diff --git a/libs/search/utils.cpp b/libs/search/utils.cpp index d85bed986..dbd76c019 100644 --- a/libs/search/utils.cpp +++ b/libs/search/utils.cpp @@ -20,7 +20,7 @@ std::vector GetCategoryTypes(std::string const & name, std::string con int8_t const code = CategoriesHolder::MapLocaleToInteger(locale); Locales locales; - locales.Insert(static_cast(code)); + locales.insert(static_cast(code)); auto const tokens = NormalizeAndTokenizeString(name); diff --git a/libs/search/utils.hpp b/libs/search/utils.hpp index 985139df9..0f9fe6001 100644 --- a/libs/search/utils.hpp +++ b/libs/search/utils.hpp @@ -85,7 +85,7 @@ bool FillCategories(QuerySliceOnRawStrings const & slice, Locales const & loc types.clear(); catHolder.ForEachNameAndType([&](CategoriesHolder::Category::Name const & categorySynonym, uint32_t type) { - if (!locales.Contains(static_cast(categorySynonym.m_locale))) + if (!locales.contains(static_cast(categorySynonym.m_locale))) return; auto const categoryTokens = NormalizeAndTokenizeString(categorySynonym.m_name);