forked from bblanchon/ArduinoJson
VariantPool: store VariantSlot
s instead of char
s
This commit is contained in:
@ -32,15 +32,15 @@ TEST_CASE("JsonDocument assignment") {
|
||||
|
||||
SECTION("Copy assignment reallocates when capacity is smaller") {
|
||||
JsonDocument doc1(4096, &spyingAllocator);
|
||||
deserializeJson(doc1, "{\"hello\":\"world\"}");
|
||||
JsonDocument doc2(8, &spyingAllocator);
|
||||
deserializeJson(doc1, "[{\"hello\":\"world\"}]");
|
||||
JsonDocument doc2(sizeofArray(1), &spyingAllocator);
|
||||
spyingAllocator.clearLog();
|
||||
|
||||
doc2 = doc1;
|
||||
|
||||
REQUIRE(doc2.as<std::string>() == "{\"hello\":\"world\"}");
|
||||
REQUIRE(doc2.as<std::string>() == "[{\"hello\":\"world\"}]");
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::Deallocate(8)
|
||||
AllocatorLog() << AllocatorLog::Deallocate(sizeofArray(1))
|
||||
<< AllocatorLog::Allocate(4096)
|
||||
<< AllocatorLog::Allocate(sizeofString(5)) // hello
|
||||
<< AllocatorLog::Allocate(sizeofString(5)) // world
|
||||
@ -68,7 +68,7 @@ TEST_CASE("JsonDocument assignment") {
|
||||
{
|
||||
JsonDocument doc1(4096, &spyingAllocator);
|
||||
doc1.set(std::string("The size of this string is 32!!"));
|
||||
JsonDocument doc2(8, &spyingAllocator);
|
||||
JsonDocument doc2(128, &spyingAllocator);
|
||||
|
||||
doc2 = std::move(doc1);
|
||||
|
||||
@ -78,8 +78,8 @@ TEST_CASE("JsonDocument assignment") {
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::Allocate(4096)
|
||||
<< AllocatorLog::Allocate(sizeofString(31))
|
||||
<< AllocatorLog::Allocate(8)
|
||||
<< AllocatorLog::Deallocate(8)
|
||||
<< AllocatorLog::Allocate(128)
|
||||
<< AllocatorLog::Deallocate(128)
|
||||
<< AllocatorLog::Deallocate(sizeofString(31))
|
||||
<< AllocatorLog::Deallocate(4096));
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "Allocators.hpp"
|
||||
|
||||
using ArduinoJson::detail::addPadding;
|
||||
using ArduinoJson::detail::sizeofObject;
|
||||
using ArduinoJson::detail::sizeofString;
|
||||
|
||||
TEST_CASE("JsonDocument constructor") {
|
||||
@ -66,8 +67,8 @@ TEST_CASE("JsonDocument constructor") {
|
||||
JsonDocument doc2(obj, &spyingAllocator);
|
||||
|
||||
REQUIRE(doc2.as<std::string>() == "{\"hello\":\"world\"}");
|
||||
REQUIRE(spyingAllocator.log() == AllocatorLog() << AllocatorLog::Allocate(
|
||||
addPadding(doc1.memoryUsage())));
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::Allocate(sizeofObject(1)));
|
||||
}
|
||||
|
||||
SECTION("Construct from JsonArray") {
|
||||
@ -89,9 +90,9 @@ TEST_CASE("JsonDocument constructor") {
|
||||
JsonDocument doc2(doc1.as<JsonVariant>(), &spyingAllocator);
|
||||
|
||||
REQUIRE(doc2.as<std::string>() == "hello");
|
||||
REQUIRE(
|
||||
spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::Allocate(addPadding(doc1.memoryUsage()))
|
||||
<< AllocatorLog::Allocate(sizeofString(5)));
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::Allocate(
|
||||
sizeofString(5)) // TODO: remove
|
||||
<< AllocatorLog::Allocate(sizeofString(5)));
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
// Copyright © 2014-2023, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson/Memory/Alignment.hpp>
|
||||
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
||||
#include <ArduinoJson/Memory/VariantPoolImpl.hpp>
|
||||
#include <catch.hpp>
|
||||
|
@ -5,6 +5,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Collection/CollectionData.hpp>
|
||||
#include <ArduinoJson/Memory/Alignment.hpp>
|
||||
#include <ArduinoJson/Strings/StringAdapters.hpp>
|
||||
#include <ArduinoJson/Variant/VariantCompare.hpp>
|
||||
#include <ArduinoJson/Variant/VariantData.hpp>
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Memory/Alignment.hpp>
|
||||
#include <ArduinoJson/Memory/Allocator.hpp>
|
||||
#include <ArduinoJson/Memory/StringPool.hpp>
|
||||
#include <ArduinoJson/Memory/VariantPool.hpp>
|
||||
@ -22,7 +21,7 @@ class ResourceManager {
|
||||
ResourceManager(size_t capa,
|
||||
Allocator* allocator = DefaultAllocator::instance())
|
||||
: allocator_(allocator), overflowed_(false) {
|
||||
variantPool_.create(addPadding(capa), allocator);
|
||||
variantPool_.create(capa, allocator);
|
||||
}
|
||||
|
||||
~ResourceManager() {
|
||||
@ -48,8 +47,8 @@ class ResourceManager {
|
||||
}
|
||||
|
||||
void reallocPool(size_t requiredSize) {
|
||||
size_t capa = addPadding(requiredSize);
|
||||
if (capa == capacity())
|
||||
size_t capa = VariantPool::bytesToSlots(requiredSize);
|
||||
if (capa == variantPool_.capacity())
|
||||
return;
|
||||
variantPool_.destroy(allocator_);
|
||||
variantPool_.create(requiredSize, allocator_);
|
||||
@ -57,11 +56,11 @@ class ResourceManager {
|
||||
|
||||
// Gets the capacity of the memoryPool in bytes
|
||||
size_t capacity() const {
|
||||
return variantPool_.capacity();
|
||||
return VariantPool::slotsToBytes(variantPool_.capacity());
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
return variantPool_.usage() + stringPool_.size();
|
||||
return VariantPool::slotsToBytes(variantPool_.usage()) + stringPool_.size();
|
||||
}
|
||||
|
||||
bool overflowed() const {
|
||||
|
@ -14,7 +14,7 @@ class VariantSlot;
|
||||
class VariantPool {
|
||||
public:
|
||||
~VariantPool() {
|
||||
ARDUINOJSON_ASSERT(data_ == nullptr);
|
||||
ARDUINOJSON_ASSERT(slots_ == nullptr);
|
||||
}
|
||||
|
||||
VariantPool& operator=(VariantPool&& src) {
|
||||
@ -22,8 +22,8 @@ class VariantPool {
|
||||
src.capacity_ = 0;
|
||||
usage_ = src.usage_;
|
||||
src.usage_ = 0;
|
||||
data_ = src.data_;
|
||||
src.data_ = nullptr;
|
||||
slots_ = src.slots_;
|
||||
src.slots_ = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -36,12 +36,13 @@ class VariantPool {
|
||||
size_t capacity() const;
|
||||
size_t usage() const;
|
||||
|
||||
static size_t sizeForCapacity(size_t);
|
||||
static size_t bytesToSlots(size_t);
|
||||
static size_t slotsToBytes(size_t);
|
||||
|
||||
private:
|
||||
size_t capacity_ = 0;
|
||||
size_t usage_ = 0;
|
||||
char* data_ = nullptr;
|
||||
VariantSlot* slots_ = nullptr;
|
||||
};
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
@ -10,40 +10,40 @@
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
inline void VariantPool::create(size_t cap, Allocator* allocator) {
|
||||
ARDUINOJSON_ASSERT(data_ == nullptr);
|
||||
ARDUINOJSON_ASSERT(slots_ == nullptr);
|
||||
if (!cap)
|
||||
return;
|
||||
data_ = reinterpret_cast<char*>(allocator->allocate(cap));
|
||||
if (data_) {
|
||||
capacity_ = cap;
|
||||
slots_ = reinterpret_cast<VariantSlot*>(allocator->allocate(cap));
|
||||
if (slots_) {
|
||||
capacity_ = bytesToSlots(cap);
|
||||
usage_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline void VariantPool::destroy(Allocator* allocator) {
|
||||
if (data_)
|
||||
allocator->deallocate(data_);
|
||||
data_ = nullptr;
|
||||
if (slots_)
|
||||
allocator->deallocate(slots_);
|
||||
slots_ = nullptr;
|
||||
capacity_ = 0;
|
||||
usage_ = 0;
|
||||
}
|
||||
|
||||
inline ptrdiff_t VariantPool::shrinkToFit(Allocator* allocator) {
|
||||
auto originalPool = data_;
|
||||
data_ = reinterpret_cast<char*>(allocator->reallocate(data_, usage_));
|
||||
if (data_)
|
||||
auto originalPool = slots_;
|
||||
slots_ = reinterpret_cast<VariantSlot*>(
|
||||
allocator->reallocate(slots_, slotsToBytes(usage_)));
|
||||
if (slots_)
|
||||
capacity_ = usage_;
|
||||
return data_ - originalPool;
|
||||
return reinterpret_cast<char*>(slots_) -
|
||||
reinterpret_cast<char*>(originalPool);
|
||||
}
|
||||
|
||||
inline VariantSlot* VariantPool::allocVariant() {
|
||||
if (!data_)
|
||||
if (!slots_)
|
||||
return nullptr;
|
||||
if (usage_ + sizeof(VariantSlot) > capacity_)
|
||||
if (usage_ + 1 > capacity_)
|
||||
return nullptr;
|
||||
auto p = data_ + usage_;
|
||||
usage_ += sizeof(VariantSlot);
|
||||
return new (p) VariantSlot;
|
||||
return new (&slots_[usage_++]) VariantSlot;
|
||||
}
|
||||
|
||||
inline size_t VariantPool::usage() const {
|
||||
@ -58,4 +58,12 @@ inline void VariantPool::clear() {
|
||||
usage_ = 0;
|
||||
}
|
||||
|
||||
inline size_t VariantPool::bytesToSlots(size_t n) {
|
||||
return n / sizeof(VariantSlot);
|
||||
}
|
||||
|
||||
inline size_t VariantPool::slotsToBytes(size_t n) {
|
||||
return n * sizeof(VariantSlot);
|
||||
}
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
Reference in New Issue
Block a user