From f7dc7faf319cb2f4764a263087bcd09159057d94 Mon Sep 17 00:00:00 2001 From: Erica Fischer Date: Thu, 21 Sep 2023 10:59:12 -0700 Subject: [PATCH] Reduce memory use of polygon shard detection (#139) * Crunch down memory required per polygon joint * *Actually* reduce the size of the structure * Update version and changelog --- CHANGELOG.md | 8 ++++++++ mbtiles.cpp | 12 ++++++++---- mbtiles.hpp | 2 ++ tile.cpp | 41 +++++++++++++++++++++++++---------------- version.hpp | 2 +- 5 files changed, 44 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d650a2450..ba4664b64 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +# 2.32.1 + +* Reduce memory usage of --no-simplification-of-shared-nodes for polygons + +# 2.32.0 + +* Extend --no-simplification-of-shared-nodes to also simplify shared polygon borders consistently + # 2.31.0 * Fix tile-join crash when trying to join empty tilesets diff --git a/mbtiles.cpp b/mbtiles.cpp index 925635fc7..3098eecc2 100644 --- a/mbtiles.cpp +++ b/mbtiles.cpp @@ -99,17 +99,21 @@ sqlite3 *mbtiles_open(char *dbname, char **argv, int forcetable) { return outdb; } -void mbtiles_write_tile(sqlite3 *outdb, int z, int tx, int ty, const char *data, int size) { +unsigned long long fnv1a(std::string const &s) { // Store tiles by a hash of their contents (fnv1a 64-bit) // http://www.isthe.com/chongo/tech/comp/fnv/ const unsigned long long fnv_offset_basis = 14695981039346656037u; const unsigned long long fnv_prime = 1099511628211u; unsigned long long h = fnv_offset_basis; - for (int i = 0; i < size; i++) { - h ^= (unsigned char) data[i]; + for (size_t i = 0; i < s.size(); i++) { + h ^= (unsigned char) s[i]; h *= fnv_prime; } - std::string hash = std::to_string(h); + return h; +} + +void mbtiles_write_tile(sqlite3 *outdb, int z, int tx, int ty, const char *data, int size) { + std::string hash = std::to_string(fnv1a(std::string(data, size))); // following https://github.com/mapbox/node-mbtiles/blob/master/lib/mbtiles.js diff --git a/mbtiles.hpp b/mbtiles.hpp index f77a87ca8..58499da96 100644 --- a/mbtiles.hpp +++ b/mbtiles.hpp @@ -85,4 +85,6 @@ std::map merge_layermaps(std::vector &file_keys, std::string const &layername, type_and_string const &val); +unsigned long long fnv1a(std::string const &s); + #endif diff --git a/tile.cpp b/tile.cpp index 7057bcfcb..4584c316a 100644 --- a/tile.cpp +++ b/tile.cpp @@ -1295,31 +1295,39 @@ long long choose_minextent(std::vector &extents, double f) { } struct joint { - draw p1; - draw mid; - draw p2; + long long x : 34; // enough to wrap around the world either way + unsigned long long p1 : 64 - 34; + + long long y : 33; // enough to touch the top and bottom of the world + unsigned long long p2 : 64 - 34; joint(draw one, draw hinge, draw two) { if (one < two) { - p1 = one; - p2 = two; - } else { - p1 = two; - p2 = one; + std::swap(one, two); } - mid = hinge; + long long coord1[2] = {one.x, one.y}; + long long coord2[2] = {two.x, two.y}; + p1 = fnv1a(std::string((const char *) &coord1, sizeof(coord1))); + p2 = fnv1a(std::string((const char *) &coord2, sizeof(coord2))); + + x = hinge.x; + y = hinge.y; } bool operator<(const joint &o) const { - if (mid < o.mid) { + if (y < o.y) { return true; - } else if (mid == o.mid) { - if (p1 < o.p1) { + } else if (y == o.y) { + if (x < o.x) { return true; - } else if (p1 == o.p1) { - if (p2 < o.p2) { + } else if (x == o.x) { + if (p1 < o.p1) { return true; + } else if (p1 == o.p1) { + if (p2 < o.p2) { + return true; + } } } } @@ -2433,10 +2441,11 @@ long long write_tile(decompressor *geoms, std::atomic *geompos_in, ch std::sort(shared_joints.begin(), shared_joints.end()); for (size_t i = 0; i + 1 < shared_joints.size(); i++) { - if (shared_joints[i].mid == shared_joints[i + 1].mid) { + if (shared_joints[i].x == shared_joints[i + 1].x && + shared_joints[i].y == shared_joints[i + 1].y) { if (shared_joints[i].p1 != shared_joints[i + 1].p1 || shared_joints[i].p2 != shared_joints[i + 1].p2) { - shared_nodes.push_back(shared_joints[i].mid); + shared_nodes.push_back(draw(VT_MOVETO, shared_joints[i].x, shared_joints[i].y)); } } } diff --git a/version.hpp b/version.hpp index 86a189f92..9d8e4b143 100644 --- a/version.hpp +++ b/version.hpp @@ -1,6 +1,6 @@ #ifndef VERSION_HPP #define VERSION_HPP -#define VERSION "v2.31.0" +#define VERSION "v2.32.1" #endif