mirror of
https://github.com/boostorg/json.git
synced 2025-05-11 05:33:57 +00:00
Add block_storage default storage
This commit is contained in:
parent
3aae726eb1
commit
c99bec33ec
@ -114,7 +114,11 @@ public:
|
||||
int repeat) const override
|
||||
{
|
||||
while(repeat--)
|
||||
json::parse(s);
|
||||
{
|
||||
auto sp = json::make_storage<
|
||||
json::block_storage>();
|
||||
json::parse(s, sp);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <boost/json/assign_string.hpp>
|
||||
#include <boost/json/assign_vector.hpp>
|
||||
#include <boost/json/basic_parser.hpp>
|
||||
#include <boost/json/block_storage.hpp>
|
||||
#include <boost/json/error.hpp>
|
||||
#include <boost/json/fixed_storage.hpp>
|
||||
#include <boost/json/ieee_decimal.hpp>
|
||||
|
141
include/boost/json/block_storage.hpp
Normal file
141
include/boost/json/block_storage.hpp
Normal file
@ -0,0 +1,141 @@
|
||||
//
|
||||
// Copyright (c) 2018-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Official repository: https://github.com/vinniefalco/json
|
||||
//
|
||||
|
||||
#ifndef BOOST_JSON_BLOCK_STORAGE_HPP
|
||||
#define BOOST_JSON_BLOCK_STORAGE_HPP
|
||||
|
||||
#include <boost/json/detail/config.hpp>
|
||||
#include <boost/json/detail/assert.hpp>
|
||||
#include <boost/json/storage.hpp>
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace boost {
|
||||
namespace json {
|
||||
|
||||
/** A storage which uses a multiple fixed size blocks
|
||||
*/
|
||||
class block_storage : public storage
|
||||
{
|
||||
struct block
|
||||
{
|
||||
std::size_t const size;
|
||||
std::size_t used;
|
||||
block* next;
|
||||
|
||||
char*
|
||||
begin() noexcept
|
||||
{
|
||||
return reinterpret_cast<
|
||||
char*>(this+1);
|
||||
}
|
||||
|
||||
char*
|
||||
end() noexcept
|
||||
{
|
||||
return begin() + size;
|
||||
}
|
||||
};
|
||||
|
||||
std::size_t const block_size_;
|
||||
std::size_t refs_ = 0;
|
||||
block* head_ = nullptr;
|
||||
|
||||
public:
|
||||
~block_storage()
|
||||
{
|
||||
std::allocator<block> a;
|
||||
auto b = head_;
|
||||
while(b)
|
||||
{
|
||||
auto next = b->next;
|
||||
a.deallocate(b,
|
||||
sizeof(*b) + b->size);
|
||||
b = next;
|
||||
}
|
||||
}
|
||||
|
||||
explicit
|
||||
block_storage(
|
||||
std::size_t block_size = 256 * 1024)
|
||||
: block_size_(block_size)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
block&
|
||||
alloc_block(std::size_t size)
|
||||
{
|
||||
std::allocator<block> a;
|
||||
auto const n = (
|
||||
size + sizeof(block) - 1) /
|
||||
sizeof(block);
|
||||
auto& b = *::new(
|
||||
a.allocate(n + 1)) block{
|
||||
n * sizeof(block),
|
||||
0,
|
||||
head_};
|
||||
head_ = &b;
|
||||
return b;
|
||||
}
|
||||
|
||||
void*
|
||||
do_allocate(
|
||||
std::size_t n,
|
||||
std::size_t align) override
|
||||
{
|
||||
(void)align;
|
||||
// must be power of 2
|
||||
BOOST_JSON_ASSERT(
|
||||
(align & (align - 1)) == 0);
|
||||
// cannot exceed max alignment
|
||||
BOOST_JSON_ASSERT(
|
||||
align <= sizeof(std::max_align_t));
|
||||
auto const needed =
|
||||
[&]
|
||||
{
|
||||
if(n < block_size_)
|
||||
return block_size_;
|
||||
return n + sizeof(block);
|
||||
};
|
||||
if(head_)
|
||||
{
|
||||
auto const avail =
|
||||
head_->size - head_->used;
|
||||
if(avail < n)
|
||||
alloc_block(needed());
|
||||
}
|
||||
else
|
||||
{
|
||||
alloc_block(needed());
|
||||
}
|
||||
++refs_;
|
||||
auto p =
|
||||
head_->begin() + head_->used;
|
||||
head_->used += n;
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
do_deallocate(
|
||||
void*,
|
||||
std::size_t,
|
||||
std::size_t) noexcept override
|
||||
{
|
||||
if(--refs_ > 0)
|
||||
return;
|
||||
//clear();
|
||||
}
|
||||
};
|
||||
|
||||
} // json
|
||||
} // boost
|
||||
|
||||
#endif
|
@ -11,7 +11,10 @@
|
||||
#define BOOST_JSON_FIXED_STORAGE_HPP
|
||||
|
||||
#include <boost/json/detail/config.hpp>
|
||||
#include <boost/json/detail/assert.hpp>
|
||||
#include <boost/json/storage.hpp>
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace boost {
|
||||
@ -21,22 +24,32 @@ namespace json {
|
||||
*/
|
||||
class fixed_storage : public storage
|
||||
{
|
||||
char* const base_;
|
||||
std::size_t const size_;
|
||||
char* const base_;
|
||||
std::size_t used_ = 0;
|
||||
std::size_t refs_ = 0;
|
||||
|
||||
public:
|
||||
~fixed_storage()
|
||||
{
|
||||
delete[] base_;
|
||||
std::allocator<
|
||||
char>{}.deallocate(base_, size_);
|
||||
}
|
||||
|
||||
explicit
|
||||
fixed_storage(
|
||||
std::size_t bytes)
|
||||
: base_(new char[bytes])
|
||||
, size_(bytes)
|
||||
: size_(
|
||||
[bytes]
|
||||
{
|
||||
auto const align =
|
||||
sizeof(std::max_align_t) - 1;
|
||||
if(bytes & align)
|
||||
return bytes | align;
|
||||
return bytes;
|
||||
}())
|
||||
, base_(std::allocator<
|
||||
char>{}.allocate(size_))
|
||||
{
|
||||
}
|
||||
|
||||
@ -46,6 +59,7 @@ protected:
|
||||
std::size_t n,
|
||||
std::size_t align) override
|
||||
{
|
||||
(void)align;
|
||||
// must be power of 2
|
||||
BOOST_JSON_ASSERT(
|
||||
(align & (align - 1)) == 0);
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include <boost/json/parser.hpp>
|
||||
#include <boost/json/error.hpp>
|
||||
#include <boost/json/block_storage.hpp>
|
||||
#include <boost/json/detail/assert.hpp>
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
@ -54,6 +55,8 @@ parser::
|
||||
|
||||
parser::
|
||||
parser()
|
||||
: jv_(make_storage<
|
||||
block_storage>())
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include <boost/json/basic_parser.hpp>
|
||||
#include <boost/json/storage.hpp>
|
||||
#include <boost/json/value.hpp>
|
||||
#include <boost/json/storage.hpp>
|
||||
#include <boost/json/detail/string.hpp>
|
||||
#include <new>
|
||||
#include <string>
|
||||
|
@ -34,7 +34,9 @@ add_executable (json-tests
|
||||
assign_string.cpp
|
||||
assign_vector.cpp
|
||||
basic_parser.cpp
|
||||
block_storage.cpp
|
||||
error.cpp
|
||||
fixed_storage.cpp
|
||||
ieee_decimal.cpp
|
||||
json.cpp
|
||||
kind.cpp
|
||||
|
@ -30,7 +30,9 @@ local SOURCES =
|
||||
assign_string.cpp
|
||||
assign_vector.cpp
|
||||
basic_parser.cpp
|
||||
block_storage.cpp
|
||||
error.cpp
|
||||
fixed_storage.cpp
|
||||
ieee_decimal.cpp
|
||||
json.cpp
|
||||
kind.cpp
|
||||
|
31
test/block_storage.cpp
Normal file
31
test/block_storage.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
//
|
||||
// Copyright (c) 2018-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Official repository: https://github.com/vinniefalco/json
|
||||
//
|
||||
|
||||
// Test that header file is self-contained.
|
||||
#include <boost/json/block_storage.hpp>
|
||||
|
||||
#include <boost/beast/_experimental/unit_test/suite.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace json {
|
||||
|
||||
class block_storage_test : public beast::unit_test::suite
|
||||
{
|
||||
public:
|
||||
void run() override
|
||||
{
|
||||
make_storage<block_storage>();
|
||||
pass();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(boost,json,block_storage);
|
||||
|
||||
} // json
|
||||
} // boost
|
31
test/fixed_storage.cpp
Normal file
31
test/fixed_storage.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
//
|
||||
// Copyright (c) 2018-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Official repository: https://github.com/vinniefalco/json
|
||||
//
|
||||
|
||||
// Test that header file is self-contained.
|
||||
#include <boost/json/fixed_storage.hpp>
|
||||
|
||||
#include <boost/beast/_experimental/unit_test/suite.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace json {
|
||||
|
||||
class fixed_storage_test : public beast::unit_test::suite
|
||||
{
|
||||
public:
|
||||
void run() override
|
||||
{
|
||||
make_storage<fixed_storage>(65536);
|
||||
pass();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(boost,json,fixed_storage);
|
||||
|
||||
} // json
|
||||
} // boost
|
Loading…
x
Reference in New Issue
Block a user