mirror of
https://github.com/bblanchon/ArduinoJson.git
synced 2025-07-17 20:42:24 +02:00
Extract VariantPool
from ResourceManager
This commit is contained in:
@ -3,7 +3,7 @@
|
|||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantSlot.hpp>
|
#include <ArduinoJson/Memory/VariantPoolImpl.hpp>
|
||||||
#include <catch.hpp>
|
#include <catch.hpp>
|
||||||
|
|
||||||
#include "Allocators.hpp"
|
#include "Allocators.hpp"
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
||||||
|
#include <ArduinoJson/Memory/VariantPoolImpl.hpp>
|
||||||
#include <ArduinoJson/Strings/StringAdapters.hpp>
|
#include <ArduinoJson/Strings/StringAdapters.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantSlot.hpp>
|
|
||||||
#include <catch.hpp>
|
#include <catch.hpp>
|
||||||
|
|
||||||
using namespace ArduinoJson::detail;
|
using namespace ArduinoJson::detail;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantSlot.hpp>
|
#include <ArduinoJson/Memory/VariantPoolImpl.hpp>
|
||||||
#include <catch.hpp>
|
#include <catch.hpp>
|
||||||
|
|
||||||
using namespace ArduinoJson::detail;
|
using namespace ArduinoJson::detail;
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include "ArduinoJson/Array/JsonArrayImpl.hpp"
|
#include "ArduinoJson/Array/JsonArrayImpl.hpp"
|
||||||
#include "ArduinoJson/Array/Utilities.hpp"
|
#include "ArduinoJson/Array/Utilities.hpp"
|
||||||
#include "ArduinoJson/Collection/CollectionImpl.hpp"
|
#include "ArduinoJson/Collection/CollectionImpl.hpp"
|
||||||
|
#include "ArduinoJson/Memory/VariantPoolImpl.hpp"
|
||||||
#include "ArduinoJson/Object/JsonObjectImpl.hpp"
|
#include "ArduinoJson/Object/JsonObjectImpl.hpp"
|
||||||
#include "ArduinoJson/Object/MemberProxy.hpp"
|
#include "ArduinoJson/Object/MemberProxy.hpp"
|
||||||
#include "ArduinoJson/Variant/ConverterImpl.hpp"
|
#include "ArduinoJson/Variant/ConverterImpl.hpp"
|
||||||
|
@ -7,24 +7,27 @@
|
|||||||
#include <ArduinoJson/Memory/Alignment.hpp>
|
#include <ArduinoJson/Memory/Alignment.hpp>
|
||||||
#include <ArduinoJson/Memory/Allocator.hpp>
|
#include <ArduinoJson/Memory/Allocator.hpp>
|
||||||
#include <ArduinoJson/Memory/StringNode.hpp>
|
#include <ArduinoJson/Memory/StringNode.hpp>
|
||||||
|
#include <ArduinoJson/Memory/VariantPool.hpp>
|
||||||
#include <ArduinoJson/Polyfills/assert.hpp>
|
#include <ArduinoJson/Polyfills/assert.hpp>
|
||||||
|
#include <ArduinoJson/Polyfills/utility.hpp>
|
||||||
#include <ArduinoJson/Strings/StringAdapters.hpp>
|
#include <ArduinoJson/Strings/StringAdapters.hpp>
|
||||||
|
|
||||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||||
|
|
||||||
class VariantSlot;
|
class VariantSlot;
|
||||||
|
class VariantPool;
|
||||||
|
|
||||||
class ResourceManager {
|
class ResourceManager {
|
||||||
public:
|
public:
|
||||||
ResourceManager(size_t capa,
|
ResourceManager(size_t capa,
|
||||||
Allocator* allocator = DefaultAllocator::instance())
|
Allocator* allocator = DefaultAllocator::instance())
|
||||||
: allocator_(allocator), overflowed_(false) {
|
: allocator_(allocator), overflowed_(false) {
|
||||||
allocPool(addPadding(capa));
|
variantPool_.create(addPadding(capa), allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
~ResourceManager() {
|
~ResourceManager() {
|
||||||
deallocAllStrings();
|
deallocAllStrings();
|
||||||
deallocPool();
|
variantPool_.destroy(allocator_);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceManager(const ResourceManager&) = delete;
|
ResourceManager(const ResourceManager&) = delete;
|
||||||
@ -32,14 +35,10 @@ class ResourceManager {
|
|||||||
|
|
||||||
ResourceManager& operator=(ResourceManager&& src) {
|
ResourceManager& operator=(ResourceManager&& src) {
|
||||||
deallocAllStrings();
|
deallocAllStrings();
|
||||||
deallocPool();
|
variantPool_.destroy(allocator_);
|
||||||
allocator_ = src.allocator_;
|
allocator_ = src.allocator_;
|
||||||
pool_ = src.pool_;
|
variantPool_ = detail::move(src.variantPool_);
|
||||||
poolCapacity_ = src.poolCapacity_;
|
|
||||||
poolUsage_ = src.poolUsage_;
|
|
||||||
overflowed_ = src.overflowed_;
|
overflowed_ = src.overflowed_;
|
||||||
src.pool_ = nullptr;
|
|
||||||
src.poolCapacity_ = src.poolUsage_ = 0;
|
|
||||||
strings_ = src.strings_;
|
strings_ = src.strings_;
|
||||||
src.strings_ = nullptr;
|
src.strings_ = nullptr;
|
||||||
return *this;
|
return *this;
|
||||||
@ -53,17 +52,17 @@ class ResourceManager {
|
|||||||
size_t capa = addPadding(requiredSize);
|
size_t capa = addPadding(requiredSize);
|
||||||
if (capa == capacity())
|
if (capa == capacity())
|
||||||
return;
|
return;
|
||||||
allocator_->deallocate(pool_);
|
variantPool_.destroy(allocator_);
|
||||||
allocPool(requiredSize);
|
variantPool_.create(requiredSize, allocator_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets the capacity of the memoryPool in bytes
|
// Gets the capacity of the memoryPool in bytes
|
||||||
size_t capacity() const {
|
size_t capacity() const {
|
||||||
return poolCapacity_;
|
return variantPool_.capacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size() const {
|
size_t size() const {
|
||||||
size_t total = poolUsage_;
|
size_t total = variantPool_.usage();
|
||||||
for (auto node = strings_; node; node = node->next)
|
for (auto node = strings_; node; node = node->next)
|
||||||
total += sizeofString(node->length);
|
total += sizeofString(node->length);
|
||||||
return total;
|
return total;
|
||||||
@ -73,7 +72,12 @@ class ResourceManager {
|
|||||||
return overflowed_;
|
return overflowed_;
|
||||||
}
|
}
|
||||||
|
|
||||||
VariantSlot* allocVariant();
|
VariantSlot* allocVariant() {
|
||||||
|
auto p = variantPool_.allocVariant();
|
||||||
|
if (!p)
|
||||||
|
overflowed_ = true;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
StringNode* saveString(TAdaptedString str) {
|
StringNode* saveString(TAdaptedString str) {
|
||||||
@ -160,7 +164,7 @@ class ResourceManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
poolUsage_ = 0;
|
variantPool_.clear();
|
||||||
overflowed_ = false;
|
overflowed_ = false;
|
||||||
deallocAllStrings();
|
deallocAllStrings();
|
||||||
}
|
}
|
||||||
@ -171,10 +175,7 @@ class ResourceManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ptrdiff_t shrinkToFit() {
|
ptrdiff_t shrinkToFit() {
|
||||||
auto originalPoolAddress = pool_;
|
return variantPool_.shrinkToFit(allocator_);
|
||||||
pool_ = reinterpret_cast<char*>(allocator_->reallocate(pool_, poolUsage_));
|
|
||||||
poolCapacity_ = poolUsage_;
|
|
||||||
return pool_ - originalPoolAddress;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -186,23 +187,10 @@ class ResourceManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void allocPool(size_t capa) {
|
|
||||||
pool_ = capa ? reinterpret_cast<char*>(allocator_->allocate(capa)) : 0;
|
|
||||||
poolUsage_ = 0;
|
|
||||||
poolCapacity_ = pool_ ? capa : 0;
|
|
||||||
ARDUINOJSON_ASSERT(isAligned(pool_));
|
|
||||||
}
|
|
||||||
|
|
||||||
void deallocPool() {
|
|
||||||
if (pool_)
|
|
||||||
allocator_->deallocate(pool_);
|
|
||||||
}
|
|
||||||
|
|
||||||
Allocator* allocator_;
|
Allocator* allocator_;
|
||||||
char* pool_;
|
|
||||||
size_t poolUsage_, poolCapacity_;
|
|
||||||
bool overflowed_;
|
bool overflowed_;
|
||||||
StringNode* strings_ = nullptr;
|
StringNode* strings_ = nullptr;
|
||||||
|
VariantPool variantPool_;
|
||||||
};
|
};
|
||||||
|
|
||||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||||
|
47
src/ArduinoJson/Memory/VariantPool.hpp
Normal file
47
src/ArduinoJson/Memory/VariantPool.hpp
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// ArduinoJson - https://arduinojson.org
|
||||||
|
// Copyright © 2014-2023, Benoit BLANCHON
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
||||||
|
#include <ArduinoJson/Polyfills/assert.hpp>
|
||||||
|
|
||||||
|
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||||
|
|
||||||
|
class VariantSlot;
|
||||||
|
|
||||||
|
class VariantPool {
|
||||||
|
public:
|
||||||
|
~VariantPool() {
|
||||||
|
ARDUINOJSON_ASSERT(data_ == nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
VariantPool& operator=(VariantPool&& src) {
|
||||||
|
capacity_ = src.capacity_;
|
||||||
|
src.capacity_ = 0;
|
||||||
|
usage_ = src.usage_;
|
||||||
|
src.usage_ = 0;
|
||||||
|
data_ = src.data_;
|
||||||
|
src.data_ = nullptr;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void create(size_t cap, Allocator* allocator);
|
||||||
|
void destroy(Allocator* allocator);
|
||||||
|
|
||||||
|
VariantSlot* allocVariant();
|
||||||
|
void clear();
|
||||||
|
ptrdiff_t shrinkToFit(Allocator*);
|
||||||
|
size_t capacity() const;
|
||||||
|
size_t usage() const;
|
||||||
|
|
||||||
|
static size_t sizeForCapacity(size_t);
|
||||||
|
|
||||||
|
private:
|
||||||
|
size_t capacity_ = 0;
|
||||||
|
size_t usage_ = 0;
|
||||||
|
char* data_ = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
61
src/ArduinoJson/Memory/VariantPoolImpl.hpp
Normal file
61
src/ArduinoJson/Memory/VariantPoolImpl.hpp
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
// ArduinoJson - https://arduinojson.org
|
||||||
|
// Copyright © 2014-2023, Benoit BLANCHON
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ArduinoJson/Memory/VariantPool.hpp>
|
||||||
|
#include <ArduinoJson/Variant/VariantSlot.hpp>
|
||||||
|
|
||||||
|
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||||
|
|
||||||
|
inline void VariantPool::create(size_t cap, Allocator* allocator) {
|
||||||
|
ARDUINOJSON_ASSERT(data_ == nullptr);
|
||||||
|
if (!cap)
|
||||||
|
return;
|
||||||
|
data_ = reinterpret_cast<char*>(allocator->allocate(cap));
|
||||||
|
if (data_) {
|
||||||
|
capacity_ = cap;
|
||||||
|
usage_ = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void VariantPool::destroy(Allocator* allocator) {
|
||||||
|
if (data_)
|
||||||
|
allocator->deallocate(data_);
|
||||||
|
data_ = 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_)
|
||||||
|
capacity_ = usage_;
|
||||||
|
return data_ - originalPool;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline VariantSlot* VariantPool::allocVariant() {
|
||||||
|
if (!data_)
|
||||||
|
return nullptr;
|
||||||
|
if (usage_ + sizeof(VariantSlot) > capacity_)
|
||||||
|
return nullptr;
|
||||||
|
auto p = data_ + usage_;
|
||||||
|
usage_ += sizeof(VariantSlot);
|
||||||
|
return new (p) VariantSlot;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t VariantPool::usage() const {
|
||||||
|
return usage_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t VariantPool::capacity() const {
|
||||||
|
return capacity_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void VariantPool::clear() {
|
||||||
|
usage_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
@ -117,14 +117,4 @@ constexpr size_t sizeofObject(size_t n) {
|
|||||||
return n * sizeof(VariantSlot);
|
return n * sizeof(VariantSlot);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline VariantSlot* ResourceManager::allocVariant() {
|
|
||||||
if (poolUsage_ + sizeof(VariantSlot) > poolCapacity_) {
|
|
||||||
overflowed_ = true;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
auto p = pool_ + poolUsage_;
|
|
||||||
poolUsage_ += sizeof(VariantSlot);
|
|
||||||
return new (p) VariantSlot;
|
|
||||||
}
|
|
||||||
|
|
||||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||||
|
Reference in New Issue
Block a user