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