mirror of
https://github.com/boostorg/json.git
synced 2025-05-11 21:53:58 +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
|
int repeat) const override
|
||||||
{
|
{
|
||||||
while(repeat--)
|
while(repeat--)
|
||||||
json::parse(s);
|
{
|
||||||
|
auto sp = json::make_storage<
|
||||||
|
json::block_storage>();
|
||||||
|
json::parse(s, sp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include <boost/json/assign_string.hpp>
|
#include <boost/json/assign_string.hpp>
|
||||||
#include <boost/json/assign_vector.hpp>
|
#include <boost/json/assign_vector.hpp>
|
||||||
#include <boost/json/basic_parser.hpp>
|
#include <boost/json/basic_parser.hpp>
|
||||||
|
#include <boost/json/block_storage.hpp>
|
||||||
#include <boost/json/error.hpp>
|
#include <boost/json/error.hpp>
|
||||||
#include <boost/json/fixed_storage.hpp>
|
#include <boost/json/fixed_storage.hpp>
|
||||||
#include <boost/json/ieee_decimal.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
|
#define BOOST_JSON_FIXED_STORAGE_HPP
|
||||||
|
|
||||||
#include <boost/json/detail/config.hpp>
|
#include <boost/json/detail/config.hpp>
|
||||||
|
#include <boost/json/detail/assert.hpp>
|
||||||
#include <boost/json/storage.hpp>
|
#include <boost/json/storage.hpp>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <memory>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
@ -21,22 +24,32 @@ namespace json {
|
|||||||
*/
|
*/
|
||||||
class fixed_storage : public storage
|
class fixed_storage : public storage
|
||||||
{
|
{
|
||||||
char* const base_;
|
|
||||||
std::size_t const size_;
|
std::size_t const size_;
|
||||||
|
char* const base_;
|
||||||
std::size_t used_ = 0;
|
std::size_t used_ = 0;
|
||||||
std::size_t refs_ = 0;
|
std::size_t refs_ = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~fixed_storage()
|
~fixed_storage()
|
||||||
{
|
{
|
||||||
delete[] base_;
|
std::allocator<
|
||||||
|
char>{}.deallocate(base_, size_);
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit
|
explicit
|
||||||
fixed_storage(
|
fixed_storage(
|
||||||
std::size_t bytes)
|
std::size_t bytes)
|
||||||
: base_(new char[bytes])
|
: size_(
|
||||||
, size_(bytes)
|
[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 n,
|
||||||
std::size_t align) override
|
std::size_t align) override
|
||||||
{
|
{
|
||||||
|
(void)align;
|
||||||
// must be power of 2
|
// must be power of 2
|
||||||
BOOST_JSON_ASSERT(
|
BOOST_JSON_ASSERT(
|
||||||
(align & (align - 1)) == 0);
|
(align & (align - 1)) == 0);
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include <boost/json/parser.hpp>
|
#include <boost/json/parser.hpp>
|
||||||
#include <boost/json/error.hpp>
|
#include <boost/json/error.hpp>
|
||||||
|
#include <boost/json/block_storage.hpp>
|
||||||
#include <boost/json/detail/assert.hpp>
|
#include <boost/json/detail/assert.hpp>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@ -54,6 +55,8 @@ parser::
|
|||||||
|
|
||||||
parser::
|
parser::
|
||||||
parser()
|
parser()
|
||||||
|
: jv_(make_storage<
|
||||||
|
block_storage>())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
#include <boost/json/basic_parser.hpp>
|
#include <boost/json/basic_parser.hpp>
|
||||||
#include <boost/json/storage.hpp>
|
#include <boost/json/storage.hpp>
|
||||||
#include <boost/json/value.hpp>
|
#include <boost/json/value.hpp>
|
||||||
#include <boost/json/storage.hpp>
|
|
||||||
#include <boost/json/detail/string.hpp>
|
#include <boost/json/detail/string.hpp>
|
||||||
#include <new>
|
#include <new>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -34,7 +34,9 @@ add_executable (json-tests
|
|||||||
assign_string.cpp
|
assign_string.cpp
|
||||||
assign_vector.cpp
|
assign_vector.cpp
|
||||||
basic_parser.cpp
|
basic_parser.cpp
|
||||||
|
block_storage.cpp
|
||||||
error.cpp
|
error.cpp
|
||||||
|
fixed_storage.cpp
|
||||||
ieee_decimal.cpp
|
ieee_decimal.cpp
|
||||||
json.cpp
|
json.cpp
|
||||||
kind.cpp
|
kind.cpp
|
||||||
|
@ -30,7 +30,9 @@ local SOURCES =
|
|||||||
assign_string.cpp
|
assign_string.cpp
|
||||||
assign_vector.cpp
|
assign_vector.cpp
|
||||||
basic_parser.cpp
|
basic_parser.cpp
|
||||||
|
block_storage.cpp
|
||||||
error.cpp
|
error.cpp
|
||||||
|
fixed_storage.cpp
|
||||||
ieee_decimal.cpp
|
ieee_decimal.cpp
|
||||||
json.cpp
|
json.cpp
|
||||||
kind.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