mirror of
https://github.com/felt/tippecanoe.git
synced 2026-10-03 00:45:41 +02:00
Migrate jsonpull to unique_ptr ownership
Replaces the shared_ptr-based json_object_ptr with a unique_ptr that has a stateless custom deleter dispatching on json_object::type before calling the right subclass destructor. Eliminates per-node atomic reference-counting and the control-block allocation that shared_ptr required for every node in the tree. API now distinguishes owning and borrowing pointers explicitly: - json_read / json_read_separators / json_hash_get return raw json_object * (borrowed from the parser-owned tree). - json_read_tree / json_disconnect return json_object_ptr (caller takes ownership; back-pointers are cleared so the subtree can outlive the parser). - json_free / json_context / json_stringify take raw pointers. - The parser's container_stack holds raw pointers; jp->root keeps unique_ptr ownership of the most recent top-level value. Internally, take_from_owner moves the unique_ptr out of whichever parent vector / hash entry / parser root owned it, which both json_free and json_disconnect rely on. In the streaming parsers (parse_feature, parse_layers, the geojson-loop callback), we are careful to free `j` only after we have processed a complete Feature: json_read returns each token as the tree is being built up, and freeing an intermediate node would splice it out of the surrounding hash and corrupt the in-progress feature. Benchmark (tl_2022_us_county.json, -z0 --extend-zooms-if-still-dropping, median of 5 runs on macOS arm64): 8.5s, vs 10.6s with shared_ptr and 8.7s on the pre-refactor C baseline. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1215,7 +1215,7 @@ double round_droprate(double r) {
|
||||
return std::round(r * 100000.0) / 100000.0;
|
||||
}
|
||||
|
||||
std::pair<int, metadata> read_input(std::vector<source> &sources, char *fname, int maxzoom, int minzoom, int basezoom, double basezoom_marker_width, sqlite3 *outdb, const char *outdir, std::set<std::string> *exclude, std::set<std::string> *include, int exclude_all, json_object_ptr filter, double droprate, int buffer, const char *tmpdir, double gamma, int read_parallel, int forcetable, const char *attribution, bool uses_gamma, long long *file_bbox, long long *file_bbox1, long long *file_bbox2, const char *prefilter, const char *postfilter, const char *description, bool guess_maxzoom, bool guess_cluster_maxzoom, std::unordered_map<std::string, int> const *attribute_types, const char *pgm, std::unordered_map<std::string, attribute_op> const *attribute_accum, std::map<std::string, std::string> const &attribute_descriptions, std::string const &commandline, int minimum_maxzoom) {
|
||||
std::pair<int, metadata> read_input(std::vector<source> &sources, char *fname, int maxzoom, int minzoom, int basezoom, double basezoom_marker_width, sqlite3 *outdb, const char *outdir, std::set<std::string> *exclude, std::set<std::string> *include, int exclude_all, json_object *filter, double droprate, int buffer, const char *tmpdir, double gamma, int read_parallel, int forcetable, const char *attribution, bool uses_gamma, long long *file_bbox, long long *file_bbox1, long long *file_bbox2, const char *prefilter, const char *postfilter, const char *description, bool guess_maxzoom, bool guess_cluster_maxzoom, std::unordered_map<std::string, int> const *attribute_types, const char *pgm, std::unordered_map<std::string, attribute_op> const *attribute_accum, std::map<std::string, std::string> const &attribute_descriptions, std::string const &commandline, int minimum_maxzoom) {
|
||||
int ret = EXIT_SUCCESS;
|
||||
|
||||
std::vector<struct reader> readers;
|
||||
@@ -2892,7 +2892,7 @@ void set_attribute_value(const char *arg) {
|
||||
exit(EXIT_JSON);
|
||||
}
|
||||
|
||||
serial_val val = stringify_value(e.value, "json", 1, o);
|
||||
serial_val val = stringify_value(e.value.get(), "json", 1, o.get());
|
||||
set_attributes.emplace(e.key->string(), val);
|
||||
i++;
|
||||
}
|
||||
@@ -2934,7 +2934,7 @@ void parse_json_source(const char *arg, struct source &src) {
|
||||
exit(EXIT_JSON);
|
||||
}
|
||||
|
||||
json_object_ptr fname = json_hash_get(o, "file");
|
||||
json_object *fname = json_hash_get(o, "file");
|
||||
if (fname == nullptr || fname->type != JSON_STRING) {
|
||||
fprintf(stderr, "%s: -L%s: requires \"file\": filename\n", *av, arg);
|
||||
exit(EXIT_JSON);
|
||||
@@ -2942,17 +2942,17 @@ void parse_json_source(const char *arg, struct source &src) {
|
||||
|
||||
src.file = fname->string();
|
||||
|
||||
json_object_ptr layer = json_hash_get(o, "layer");
|
||||
json_object *layer = json_hash_get(o, "layer");
|
||||
if (layer != nullptr && layer->type == JSON_STRING) {
|
||||
src.layer = layer->string();
|
||||
}
|
||||
|
||||
json_object_ptr description = json_hash_get(o, "description");
|
||||
json_object *description = json_hash_get(o, "description");
|
||||
if (description != nullptr && description->type == JSON_STRING) {
|
||||
src.description = description->string();
|
||||
}
|
||||
|
||||
json_object_ptr format = json_hash_get(o, "format");
|
||||
json_object *format = json_hash_get(o, "format");
|
||||
if (format != nullptr && format->type == JSON_STRING) {
|
||||
src.format = format->string();
|
||||
}
|
||||
@@ -3846,7 +3846,7 @@ int main(int argc, char **argv) {
|
||||
|
||||
auto input_ret = read_input(sources, name ? name : out_mbtiles ? out_mbtiles
|
||||
: out_dir,
|
||||
maxzoom, minzoom, basezoom, basezoom_marker_width, outdb, out_dir, &exclude, &include, exclude_all, filter, droprate, buffer, tmpdir, gamma, read_parallel, forcetable, attribution, gamma != 0, file_bbox, file_bbox1, file_bbox2, prefilter, postfilter, description, guess_maxzoom, guess_cluster_maxzoom, &attribute_types, argv[0], &attribute_accum, attribute_descriptions, commandline, minimum_maxzoom);
|
||||
maxzoom, minzoom, basezoom, basezoom_marker_width, outdb, out_dir, &exclude, &include, exclude_all, filter.get(), droprate, buffer, tmpdir, gamma, read_parallel, forcetable, attribution, gamma != 0, file_bbox, file_bbox1, file_bbox2, prefilter, postfilter, description, guess_maxzoom, guess_cluster_maxzoom, &attribute_types, argv[0], &attribute_accum, attribute_descriptions, commandline, minimum_maxzoom);
|
||||
|
||||
ret = std::get<0>(input_ret);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user