Allow byte_stream->byte_slice conversion to shrink unused buffer space
This commit is contained in:
parent
83f1d863bd
commit
249eae5f4a
|
@ -112,7 +112,7 @@ namespace epee
|
||||||
explicit byte_slice(std::string&& buffer);
|
explicit byte_slice(std::string&& buffer);
|
||||||
|
|
||||||
//! Convert `stream` into a slice with zero allocations.
|
//! Convert `stream` into a slice with zero allocations.
|
||||||
explicit byte_slice(byte_stream&& stream) noexcept;
|
explicit byte_slice(byte_stream&& stream, bool shrink = true);
|
||||||
|
|
||||||
byte_slice(byte_slice&& source) noexcept;
|
byte_slice(byte_slice&& source) noexcept;
|
||||||
~byte_slice() noexcept = default;
|
~byte_slice() noexcept = default;
|
||||||
|
|
|
@ -36,6 +36,11 @@
|
||||||
#include "byte_slice.h"
|
#include "byte_slice.h"
|
||||||
#include "byte_stream.h"
|
#include "byte_stream.h"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
const std::size_t page_size = 4096;
|
||||||
|
}
|
||||||
|
|
||||||
namespace epee
|
namespace epee
|
||||||
{
|
{
|
||||||
struct byte_slice_data
|
struct byte_slice_data
|
||||||
|
@ -173,16 +178,27 @@ namespace epee
|
||||||
: byte_slice(adapt_buffer{}, std::move(buffer))
|
: byte_slice(adapt_buffer{}, std::move(buffer))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
byte_slice::byte_slice(byte_stream&& stream) noexcept
|
byte_slice::byte_slice(byte_stream&& stream, const bool shrink)
|
||||||
: storage_(nullptr), portion_(stream.data(), stream.size())
|
: storage_(nullptr), portion_(stream.data(), stream.size())
|
||||||
{
|
{
|
||||||
if (stream.size())
|
if (portion_.size())
|
||||||
{
|
{
|
||||||
std::uint8_t* const data = stream.take_buffer().release() - sizeof(raw_byte_slice);
|
byte_buffer buf;
|
||||||
|
if (shrink && page_size <= stream.available())
|
||||||
|
{
|
||||||
|
buf = byte_buffer_resize(stream.take_buffer(), portion_.size());
|
||||||
|
if (!buf)
|
||||||
|
throw std::bad_alloc{};
|
||||||
|
portion_ = {buf.get(), portion_.size()};
|
||||||
|
}
|
||||||
|
else // no need to shrink buffer
|
||||||
|
buf = stream.take_buffer();
|
||||||
|
|
||||||
|
std::uint8_t* const data = buf.release() - sizeof(raw_byte_slice);
|
||||||
new (data) raw_byte_slice{};
|
new (data) raw_byte_slice{};
|
||||||
storage_.reset(reinterpret_cast<raw_byte_slice*>(data));
|
storage_.reset(reinterpret_cast<raw_byte_slice*>(data));
|
||||||
}
|
}
|
||||||
else
|
else // empty stream
|
||||||
portion_ = nullptr;
|
portion_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1090,11 +1090,13 @@ TEST(ByteStream, ToByteSlice)
|
||||||
|
|
||||||
epee::byte_stream stream;
|
epee::byte_stream stream;
|
||||||
|
|
||||||
|
stream.reserve(128*1024);
|
||||||
stream.write(source);
|
stream.write(source);
|
||||||
EXPECT_EQ(sizeof(source), stream.size());
|
EXPECT_EQ(sizeof(source), stream.size());
|
||||||
|
EXPECT_EQ(128*1024, stream.capacity());
|
||||||
EXPECT_TRUE(equal(source, byte_span{stream.data(), stream.size()}));
|
EXPECT_TRUE(equal(source, byte_span{stream.data(), stream.size()}));
|
||||||
|
|
||||||
const epee::byte_slice slice{std::move(stream)};
|
const epee::byte_slice slice{std::move(stream), true};
|
||||||
EXPECT_EQ(0u, stream.size());
|
EXPECT_EQ(0u, stream.size());
|
||||||
EXPECT_EQ(0u, stream.available());
|
EXPECT_EQ(0u, stream.available());
|
||||||
EXPECT_EQ(0u, stream.capacity());
|
EXPECT_EQ(0u, stream.capacity());
|
||||||
|
|
Loading…
Reference in New Issue