Improve tiling speed (#195)

* Add a way to run tippecanoe single-threaded for profiling

* Do less work when the tilestats sample values list is already full

* Save a copy when retrieving the attribute key

* Fewer atomic operations

* Move string hashing from mbtiles to text

* Only do approximate attribute deduplication when writing tiles

* Feature dropping tests are sensitive to exact tile size

* All tile creators now create a string pool for the tile

* Features clipped away to nothing should not participate in that tile

* Revert "Only do approximate attribute deduplication when writing tiles"

This reverts commit c42b34b498.

* Also revert the related test changes

* Revert "Revert "Only do approximate attribute deduplication when writing tiles""

This reverts commit 18509876c3.

* Be more specific about the string hash function

* Use fnv1a instead of std::hash for everything

* Reduce the chance of hash collisions

* Stick a hash search on the front of the tree search in addpool

* Eliminate repeated hashing of the same string

* Switch instead of ifs in json parsing

* A few more cases to populate the hash in addpool

* Store the hash in the tree instead of recalculating

* Add explanatory comment for mysterious argument

* Fewer copies in attribute stringification

* Clean up ancient weirdness in JSON attribute stringification

* More serial_val cleanup

* Pass a serial_feature to rewrite instead of many broken-down arguments

* Get rid of the multiple geometries within `partial`

* Revert "Pass a serial_feature to rewrite instead of many broken-down arguments"

This reverts commit 6f4ab9b725.

* Goodbye, struct coalesce

* Revert "Features clipped away to nothing should not participate in that tile"

This reverts commit 124462fbdc.

* Migrating fields from partial to serial_feature

* Name reconciliation between serial_feature and partial

* Replace struct partial with an augmented serial_feature

* Fix some overzealous search-and-replace renaming

* Don't say struct so often

* Remove more of the former partial construction

* Commenting and cleaning up

* Trying again to avoid all these arguments to rewrite

* I swear I did this same thing before and it didn't work.

* More rewrite cleanup

* Exile --detect-shared-borders to its own file

* Add missing headers

* More commenting and cleanup

* More comments

* Sprinkle consts around

* Emplacing and std::moving

* More cleanup

* That shouldn't have worked after a std::move

* Don't need to allocate memory to compare keys

* Reduce use of the global string pool in tiling

* Another avoidable mvt_value construction

* Further reduction to explicit string pool passing

* These reverses are no longer optimizations

* These layernames can all be references

* Don't drag an unused layername string around with every feature

* Heed a compiler warning about potential buffer overflow

* Fix my confusion about which feature's string pool is relevant

* Avoid some unnecessary allocations in attribute accumulation

* Maybe faster serialization?

* Eliminate a comparison

* Do the same here

* Save a couple of allocations when parsing numbers in JSON

* Immediately assign features to layers instead of subdividing later

* Maintain tilestats for tippecanoe:retain_points_multiplier_sequence

* Crunch out more duplicate attribute values when writing out the tile

* Do tilestats for tippecanoe:retain_points_multiplier_first too

* Shell filters need to be real threads, even if nothing else does

* Simplify tippecanoe_minzoom/maxzoom representation

* Update version and changelog
This commit is contained in:
Erica Fischer
2024-02-07 17:50:35 -08:00
committed by GitHub
parent c5c4698161
commit e2a7a409c7
46 changed files with 22817 additions and 22778 deletions
+12 -47
View File
@@ -10,7 +10,6 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <string.h>
#include <fcntl.h>
#include <ctype.h>
#include <errno.h>
@@ -41,7 +40,7 @@
#include "milo/dtoa_milo.h"
#include "errors.hpp"
int serialize_geojson_feature(struct serialization_state *sst, json_object *geometry, json_object *properties, json_object *id, int layer, json_object *tippecanoe, json_object *feature, std::string layername) {
int serialize_geojson_feature(struct serialization_state *sst, json_object *geometry, json_object *properties, json_object *id, int layer, json_object *tippecanoe, json_object *feature, std::string const &layername) {
json_object *geometry_type = json_hash_get(geometry, "type");
if (geometry_type == NULL) {
static int warned = 0;
@@ -81,7 +80,7 @@ int serialize_geojson_feature(struct serialization_state *sst, json_object *geom
int tippecanoe_minzoom = -1;
int tippecanoe_maxzoom = -1;
std::string tippecanoe_layername;
std::string tippecanoe_layername = layername;
if (tippecanoe != NULL) {
json_object *min = json_hash_get(tippecanoe, "minzoom");
@@ -182,36 +181,18 @@ int serialize_geojson_feature(struct serialization_state *sst, json_object *geom
nprop = properties->value.object.length;
}
std::vector<char *> metakey;
metakey.resize(nprop);
std::vector<std::string> keys;
std::vector<serial_val> values;
std::vector<std::string> metaval;
metaval.resize(nprop);
std::vector<int> metatype;
metatype.resize(nprop);
size_t m = 0;
keys.reserve(nprop);
values.reserve(nprop);
for (size_t i = 0; i < nprop; i++) {
if (properties->value.object.keys[i]->type == JSON_STRING) {
std::string s(properties->value.object.keys[i]->value.string.string);
serial_val sv = stringify_value(properties->value.object.values[i], sst->fname, sst->line, feature);
int type = -1;
std::string val;
stringify_value(properties->value.object.values[i], type, val, sst->fname, sst->line, feature);
if (type >= 0) {
metakey[m] = properties->value.object.keys[i]->value.string.string;
metatype[m] = type;
metaval[m] = val;
m++;
} else {
metakey[m] = properties->value.object.keys[i]->value.string.string;
metatype[m] = mvt_null;
metaval[m] = "null";
m++;
}
keys.emplace_back(properties->value.object.keys[i]->value.string.string);
values.push_back(std::move(sv));
}
}
@@ -224,31 +205,15 @@ int serialize_geojson_feature(struct serialization_state *sst, json_object *geom
sf.t = mb_geometry[t];
sf.has_id = has_id;
sf.id = id_value;
sf.has_tippecanoe_minzoom = (tippecanoe_minzoom != -1);
sf.tippecanoe_minzoom = tippecanoe_minzoom;
sf.has_tippecanoe_maxzoom = (tippecanoe_maxzoom != -1);
sf.tippecanoe_maxzoom = tippecanoe_maxzoom;
sf.geometry = dv;
sf.feature_minzoom = 0; // Will be filled in during index merging
sf.seq = *(sst->layer_seq);
sf.full_keys = std::move(keys);
sf.full_values = std::move(values);
if (tippecanoe_layername.size() != 0) {
sf.layername = tippecanoe_layername;
} else {
sf.layername = layername;
}
for (size_t i = 0; i < m; i++) {
sf.full_keys.push_back(metakey[i]);
serial_val sv;
sv.type = metatype[i];
sv.s = metaval[i];
sf.full_values.push_back(sv);
}
return serialize_feature(sst, sf);
return serialize_feature(sst, sf, tippecanoe_layername);
}
void check_crs(json_object *j, const char *reading) {