Skip to content

Commit 7f0fd65

Browse files
Decrease number of memory reallocations
Adds dedicated filtering for cases when only tile keys are required by the caller. Relates-To: MINOR Signed-off-by: Rustam Gamidov <ext-rustam.gamidov@here.com>
1 parent 91d6934 commit 7f0fd65

File tree

5 files changed

+140
-77
lines changed

5 files changed

+140
-77
lines changed

olp-cpp-sdk-dataservice-read/src/QueryMetadataJob.h

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2020 HERE Europe B.V.
2+
* Copyright (C) 2020-2024 HERE Europe B.V.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -42,7 +42,7 @@ using QueryItemsFunc =
4242
std::function<QueryResponseType(QueryType, client::CancellationContext)>;
4343

4444
template <typename QueryResponseType>
45-
using FilterItemsFunc = std::function<QueryResponseType(QueryResponseType)>;
45+
using FilterItemsFunc = std::function<void(QueryResponseType&)>;
4646

4747
using VectorOfTokens = std::vector<olp::client::CancellationToken>;
4848

@@ -99,9 +99,13 @@ class QueryMetadataJob {
9999
accumulated_statistics_ += GetNetworkStatistics(response);
100100

101101
if (response.IsSuccessful()) {
102-
auto items = response.MoveResult();
103-
std::move(items.begin(), items.end(),
104-
std::inserter(query_result_, query_result_.begin()));
102+
if (query_result_.empty()) {
103+
query_result_ = response.MoveResult();
104+
} else {
105+
auto items = response.MoveResult();
106+
std::move(items.begin(), items.end(),
107+
std::inserter(query_result_, query_result_.begin()));
108+
}
105109
} else {
106110
const auto& error = response.GetError();
107111
if (error.GetErrorCode() == client::ErrorCode::Cancelled) {
@@ -125,7 +129,7 @@ class QueryMetadataJob {
125129
}
126130

127131
if (filter_) {
128-
query_result_ = filter_(std::move(query_result_));
132+
filter_(query_result_);
129133
}
130134

131135
if (query_result_.empty()) {

olp-cpp-sdk-dataservice-read/src/VersionedLayerClientImpl.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -499,11 +499,12 @@ client::CancellationToken VersionedLayerClientImpl::PrefetchTiles(
499499

500500
const bool aggregation_enabled = request.GetDataAggregationEnabled();
501501

502-
auto filter = [=](repository::SubQuadsResult tiles) mutable {
502+
auto filter = [=](repository::SubQuadsResult& tiles) {
503503
if (request_only_input_tiles) {
504-
return repository.FilterTilesByList(request, std::move(tiles));
504+
repository.FilterTilesByList(request, tiles);
505+
} else {
506+
repository.FilterTilesByLevel(request, tiles);
505507
}
506-
return repository.FilterTilesByLevel(request, std::move(tiles));
507508
};
508509

509510
auto query = [=](geo::TileKey root,
@@ -512,8 +513,13 @@ client::CancellationToken VersionedLayerClientImpl::PrefetchTiles(
512513
root, kQuadTreeDepth, version, inner_context);
513514

514515
if (response.IsSuccessful() && aggregation_enabled) {
516+
const auto& tiles = response.GetResult();
515517
auto network_stats = repository.LoadAggregatedSubQuads(
516-
root, filter(response.GetResult()), version, inner_context);
518+
root,
519+
request_only_input_tiles
520+
? repository.FilterTileKeysByList(request, tiles)
521+
: repository.FilterTileKeysByLevel(request, tiles),
522+
version, inner_context);
517523

518524
// append network statistics
519525
network_stats += GetNetworkStatistics(response);

olp-cpp-sdk-dataservice-read/src/VolatileLayerClientImpl.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2019-2021 HERE Europe B.V.
2+
* Copyright (C) 2019-2024 HERE Europe B.V.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -226,11 +226,11 @@ client::CancellationToken VolatileLayerClientImpl::PrefetchTiles(
226226
inner_context);
227227
};
228228

229-
auto filter = [=](repository::SubQuadsResult tiles) mutable {
229+
auto filter = [=](repository::SubQuadsResult& tiles) {
230230
if (request_only_input_tiles) {
231-
return repository.FilterTilesByList(request, std::move(tiles));
231+
repository.FilterTilesByList(request, tiles);
232232
} else {
233-
return repository.FilterTilesByLevel(request, std::move(tiles));
233+
repository.FilterTilesByLevel(request, tiles);
234234
}
235235
};
236236

olp-cpp-sdk-dataservice-read/src/repositories/PrefetchTilesRepository.cpp

Lines changed: 81 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,14 @@ constexpr std::uint32_t kMaxQuadTreeIndexDepth = 4u;
4949
SubQuadsResult 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

175178
client::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

404431
PrefetchTilesRepository::QuadTreeResponse

olp-cpp-sdk-dataservice-read/src/repositories/PrefetchTilesRepository.h

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2019-2021 HERE Europe B.V.
2+
* Copyright (C) 2019-2024 HERE Europe B.V.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
2121

2222
#include <map>
2323
#include <string>
24+
#include <vector>
2425

2526
#include <olp/core/client/ApiError.h>
2627
#include <olp/core/client/ApiLookupClient.h>
@@ -71,6 +72,18 @@ class PrefetchTilesRepository {
7172
RootTilesForRequest GetSlicedTiles(const std::vector<geo::TileKey>& tile_keys,
7273
std::uint32_t min, std::uint32_t max);
7374

75+
/**
76+
* @brief Filters the input tiles according to the request.
77+
*
78+
* Removes tiles that do not belong to the minimum and maximum levels.
79+
* Removes tiles that are not a child or a parent of the requested tiles.
80+
*
81+
* @param request Your request.
82+
* @param tiles The input tiles.
83+
*/
84+
void FilterTilesByLevel(const PrefetchTilesRequest& request,
85+
SubQuadsResult& tiles) const;
86+
7487
/**
7588
* @brief Filters the input tiles according to the request.
7689
*
@@ -80,10 +93,10 @@ class PrefetchTilesRepository {
8093
* @param request Your request.
8194
* @param tiles The input tiles.
8295
*
83-
* @returns The modified tiles.
96+
* @returns Tile keys matching the request.
8497
*/
85-
SubQuadsResult FilterTilesByLevel(const PrefetchTilesRequest& request,
86-
SubQuadsResult tiles);
98+
std::vector<geo::TileKey> FilterTileKeysByLevel(
99+
const PrefetchTilesRequest& request, const SubQuadsResult& tiles) const;
87100

88101
/**
89102
* @brief Filters the input tiles according to the request.
@@ -94,15 +107,28 @@ class PrefetchTilesRepository {
94107
*
95108
* @param request Your request.
96109
* @param tiles The input tiles.
110+
*/
111+
void FilterTilesByList(const PrefetchTilesRequest& request,
112+
SubQuadsResult& tiles) const;
113+
114+
/**
115+
* @brief Filters the input tiles according to the request.
116+
*
117+
* Removes tile keys that are not requested.
118+
* Adds tile keys that are missing (to notify you that they are not found).
119+
* If aggregated tiles were requested, scans for parents.
97120
*
98-
* @returns The modified tiles.
121+
* @param request Your request.
122+
* @param tiles The input tiles.
123+
*
124+
* @returns Tile keys matching the request.
99125
*/
100-
SubQuadsResult FilterTilesByList(const PrefetchTilesRequest& request,
101-
SubQuadsResult tiles);
126+
std::vector<geo::TileKey> FilterTileKeysByList(
127+
const PrefetchTilesRequest& request, const SubQuadsResult& tiles) const;
102128

103129
client::NetworkStatistics LoadAggregatedSubQuads(
104-
geo::TileKey tile, const SubQuadsResult& tiles, std::int64_t version,
105-
client::CancellationContext context);
130+
geo::TileKey tile, const std::vector<geo::TileKey>& tiles,
131+
std::int64_t version, client::CancellationContext context);
106132

107133
SubQuadsResponse GetVersionedSubQuads(geo::TileKey tile, int32_t depth,
108134
std::int64_t version,

0 commit comments

Comments
 (0)