From d8fa9aa322d00e796402cf99a35bdeae9b193c8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Tue, 13 May 2014 12:01:29 +0200 Subject: [PATCH] move weak_ptr list of tile_data objects to a map for faster lookups --- include/llmr/map/source.hpp | 3 ++- include/llmr/util/std.hpp | 17 +++++++++++++++++ src/map/source.cpp | 16 +++++++--------- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/include/llmr/map/source.hpp b/include/llmr/map/source.hpp index 7d47d61b7..da2d87ae8 100644 --- a/include/llmr/map/source.hpp +++ b/include/llmr/map/source.hpp @@ -12,6 +12,7 @@ #include #include #include +#include namespace llmr { @@ -69,7 +70,7 @@ private: const int32_t max_zoom; std::forward_list tiles; - std::forward_list> tile_data; + std::map> tile_data; }; } diff --git a/include/llmr/util/std.hpp b/include/llmr/util/std.hpp index 4ef28d5f8..c09aa5ff6 100644 --- a/include/llmr/util/std.hpp +++ b/include/llmr/util/std.hpp @@ -11,6 +11,23 @@ template return ::std::unique_ptr(new T(::std::forward(args)...)); } + +template +void erase_if(Container &container, ForwardIterator it, const ForwardIterator end, Predicate pred) { + while (it != end) { + if (pred(*it)) { + container.erase(it++); + } else { + ++it; + } + } +} + +template +void erase_if(Container &container, Predicate pred) { + erase_if(container, container.begin(), container.end(), pred); +} + } #endif diff --git a/src/map/source.cpp b/src/map/source.cpp index 384cb0a62..5571f74c7 100644 --- a/src/map/source.cpp +++ b/src/map/source.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include @@ -110,13 +111,10 @@ TileData::State Source::addTile(const Tile::ID& id) { // Try to find the associated TileData object. const Tile::ID normalized_id = id.normalized(); - auto it = std::find_if(tile_data.begin(), tile_data.end(), [normalized_id](const std::weak_ptr& tile_data) { - return !tile_data.expired() && tile_data.lock()->id == normalized_id; - }); - + auto it = tile_data.find(normalized_id); if (it != tile_data.end()) { // Create a shared_ptr handle. Note that this might be empty! - new_tile.data = it->lock(); + new_tile.data = it->second.lock(); } if (new_tile.data && new_tile.data->state == TileData::State::obsolete) { @@ -138,7 +136,7 @@ TileData::State Source::addTile(const Tile::ID& id) { } new_tile.data->request(); - tile_data.push_front(new_tile.data); + tile_data.emplace(new_tile.data->id, new_tile.data); } return new_tile.data->state; @@ -269,9 +267,9 @@ bool Source::updateTiles() { return a.id.z < b.id.z; }); - // Remove all the expired pointers from the list. - tile_data.remove_if([&retain_data](const std::weak_ptr& tile_data) { - const std::shared_ptr tile = tile_data.lock(); + // Remove all the expired pointers from the set. + std::erase_if(tile_data, [&retain_data](const std::pair>& pair) { + const std::shared_ptr tile = pair.second.lock(); if (!tile) { return true; }