2017-04-01 09:19:00 +00:00
|
|
|
#include <Common/Exception.h>
|
2021-05-26 20:37:44 +00:00
|
|
|
#include <Common/Throttler.h>
|
2017-04-01 09:19:00 +00:00
|
|
|
#include <IO/ReadBuffer.h>
|
|
|
|
#include <IO/WriteBuffer.h>
|
|
|
|
#include <IO/copyData.h>
|
2016-06-07 08:23:15 +00:00
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
2020-02-25 18:10:48 +00:00
|
|
|
namespace ErrorCodes
|
|
|
|
{
|
|
|
|
extern const int ATTEMPT_TO_READ_AFTER_EOF;
|
|
|
|
}
|
2016-06-07 08:23:15 +00:00
|
|
|
|
|
|
|
namespace
|
|
|
|
{
|
|
|
|
|
2021-05-26 20:37:44 +00:00
|
|
|
void copyDataImpl(ReadBuffer & from, WriteBuffer & to, bool check_bytes, size_t bytes, const std::atomic<int> * is_cancelled, ThrottlerPtr throttler)
|
2016-06-07 08:23:15 +00:00
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
/// If read to the end of the buffer, eof() either fills the buffer with new data and moves the cursor to the beginning, or returns false.
|
|
|
|
while (bytes > 0 && !from.eof())
|
|
|
|
{
|
|
|
|
if (is_cancelled && *is_cancelled)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/// buffer() - a piece of data available for reading; position() - the cursor of the place to which you have already read.
|
|
|
|
size_t count = std::min(bytes, static_cast<size_t>(from.buffer().end() - from.position()));
|
|
|
|
to.write(from.position(), count);
|
|
|
|
from.position() += count;
|
|
|
|
bytes -= count;
|
2021-05-26 20:37:44 +00:00
|
|
|
|
|
|
|
if (throttler)
|
|
|
|
throttler->add(count);
|
2017-04-01 07:20:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (check_bytes && bytes > 0)
|
|
|
|
throw Exception("Attempt to read after EOF.", ErrorCodes::ATTEMPT_TO_READ_AFTER_EOF);
|
2016-06-07 08:23:15 +00:00
|
|
|
}
|
|
|
|
|
2021-05-26 20:37:44 +00:00
|
|
|
void copyDataImpl(ReadBuffer & from, WriteBuffer & to, bool check_bytes, size_t bytes, std::function<void()> cancellation_hook, ThrottlerPtr throttler)
|
2016-06-07 08:23:15 +00:00
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
/// If read to the end of the buffer, eof() either fills the buffer with new data and moves the cursor to the beginning, or returns false.
|
|
|
|
while (bytes > 0 && !from.eof())
|
|
|
|
{
|
|
|
|
if (cancellation_hook)
|
|
|
|
cancellation_hook();
|
|
|
|
|
|
|
|
/// buffer() - a piece of data available for reading; position() - the cursor of the place to which you have already read.
|
|
|
|
size_t count = std::min(bytes, static_cast<size_t>(from.buffer().end() - from.position()));
|
|
|
|
to.write(from.position(), count);
|
|
|
|
from.position() += count;
|
|
|
|
bytes -= count;
|
2021-05-26 20:37:44 +00:00
|
|
|
|
|
|
|
if (throttler)
|
|
|
|
throttler->add(count);
|
2017-04-01 07:20:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (check_bytes && bytes > 0)
|
|
|
|
throw Exception("Attempt to read after EOF.", ErrorCodes::ATTEMPT_TO_READ_AFTER_EOF);
|
2016-06-07 08:23:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void copyData(ReadBuffer & from, WriteBuffer & to)
|
|
|
|
{
|
2021-05-26 20:37:44 +00:00
|
|
|
copyDataImpl(from, to, false, std::numeric_limits<size_t>::max(), nullptr, nullptr);
|
2016-06-07 08:23:15 +00:00
|
|
|
}
|
|
|
|
|
2018-05-25 11:45:19 +00:00
|
|
|
void copyData(ReadBuffer & from, WriteBuffer & to, const std::atomic<int> & is_cancelled)
|
2016-06-07 08:23:15 +00:00
|
|
|
{
|
2021-05-26 20:37:44 +00:00
|
|
|
copyDataImpl(from, to, false, std::numeric_limits<size_t>::max(), &is_cancelled, nullptr);
|
2016-06-07 08:23:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void copyData(ReadBuffer & from, WriteBuffer & to, std::function<void()> cancellation_hook)
|
|
|
|
{
|
2021-05-26 20:37:44 +00:00
|
|
|
copyDataImpl(from, to, false, std::numeric_limits<size_t>::max(), cancellation_hook, nullptr);
|
2016-06-07 08:23:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void copyData(ReadBuffer & from, WriteBuffer & to, size_t bytes)
|
|
|
|
{
|
2021-05-26 20:37:44 +00:00
|
|
|
copyDataImpl(from, to, true, bytes, nullptr, nullptr);
|
2016-06-07 08:23:15 +00:00
|
|
|
}
|
|
|
|
|
2018-05-25 11:45:19 +00:00
|
|
|
void copyData(ReadBuffer & from, WriteBuffer & to, size_t bytes, const std::atomic<int> & is_cancelled)
|
2016-06-07 08:23:15 +00:00
|
|
|
{
|
2021-05-26 20:37:44 +00:00
|
|
|
copyDataImpl(from, to, true, bytes, &is_cancelled, nullptr);
|
2016-06-07 08:23:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void copyData(ReadBuffer & from, WriteBuffer & to, size_t bytes, std::function<void()> cancellation_hook)
|
|
|
|
{
|
2021-05-26 20:37:44 +00:00
|
|
|
copyDataImpl(from, to, true, bytes, cancellation_hook, nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void copyDataWithThrottler(ReadBuffer & from, WriteBuffer & to, const std::atomic<int> & is_cancelled, ThrottlerPtr throttler)
|
|
|
|
{
|
|
|
|
copyDataImpl(from, to, true, std::numeric_limits<size_t>::max(), &is_cancelled, throttler);
|
|
|
|
}
|
|
|
|
|
|
|
|
void copyDataWithThrottler(ReadBuffer & from, WriteBuffer & to, size_t bytes, const std::atomic<int> & is_cancelled, ThrottlerPtr throttler)
|
|
|
|
{
|
|
|
|
copyDataImpl(from, to, true, bytes, &is_cancelled, throttler);
|
2016-06-07 08:23:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|