mirror of
https://github.com/felt/tippecanoe.git
synced 2026-10-02 16:35:40 +02:00
Subclass json_object so primitives shrink from 168 to 24 bytes
The previous "every member in a struct" layout cost 168 bytes per json_object, even for JSON_NULL / JSON_TRUE / JSON_FALSE nodes that have no payload. Splitting json_object into a small base class plus json_number / json_string / json_array / json_hash subclasses brings each instance down to just the size of its actual contents: json_object (base, TRUE / FALSE / NULL) 24 bytes json_number 48 bytes json_string 48 bytes json_array (empty) 48 bytes json_hash (empty) 72 bytes Other size wins along the way: * Drop enable_shared_from_this<json_object> (its embedded weak_ptr was 16 bytes per node). json_pull now keeps an explicit container_stack and the parser no longer needs to resurrect a shared_ptr from a raw `parent` walk. * Remove the unused `refcon` slot from the string variant. * No virtual destructor: shared_ptr keeps the deleter from the original std::make_shared<json_xxx> call, so destroying a shared_ptr<json_object> still runs the right subclass dtor. The base class exposes type-tagged accessors (o->string(), o->number(), o->array(), o->keys(), o->values(), o->large_signed(), o->large_unsigned()) that assert the type matches and downcast to the appropriate subclass storage. All call sites were swept from the old `o->value.X.Y` field paths to these accessors. A raw-pointer overload of json_hash_get() replaces the few external uses of shared_from_this() that survived in geojson-loop.cpp. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+16
-22
@@ -149,7 +149,7 @@ void out(std::string const &s, int type, json_object_ptr properties) {
|
||||
if (o != nullptr) {
|
||||
found = true;
|
||||
if (o->type == JSON_STRING || o->type == JSON_NUMBER) {
|
||||
extracted = sort_quote(o->value.string.string.c_str());
|
||||
extracted = sort_quote(o->string().c_str());
|
||||
} else {
|
||||
extracted = sort_quote(json_stringify(o).c_str());
|
||||
}
|
||||
@@ -244,9 +244,9 @@ void join_csv(json_object_ptr j) {
|
||||
|
||||
std::string joinkey;
|
||||
if (key->type == JSON_STRING) {
|
||||
joinkey = key->value.string.string;
|
||||
joinkey = key->string();
|
||||
} else if (key->type == JSON_NUMBER) {
|
||||
joinkey = milo::dtoa_milo(key->value.number.number);
|
||||
joinkey = milo::dtoa_milo(key->number());
|
||||
} else {
|
||||
joinkey = json_stringify(key);
|
||||
}
|
||||
@@ -298,8 +298,8 @@ void join_csv(json_object_ptr j) {
|
||||
}
|
||||
|
||||
if (fields.size() > 0 && joinkey == fields[0]) {
|
||||
properties->value.object.keys.reserve(properties->value.object.keys.size() + fields.size());
|
||||
properties->value.object.values.reserve(properties->value.object.values.size() + fields.size());
|
||||
properties->keys().reserve(properties->keys().size() + fields.size());
|
||||
properties->values().reserve(properties->values().size() + fields.size());
|
||||
|
||||
for (size_t i = 1; i < fields.size(); i++) {
|
||||
std::string k = header[i];
|
||||
@@ -317,30 +317,24 @@ void join_csv(json_object_ptr j) {
|
||||
}
|
||||
|
||||
if (attr_type != JSON_NULL) {
|
||||
auto ko = std::make_shared<json_object>();
|
||||
auto vo = std::make_shared<json_object>();
|
||||
|
||||
ko->type = JSON_STRING;
|
||||
ko->parent = properties.get();
|
||||
ko->parser = properties->parser;
|
||||
ko->value.string.string = k;
|
||||
|
||||
vo->type = attr_type;
|
||||
vo->parent = properties.get();
|
||||
vo->parser = properties->parser;
|
||||
auto ko = std::make_shared<json_string>(properties.get(), properties->parser);
|
||||
ko->string_value = k;
|
||||
|
||||
json_object_ptr vo;
|
||||
if (attr_type == JSON_STRING) {
|
||||
vo->value.string.string = v;
|
||||
auto s = std::make_shared<json_string>(properties.get(), properties->parser);
|
||||
s->string_value = v;
|
||||
vo = s;
|
||||
} else if (attr_type == JSON_NUMBER) {
|
||||
vo->value.number.number = atof(v.c_str());
|
||||
vo->value.number.large_unsigned = 0;
|
||||
vo->value.number.large_signed = 0;
|
||||
auto n = std::make_shared<json_number>(properties.get(), properties->parser);
|
||||
n->number_value = atof(v.c_str());
|
||||
vo = n;
|
||||
} else {
|
||||
abort();
|
||||
}
|
||||
|
||||
properties->value.object.keys.push_back(ko);
|
||||
properties->value.object.values.push_back(vo);
|
||||
properties->keys().push_back(ko);
|
||||
properties->values().push_back(vo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user