Commit Graph
26 Commits
Author SHA1 Message Date
Erica FischerandCursor 65beb3f0d7 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>
2026-05-30 20:44:25 -07:00
Erica FischerandCursor 05b1762077 Fix bugs flagged in code review of jsonpull C++ port
- jsontool.cpp `out()`: route JSON_NUMBER (and anything else non-string)
  through `json_stringify` instead of `o->string()`, which now asserts
  on a non-string type and would crash `--extract` on numeric attributes.
- geojson.{hpp,cpp} `json_end_map`: take `json_pull_ptr` by reference so
  the caller's shared_ptr is released, null-guard before touching
  `jp->source`, and clear `jp->source` after delete to avoid a dangling
  pointer.
- jsonpull/jsonpull.cpp: low-surrogate range check was comparing the
  outer-loop byte `c` instead of the parsed code unit `ch`, breaking
  surrogate-pair decoding for some \\uXXXX escapes. Pre-existing bug
  preserved across the port.
- tile-join.cpp `handle_vector_layers`: require the field value to have
  type JSON_STRING (and the key to be non-null) before calling
  `string()`; the previous truthy `type` check would assert on a
  non-string value.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-30 17:49:28 -07:00
Erica FischerandCursor 3da03c6075 Convert jsonpull to C++ with shared_ptr and std::vector/std::string
Replace the manual malloc/realloc/free memory management in jsonpull
with std::shared_ptr ownership. Each json_object now owns its children
through std::vector<json_object_ptr>; raw back-pointers to parent and
parser remain valid by structural invariant and are cleared on
json_disconnect so detached subtrees can outlive their parser.
Strings become std::string, child arrays become std::vector, and the
old union becomes a struct so non-trivial members can coexist while
preserving the existing o->value.xxx access paths.

The old jsonpull.c is replaced by jsonpull.cpp, json_stringify now
returns std::string, and all callers across tippecanoe, tile-join,
tippecanoe-decode, tippecanoe-json-tool, tippecanoe-overzoom and the
unit tests are updated to use json_object_ptr / json_pull_ptr.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-30 17:48:32 -07:00
Eric Fischer 069807caf4 Use a proper constructor, discover two unused fields 2017-11-10 13:06:47 -08:00
Eric Fischer ba62ab8596 More structure initializers 2017-11-07 15:20:17 -08:00
Eric Fischer e7ee83f27b Move attribute type coercion out of parsing and into serialization 2017-08-24 17:27:30 -07:00
Eric Fischer f4818ffb07 Move attribute include/exclude logic into serialization 2017-08-24 17:10:15 -07:00
Eric Fischer 34b1b215f4 Move tilestats management out of parsing and into serialization 2017-08-24 16:30:01 -07:00
Eric Fischer ed8fbd0236 Split more serialization details out from being parsing parameters 2017-08-24 15:57:33 -07:00
Eric Fischer 6caf20b9c8 Put the pieces back together 2017-08-23 11:43:48 -07:00
Eric Fischer 635429cd87 Fix dangling pointer. Defer tilestats generation until tiling if filtering. 2017-08-08 13:38:48 -07:00
Eric Fischer 65c095cc2b Clean up #includes and add fields for counting attributes 2017-07-14 16:56:23 -07:00
Eric Fischer c7d146ea48 Don't do work for guessing maxzoom unless needed. Add a better test. 2017-05-30 16:58:56 -07:00
Eric Fischer 331707f88a Better maxzoom guessing by considering resolution within features 2017-05-30 13:28:25 -07:00
Eric Fischer 178b5d0054 Add -T option to coerce the types of feature attributes 2017-04-17 15:20:03 -07:00
Eric Fischer 32aa653082 Don't spend geometry space on index or extent unless it is needed 2016-11-11 17:37:46 -08:00
Eric Fischer d4e1ee0627 Replace malloc/free with new/delete to fix parallel-reading crash 2016-08-30 14:02:51 -07:00
Eric Fischer 31d2a3738a Get rid of the old file_keys 2016-08-30 13:46:37 -07:00
Eric Fischer 7f49ce5caa Merge per-thread layer names and file keys 2016-08-29 16:38:57 -07:00
Eric Fischer c26fa23564 Per-thread layermap will contain the file keys, not just a layer ID 2016-08-29 14:59:28 -07:00
Eric Fischer f7e64dca5f Work in progress on being able to specify per-feature layer names 2016-08-23 15:33:53 -07:00
Eric Fischer 3655a54d22 Add the ability to inline metadata with geometry 2016-05-10 16:46:45 -07:00
Eric Fischer adc70341ad Use std::set to track the layer-wide feature attribute types.
Track them during parsing, not tiling.  Remove the old string pool code.
2016-04-28 14:59:58 -07:00
Eric Fischer 87b90a5033 Use std::set to track included and excluded feature properties 2016-04-28 12:57:03 -07:00
Eric Fischer c4274303ea Fix indentation 2016-04-27 15:10:26 -07:00
Eric Fischer 3662f1a66b Split main program functions apart from GeoJSON parsing 2016-04-27 14:59:20 -07:00