Reduce memory use of GridIndex (#2362)
This commit is contained in:
@@ -45,6 +45,8 @@ public:
|
||||
|
||||
bool isReleased() const { return released; }
|
||||
|
||||
void reserve(std::size_t count) { v.reserve(count); }
|
||||
|
||||
void extend(std::size_t n, const uint16_t val) {
|
||||
assert(!released);
|
||||
v.resize(v.size() + n, val);
|
||||
|
||||
@@ -138,6 +138,16 @@ void PolylineGenerator<PLV, PS>::generate(const GeometryCoordinates& coordinates
|
||||
const std::size_t startVertex = vertices.elements();
|
||||
std::vector<TriangleElement> triangleStore;
|
||||
|
||||
// Pre-allocate for triangles based on measuring benchmark execution
|
||||
constexpr auto approxTrianglesPerSegment = 6;
|
||||
triangleStore.reserve((len - first) * approxTrianglesPerSegment);
|
||||
|
||||
// Vertex count depends on length rather than segment count, and two elements often generates
|
||||
// thousands of vertices, so we allocate some extra memory to skip the next 10 allocations.
|
||||
if (vertices.empty()) {
|
||||
vertices.reserve(1 << 10);
|
||||
}
|
||||
|
||||
for (std::size_t i = first; i < len; ++i) {
|
||||
if (options.type == FeatureType::Polygon && i == len - 1) {
|
||||
// if the line is closed, we treat the last vertex like the first
|
||||
@@ -533,6 +543,9 @@ void PolylineGenerator<PLV, PS>::generate(const GeometryCoordinates& coordinates
|
||||
assert(segment.vertexLength <= std::numeric_limits<uint16_t>::max());
|
||||
const uint16_t index = static_cast<uint16_t>(segment.vertexLength);
|
||||
|
||||
if (indexes.empty()) {
|
||||
indexes.reserve(triangleStore.size() * 3);
|
||||
}
|
||||
for (const auto& triangle : triangleStore) {
|
||||
indexes.emplace_back(index + triangle.a, index + triangle.b, index + triangle.c);
|
||||
}
|
||||
@@ -552,7 +565,7 @@ void PolylineGenerator<PLV, PS>::addCurrentVertex(const GeometryCoordinate& curr
|
||||
std::vector<TriangleElement>& triangleStore,
|
||||
std::optional<PolylineGeneratorDistances> lineDistances) {
|
||||
Point<double> extrude = normal;
|
||||
double scaledDistance = lineDistances ? lineDistances->scaleToMaxLineDistance(distance) : distance;
|
||||
const double scaledDistance = lineDistances ? lineDistances->scaleToMaxLineDistance(distance) : distance;
|
||||
|
||||
if (endLeft) extrude = extrude - (util::perp(normal) * endLeft);
|
||||
vertices.emplace_back(layoutVertex(currentCoordinate,
|
||||
|
||||
@@ -178,7 +178,7 @@ public:
|
||||
|
||||
void setPatternParameters(const std::optional<ImagePosition>&,
|
||||
const std::optional<ImagePosition>&,
|
||||
const CrossfadeParameters&) override {};
|
||||
const CrossfadeParameters&) override {}
|
||||
|
||||
std::tuple<float> interpolationFactor(float) const override { return std::tuple<float>{0.0f}; }
|
||||
|
||||
@@ -272,7 +272,7 @@ public:
|
||||
|
||||
void setPatternParameters(const std::optional<ImagePosition>&,
|
||||
const std::optional<ImagePosition>&,
|
||||
const CrossfadeParameters&) override {};
|
||||
const CrossfadeParameters&) override {}
|
||||
void populateVertexVector(const GeometryTileFeature& feature,
|
||||
std::size_t length,
|
||||
std::size_t index,
|
||||
@@ -391,7 +391,7 @@ public:
|
||||
|
||||
void setPatternParameters(const std::optional<ImagePosition>&,
|
||||
const std::optional<ImagePosition>&,
|
||||
const CrossfadeParameters&) override {};
|
||||
const CrossfadeParameters&) override {}
|
||||
void populateVertexVector(const GeometryTileFeature& feature,
|
||||
std::size_t length,
|
||||
std::size_t index,
|
||||
@@ -415,6 +415,9 @@ public:
|
||||
const AttributeValue value = zoomInterpolatedAttributeValue(attributeValue(range.min),
|
||||
attributeValue(range.max));
|
||||
const auto elements = vertexVector.elements();
|
||||
if (vertexVector.empty()) {
|
||||
vertexVector.reserve(length);
|
||||
}
|
||||
for (std::size_t i = elements; i < length; ++i) {
|
||||
vertexVector.emplace_back(Vertex{value});
|
||||
}
|
||||
|
||||
@@ -13,14 +13,14 @@ TileLayerIndex::TileLayerIndex(OverscaledTileID coord_,
|
||||
: coord(coord_),
|
||||
bucketInstanceId(bucketInstanceId_),
|
||||
bucketLeaderId(std::move(bucketLeaderId_)) {
|
||||
for (SymbolInstance& symbolInstance : symbolInstances) {
|
||||
for (const SymbolInstance& symbolInstance : symbolInstances) {
|
||||
if (symbolInstance.crossTileID == SymbolInstance::invalidCrossTileID()) continue;
|
||||
indexedSymbolInstances[symbolInstance.key].emplace_back(symbolInstance.crossTileID,
|
||||
getScaledCoordinates(symbolInstance, coord));
|
||||
}
|
||||
}
|
||||
|
||||
Point<int64_t> TileLayerIndex::getScaledCoordinates(SymbolInstance& symbolInstance,
|
||||
Point<int64_t> TileLayerIndex::getScaledCoordinates(const SymbolInstance& symbolInstance,
|
||||
const OverscaledTileID& childTileCoord) const {
|
||||
// Round anchor positions to roughly 4 pixel grid
|
||||
const double roundingFactor = 512.0 / util::EXTENT / 2.0;
|
||||
|
||||
@@ -36,7 +36,7 @@ public:
|
||||
uint32_t bucketInstanceId,
|
||||
std::string bucketLeaderId);
|
||||
|
||||
Point<int64_t> getScaledCoordinates(SymbolInstance&, const OverscaledTileID&) const;
|
||||
Point<int64_t> getScaledCoordinates(const SymbolInstance&, const OverscaledTileID&) const;
|
||||
void findMatches(SymbolBucket&, const OverscaledTileID&, std::set<uint32_t>&) const;
|
||||
|
||||
OverscaledTileID coord;
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
#include <mapbox/geometry/box.hpp>
|
||||
#include <mbgl/math/minmax.hpp>
|
||||
|
||||
#include <unordered_set>
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
#include <cassert>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
@@ -103,8 +103,8 @@ private:
|
||||
std::vector<std::pair<T, BBox>> boxElements;
|
||||
std::vector<std::pair<T, BCircle>> circleElements;
|
||||
|
||||
std::vector<std::vector<size_t>> boxCells;
|
||||
std::vector<std::vector<size_t>> circleCells;
|
||||
std::vector<std::vector<uint32_t>> boxCells;
|
||||
std::vector<std::vector<uint32_t>> circleCells;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
@@ -123,7 +123,8 @@ GridIndex<T>::GridIndex(const float width_, const float height_, const uint32_t
|
||||
|
||||
template <class T>
|
||||
void GridIndex<T>::insert(T&& t, const BBox& bbox) {
|
||||
const size_t uid = boxElements.size();
|
||||
assert(boxElements.size() < std::numeric_limits<uint32_t>::max());
|
||||
const auto uid = static_cast<uint32_t>(boxElements.size());
|
||||
|
||||
const auto cx1 = convertToXCellCoord(bbox.min.x);
|
||||
const auto cy1 = convertToYCellCoord(bbox.min.y);
|
||||
@@ -145,7 +146,8 @@ void GridIndex<T>::insert(T&& t, const BBox& bbox) {
|
||||
|
||||
template <class T>
|
||||
void GridIndex<T>::insert(T&& t, const BCircle& bcircle) {
|
||||
const size_t uid = circleElements.size();
|
||||
assert(circleElements.size() < std::numeric_limits<uint32_t>::max());
|
||||
const auto uid = static_cast<uint32_t>(circleElements.size());
|
||||
|
||||
const auto cx1 = convertToXCellCoord(bcircle.center.x - bcircle.radius);
|
||||
const auto cy1 = convertToYCellCoord(bcircle.center.y - bcircle.radius);
|
||||
@@ -231,8 +233,8 @@ typename GridIndex<T>::BBox GridIndex<T>::convertToBox(const BCircle& circle) co
|
||||
|
||||
template <class T>
|
||||
void GridIndex<T>::query(const BBox& queryBBox, std::function<bool(const T&, const BBox&)> resultFn) const {
|
||||
std::unordered_set<size_t> seenBoxes;
|
||||
std::unordered_set<size_t> seenCircles;
|
||||
std::unordered_set<uint32_t> seenBoxes;
|
||||
std::unordered_set<uint32_t> seenCircles;
|
||||
|
||||
if (noIntersection(queryBBox)) {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user