@@ -49,11 +49,14 @@ constexpr std::uint32_t kMaxQuadTreeIndexDepth = 4u;
4949SubQuadsResult FlattenTree (const QuadTreeIndex& tree) {
5050 SubQuadsResult result;
5151 auto index_data = tree.GetIndexData ();
52- std::transform (index_data.begin (), index_data.end (),
53- std::inserter (result, result.end ()),
54- [](const QuadTreeIndex::IndexData& data) {
55- return std::make_pair (data.tile_key , data.data_handle );
56- });
52+ for (auto & data : index_data) {
53+ const auto it = result.lower_bound (data.tile_key );
54+ if (it == result.end () || result.key_comp ()(data.tile_key , it->first )) {
55+ result.emplace_hint (it, std::piecewise_construct,
56+ std::forward_as_tuple (data.tile_key ),
57+ std::forward_as_tuple (std::move (data.data_handle )));
58+ }
59+ }
5760 return result;
5861}
5962
@@ -173,8 +176,8 @@ RootTilesForRequest PrefetchTilesRepository::GetSlicedTiles(
173176}
174177
175178client::NetworkStatistics PrefetchTilesRepository::LoadAggregatedSubQuads (
176- geo::TileKey root, const SubQuadsResult& tiles, std::int64_t version ,
177- client::CancellationContext context) {
179+ geo::TileKey root, const std::vector<geo::TileKey>& tiles ,
180+ std:: int64_t version, client::CancellationContext context) {
178181 // if quad tree isn't cached, no reason to download additional quads
179182 QuadTreeIndex quad_tree;
180183 client::NetworkStatistics network_stats;
@@ -191,7 +194,7 @@ client::NetworkStatistics PrefetchTilesRepository::LoadAggregatedSubQuads(
191194 // found in subtiles. In this way we make sure that all tiles within requested
192195 // tree have aggregated parent downloaded and cached. This may cause
193196 // additional or duplicate download request.
194- auto root_index = quad_tree.Find (highest_tile_it-> first , true );
197+ auto root_index = quad_tree.Find (* highest_tile_it, true );
195198 if (root_index) {
196199 const auto & aggregated_tile_key = root_index->tile_key ;
197200
@@ -316,89 +319,113 @@ SubQuadsResponse PrefetchTilesRepository::GetVolatileSubQuads(
316319 return result;
317320}
318321
319- SubQuadsResult PrefetchTilesRepository::FilterTilesByLevel (
320- const PrefetchTilesRequest& request, SubQuadsResult tiles) {
321- const auto & tile_keys = request.GetTileKeys ();
322-
323- auto skip_tile = [&](const geo::TileKey& tile_key) {
324- if (tile_key.Level () < request.GetMinLevel ()) {
325- return true ;
326- }
327-
328- if (tile_key.Level () > request.GetMaxLevel ()) {
329- return true ;
330- }
331-
332- return std::find_if (tile_keys.begin (), tile_keys.end (),
333- [&tile_key](const geo::TileKey& root_key) {
334- return (root_key.IsParentOf (tile_key) ||
335- tile_key.IsParentOf (root_key) ||
336- root_key == tile_key);
337- }) == tile_keys.end ();
338- };
322+ static bool skip_tile (const PrefetchTilesRequest& request,
323+ const geo::TileKey& tile_key) {
324+ if (tile_key.Level () < request.GetMinLevel () ||
325+ tile_key.Level () > request.GetMaxLevel ()) {
326+ return true ;
327+ }
328+ for (const geo::TileKey& root_key : request.GetTileKeys ()) {
329+ if (root_key == tile_key || root_key.IsParentOf (tile_key) ||
330+ tile_key.IsParentOf (root_key))
331+ return false ;
332+ }
333+ return true ;
334+ }
339335
336+ void PrefetchTilesRepository::FilterTilesByLevel (
337+ const PrefetchTilesRequest& request, SubQuadsResult& tiles) const {
340338 for (auto sub_quad_it = tiles.begin (); sub_quad_it != tiles.end ();) {
341- if (skip_tile (sub_quad_it->first )) {
339+ if (skip_tile (request, sub_quad_it->first )) {
342340 sub_quad_it = tiles.erase (sub_quad_it);
343341 } else {
344342 ++sub_quad_it;
345343 }
346344 }
345+ }
347346
348- return tiles;
347+ std::vector<geo::TileKey> PrefetchTilesRepository::FilterTileKeysByLevel (
348+ const PrefetchTilesRequest& request, const SubQuadsResult& tiles) const {
349+ std::vector<geo::TileKey> result;
350+ for (const auto & tile : tiles) {
351+ if (!skip_tile (request, tile.first )) {
352+ result.emplace_back (tile.first );
353+ }
354+ }
355+ return result;
349356}
350357
351- SubQuadsResult PrefetchTilesRepository::FilterTilesByList (
352- const PrefetchTilesRequest& request, SubQuadsResult tiles) {
353- const bool aggregation_enabled = request. GetDataAggregationEnabled () ;
358+ void PrefetchTilesRepository::FilterTilesByList (
359+ const PrefetchTilesRequest& request, SubQuadsResult& tiles) const {
360+ SubQuadsResult result ;
354361
362+ const bool aggregation_enabled = request.GetDataAggregationEnabled ();
355363 const auto & tile_keys = request.GetTileKeys ();
356364
357365 if (!aggregation_enabled) {
358- for (auto it = tiles. begin (); it != tiles. end (); ) {
359- if ( std::find (tile_keys. begin (), tile_keys. end (), it-> first ) ==
360- tile_keys. end ()) {
361- it = tiles.erase (it);
362- } else {
363- ++it ;
366+ for (const auto & tile : tile_keys ) {
367+ const auto it = tiles. find (tile);
368+ auto & new_tile = result[tile];
369+ if ( it ! = tiles.end ()) {
370+ new_tile = std::move (it-> second );
371+ tiles. erase (it) ;
364372 }
365373 }
374+ } else {
375+ auto append_tile = [&](const geo::TileKey& key) {
376+ const auto it = tiles.find (key);
377+ if (it != tiles.end ()) {
378+ result.emplace (key, std::move (it->second ));
379+ return true ;
380+ } else {
381+ return result.find (key) != result.end ();
382+ }
383+ };
366384
367385 for (const auto & tile : tile_keys) {
368- if (tiles.find (tile) == tiles.end ()) {
369- tiles[tile] = " " ;
386+ auto aggregated_tile = tile;
387+
388+ while (aggregated_tile.IsValid () && !append_tile (aggregated_tile)) {
389+ aggregated_tile = aggregated_tile.Parent ();
390+ }
391+
392+ if (!aggregated_tile.IsValid ()) {
393+ result[tile].clear (); // To generate Not Found error
370394 }
371395 }
396+ }
397+ tiles.swap (result);
398+ }
372399
373- } else {
374- SubQuadsResult result;
400+ std::vector<geo::TileKey> PrefetchTilesRepository::FilterTileKeysByList (
401+ const PrefetchTilesRequest& request, const SubQuadsResult& tiles) const {
402+ std::vector<geo::TileKey> result;
375403
376- auto append_tile = [&](const geo::TileKey& key) {
377- auto tile_it = tiles.find (key);
378- if (tile_it != tiles.end ()) {
379- result[tile_it->first ] = tile_it->second ;
404+ if (!request.GetDataAggregationEnabled ()) {
405+ result = request.GetTileKeys ();
406+ } else {
407+ auto append_tile = [&tiles, &result](const geo::TileKey& key) {
408+ if (tiles.count (key) == 1 ) {
409+ result.emplace_back (key);
380410 return true ;
381411 } else {
382- return false ;
412+ return std::find (result. begin (), result. end (), key) != result. end () ;
383413 }
384414 };
385415
386- for (const auto & tile : tile_keys ) {
416+ for (const auto & tile : request. GetTileKeys () ) {
387417 auto aggregated_tile = tile;
388418
389419 while (aggregated_tile.IsValid () && !append_tile (aggregated_tile)) {
390420 aggregated_tile = aggregated_tile.Parent ();
391421 }
392422
393423 if (!aggregated_tile.IsValid ()) {
394- result[ tile] = " " ; // To generate Not Found error
424+ result. emplace_back ( tile) ; // To generate Not Found error
395425 }
396426 }
397-
398- tiles.swap (result);
399427 }
400-
401- return tiles;
428+ return result;
402429}
403430
404431PrefetchTilesRepository::QuadTreeResponse
0 commit comments