Always store serialized("string") by copy (#1915)

This commit is contained in:
Benoit Blanchon
2023-05-02 09:36:40 +02:00
parent 95f5d9d134
commit 806fa907ab
10 changed files with 11 additions and 54 deletions

View File

@ -13,3 +13,4 @@ HEAD
* Remove `JsonDocument::capacity()`
* Store the strings in the heap
* Reference-count shared strings
* Always store `serialized("string")` by copy (#1915)

View File

@ -115,9 +115,9 @@ TEST_CASE("JsonArray::add()") {
REQUIRE(expectedSize == doc.memoryUsage());
}
SECTION("should not duplicate serialized(const char*)") {
SECTION("should duplicate serialized(const char*)") {
array.add(serialized("{}"));
const size_t expectedSize = sizeofArray(1);
const size_t expectedSize = sizeofArray(1) + sizeofString(2);
REQUIRE(expectedSize == doc.memoryUsage());
}

View File

@ -97,17 +97,6 @@ TEST_CASE("JsonDocument::shrinkToFit()") {
<< AllocatorLog::Reallocate(4096, 0));
}
SECTION("linked raw") {
doc.set(serialized("[{},123]"));
doc.shrinkToFit();
REQUIRE(doc.as<std::string>() == "[{},123]");
REQUIRE(spyingAllocator.log() == AllocatorLog()
<< AllocatorLog::Allocate(4096)
<< AllocatorLog::Reallocate(4096, 0));
}
SECTION("owned raw") {
doc.set(serialized(std::string("[{},12]")));

View File

@ -89,15 +89,16 @@ TEST_CASE("JsonVariant::set(JsonVariant)") {
AllocatorLog() << AllocatorLog::Allocate(sizeofString((7))));
}
SECTION("stores Serialized<const char*> by reference") {
var1.set(serialized("hello!!", 8));
SECTION("stores Serialized<const char*> by copy") {
var1.set(serialized("hello!!", 7));
spyingAllocator.clearLog();
var2.set(var1);
REQUIRE(doc1.memoryUsage() == 0);
REQUIRE(doc2.memoryUsage() == 0);
REQUIRE(spyingAllocator.log() == AllocatorLog());
REQUIRE(doc1.memoryUsage() == sizeofString(7));
REQUIRE(doc2.memoryUsage() == sizeofString(7));
REQUIRE(spyingAllocator.log() ==
AllocatorLog() << AllocatorLog::Allocate(sizeofString((7))));
}
SECTION("stores Serialized<char*> by copy") {

View File

@ -205,6 +205,6 @@ TEST_CASE("JsonVariant::set() releases the previous value") {
SECTION("Serialized<const char*>") {
v.set(serialized("[]"));
REQUIRE(doc.memoryUsage() == sizeofObject(1));
REQUIRE(doc.memoryUsage() == sizeofObject(1) + sizeofString(2));
}
}

View File

@ -155,22 +155,11 @@ convertToJson(const T& src, JsonVariant dst) {
variantSetString(data, adaptString(src), pool);
}
template <>
struct Converter<SerializedValue<const char*>>
: private detail::VariantAttorney {
static void toJson(SerializedValue<const char*> src, JsonVariant dst) {
variantSetLinkedRaw(getData(dst), src, getPool(dst));
}
};
// SerializedValue<std::string>
// SerializedValue<String>
// SerializedValue<const __FlashStringHelper*>
template <typename T>
struct Converter<
SerializedValue<T>,
typename detail::enable_if<!detail::is_same<const char*, T>::value>::type>
: private detail::VariantAttorney {
struct Converter<SerializedValue<T>> : private detail::VariantAttorney {
static void toJson(SerializedValue<T> src, JsonVariant dst) {
variantSetOwnedRaw(getData(dst), src, getPool(dst));
}

View File

@ -17,7 +17,6 @@ enum {
OWNED_VALUE_BIT = 0x01,
VALUE_IS_NULL = 0,
VALUE_IS_LINKED_RAW = 0x02,
VALUE_IS_OWNED_RAW = 0x03,
VALUE_IS_LINKED_STRING = 0x04,
VALUE_IS_OWNED_STRING = 0x05,

View File

@ -46,7 +46,6 @@ class VariantData {
content_.asString.size);
case VALUE_IS_OWNED_RAW:
case VALUE_IS_LINKED_RAW:
return visitor.visitRawJson(content_.asString.data,
content_.asString.size);
@ -158,12 +157,6 @@ class VariantData {
content_.asFloat = value;
}
void setLinkedRaw(const char* data, size_t n) {
setType(VALUE_IS_LINKED_RAW);
content_.asString.data = data;
content_.asString.size = n;
}
void setOwnedRaw(const char* data, size_t n) {
setType(VALUE_IS_OWNED_RAW);
content_.asString.data = data;

View File

@ -135,18 +135,6 @@ inline void variantSetOwnedRaw(VariantData* var, SerializedValue<T> value,
var->setNull();
}
inline void variantSetLinkedRaw(VariantData* var,
SerializedValue<const char*> value,
MemoryPool* pool) {
if (!var)
return;
variantRelease(var, pool);
if (value.data())
var->setLinkedRaw(value.data(), value.size());
else
var->setNull();
}
inline size_t variantSize(const VariantData* var) {
return var != 0 ? var->size() : 0;
}

View File

@ -85,9 +85,6 @@ inline JsonString VariantData::asString() const {
inline JsonString VariantData::asRaw() const {
switch (type()) {
case VALUE_IS_LINKED_RAW:
return JsonString(content_.asString.data, content_.asString.size,
JsonString::Linked);
case VALUE_IS_OWNED_RAW:
return JsonString(content_.asString.data, content_.asString.size,
JsonString::Copied);