From 7409d17f13791f1a02f76eb58c19f959982c0c4a Mon Sep 17 00:00:00 2001 From: Erica Fischer Date: Thu, 25 Jan 2024 14:19:02 -0800 Subject: [PATCH] Provision for different mvt_values to share a string pool --- evaluator.cpp | 14 +++++++------- mvt.cpp | 16 ++++++++-------- mvt.hpp | 39 +++++++++++++++++++++++++++++++++------ tile-join.cpp | 2 +- tile.cpp | 16 ++++++++-------- write_json.cpp | 2 +- 6 files changed, 58 insertions(+), 31 deletions(-) diff --git a/evaluator.cpp b/evaluator.cpp index 791d2962..7508f46c 100644 --- a/evaluator.cpp +++ b/evaluator.cpp @@ -11,7 +11,7 @@ static std::string mvt_value_to_string(mvt_value const &one, bool &fail) { switch (one.type) { case mvt_string: - return *(one.string_value); + return one.get_string_value(); case mvt_float: return milo::dtoa_milo(one.numeric_value.float_value); case mvt_double: @@ -53,7 +53,7 @@ int compare_fsl(mvt_value const &one, json_object *two, bool &fail) { switch (one.type) { case mvt_string: { char *endptr = NULL; - const char *s = one.string_value->c_str(); + const char *s = one.c_str(); lhs = strtod(s, &endptr); if (endptr == s) { fail = true; // non-numeric-string op number => null @@ -106,7 +106,7 @@ int compare_fsl(mvt_value const &one, json_object *two, bool &fail) { switch (one.type) { case mvt_string: - lhs = one.string_value->size() > 0; + lhs = one.get_string_view().size() > 0; break; case mvt_float: lhs = one.numeric_value.float_value != 0; @@ -152,7 +152,7 @@ int compare(mvt_value const &one, json_object *two, bool &fail) { return false; // string vs non-string } - return strcmp(one.string_value->c_str(), two->value.string.string); + return strcmp(one.c_str(), two->value.string.string); case mvt_double: case mvt_float: @@ -706,13 +706,13 @@ bool evaluate(mvt_feature const &feat, mvt_layer const &layer, json_object *filt if (feat.type == mvt_point) { const static std::string point = "Point"; - v.string_value = point; + v.set_string_value(point); } else if (feat.type == mvt_linestring) { const static std::string linestring = "LineString"; - v.string_value = linestring; + v.set_string_value(linestring); } else if (feat.type == mvt_polygon) { const static std::string polygon = "Polygon"; - v.string_value = polygon; + v.set_string_value(polygon); } return v; } diff --git a/mvt.cpp b/mvt.cpp index 72b59a7c..145b35ec 100644 --- a/mvt.cpp +++ b/mvt.cpp @@ -157,7 +157,7 @@ bool mvt_tile::decode(const std::string &message, bool &was_compressed) { switch (value_reader.tag()) { case 1: /* string */ value.type = mvt_string; - value.string_value = value_reader.get_string(); + value.set_string_value(value_reader.get_string()); break; case 2: /* float */ @@ -332,7 +332,7 @@ std::string mvt_tile::encode() { switch (pbv.type) { case mvt_string: - value_writer.add_string(1, *(pbv.string_value)); + value_writer.add_string(1, pbv.get_string_value()); break; case mvt_float: value_writer.add_float(2, pbv.numeric_value.float_value); @@ -461,7 +461,7 @@ bool mvt_value::operator<(const mvt_value &o) const { if (type == o.type) { switch (type) { case mvt_string: - return *string_value < *(o.string_value); + return get_string_view() < o.get_string_view(); case mvt_float: return numeric_value.float_value < o.numeric_value.float_value; @@ -497,7 +497,7 @@ bool mvt_value::operator==(const mvt_value &o) const { if (type == o.type) { switch (type) { case mvt_string: - return *string_value == *(o.string_value); + return get_string_view() == o.get_string_view(); case mvt_float: return numeric_value.float_value == o.numeric_value.float_value; @@ -553,7 +553,7 @@ static std::string quote(std::string const &s) { std::string mvt_value::toString() const { switch (type) { case mvt_string: - return quote(*string_value); + return quote(get_string_value()); case mvt_int: return std::to_string(numeric_value.int_value); case mvt_double: { @@ -753,7 +753,7 @@ mvt_value stringified_to_mvt_value(int type, const char *s) { break; default: tv.type = mvt_string; - tv.string_value = s; + tv.set_string_value(s); } return tv; @@ -770,7 +770,7 @@ serial_val mvt_value_to_serial_val(mvt_value const &v) { switch (v.type) { case mvt_string: sv.type = mvt_string; - sv.s = *(v.string_value); + sv.s = v.get_string_value(); break; case mvt_float: sv.type = mvt_double; @@ -812,7 +812,7 @@ serial_val mvt_value_to_serial_val(mvt_value const &v) { long long mvt_value_to_long_long(mvt_value const &v) { switch (v.type) { case mvt_string: - return atoll(v.string_value->c_str()); + return atoll(v.c_str()); case mvt_float: return v.numeric_value.float_value; case mvt_double: diff --git a/mvt.hpp b/mvt.hpp index b3611998..3967d6e9 100644 --- a/mvt.hpp +++ b/mvt.hpp @@ -3,10 +3,12 @@ #include #include +#include #include #include #include #include +#include #include "errors.hpp" @@ -75,7 +77,8 @@ enum mvt_value_type { struct mvt_value { mvt_value_type type; - std::optional string_value; + std::shared_ptr s; + union { float float_value; double double_value; @@ -84,8 +87,36 @@ struct mvt_value { long long sint_value; bool bool_value; int null_value; + struct { + size_t off; + size_t len; + } string_value; } numeric_value; + std::string get_string_value() const { + return std::string(*s, numeric_value.string_value.off, numeric_value.string_value.len); + } + + std::string_view get_string_view() const { + return std::string_view(s->c_str() + numeric_value.string_value.off, numeric_value.string_value.len); + } + + const char *c_str() const { + return s->c_str() + numeric_value.string_value.off; + } + + void set_string_value(const std::string &val) { + if (s == nullptr) { + s = std::make_shared(); + } + + type = mvt_string; + numeric_value.string_value.off = s->size(); + numeric_value.string_value.len = val.size(); + s->append(val); + s->push_back('\0'); + } + bool operator<(const mvt_value &o) const; bool operator==(const mvt_value &o) const; std::string toString() const; @@ -99,13 +130,9 @@ struct mvt_value { template <> struct std::hash { std::size_t operator()(const mvt_value &k) const { - using std::hash; - using std::size_t; - using std::string; - switch (k.type) { case mvt_string: - return std::hash()(*(k.string_value)); + return std::hash()(k.get_string_view()); case mvt_float: return std::hash()(k.numeric_value.float_value); diff --git a/tile-join.cpp b/tile-join.cpp index d780734a..f24983c4 100644 --- a/tile-join.cpp +++ b/tile-join.cpp @@ -197,7 +197,7 @@ void append_tile(std::string message, int z, unsigned x, unsigned y, std::map const &metakeys, std::vector mvt_value key = retrieve_string(metakeys[i], stringpool, NULL); mvt_value value = retrieve_string(metavals[i], stringpool, &otype); - layer.tag(feature, *(key.string_value), value); + layer.tag(feature, key.get_string_value(), value); } } @@ -227,9 +227,9 @@ static int metacmp(const std::vector &keys1, const std::vector *(key2.string_value)) { + } else if (key1.get_string_view() > key2.get_string_view()) { return 1; } @@ -259,7 +259,7 @@ static int metacmp(const std::vector &keys1, const std::vector *geompos v.type = mvt_string; if (sf.t == mvt_point) { - v.string_value = "Point"; + v.set_string_value("Point"); } else if (sf.t == mvt_linestring) { - v.string_value = "LineString"; + v.set_string_value("LineString"); } else if (sf.t == mvt_polygon) { - v.string_value = "Polygon"; + v.set_string_value("Polygon"); } attributes.insert(std::pair("$type", v)); diff --git a/write_json.cpp b/write_json.cpp index c3624a4d..02fbec9d 100644 --- a/write_json.cpp +++ b/write_json.cpp @@ -339,7 +339,7 @@ void layer_to_geojson(mvt_layer const &layer, unsigned z, unsigned x, unsigned y switch (val.type) { case mvt_string: state.json_write_string(key); - state.json_write_string(*(val.string_value)); + state.json_write_string(val.get_string_value()); break; case mvt_int: state.json_write_string(key);