2012-01-30 19:18:25 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <math.h>
|
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
2019-01-11 19:12:36 +00:00
|
|
|
#include <Common/ThreadPool.h>
|
2017-04-01 09:19:00 +00:00
|
|
|
#include <IO/WriteBuffer.h>
|
2012-01-30 19:18:25 +00:00
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
|
|
|
|
2017-05-28 14:29:40 +00:00
|
|
|
/** Writes data asynchronously using double buffering.
|
2012-01-30 19:18:25 +00:00
|
|
|
*/
|
|
|
|
class AsynchronousWriteBuffer : public WriteBuffer
|
|
|
|
{
|
|
|
|
private:
|
2017-05-28 14:29:40 +00:00
|
|
|
WriteBuffer & out; /// The main buffer, responsible for writing data.
|
|
|
|
std::vector <char> memory; /// A piece of memory for duplicating the buffer.
|
|
|
|
ThreadPool pool; /// For asynchronous data writing.
|
|
|
|
bool started; /// Has an asynchronous data write started?
|
2017-04-01 07:20:54 +00:00
|
|
|
|
2017-05-28 14:29:40 +00:00
|
|
|
/// Swap the main and duplicate buffers.
|
2017-04-01 07:20:54 +00:00
|
|
|
void swapBuffers()
|
|
|
|
{
|
2018-08-25 11:57:00 +00:00
|
|
|
swap(out);
|
2017-04-01 07:20:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void nextImpl() override
|
|
|
|
{
|
|
|
|
if (!offset())
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (started)
|
|
|
|
pool.wait();
|
|
|
|
else
|
|
|
|
started = true;
|
|
|
|
|
|
|
|
swapBuffers();
|
|
|
|
|
2017-05-28 14:29:40 +00:00
|
|
|
/// The data will be written in separate stream.
|
2019-10-17 14:41:27 +00:00
|
|
|
pool.scheduleOrThrowOnError([this] { thread(); });
|
2017-04-01 07:20:54 +00:00
|
|
|
}
|
2012-01-30 19:18:25 +00:00
|
|
|
|
|
|
|
public:
|
2017-04-01 07:20:54 +00:00
|
|
|
AsynchronousWriteBuffer(WriteBuffer & out_) : WriteBuffer(nullptr, 0), out(out_), memory(out.buffer().size()), pool(1), started(false)
|
|
|
|
{
|
2017-05-28 14:29:40 +00:00
|
|
|
/// Data is written to the duplicate buffer.
|
2017-04-01 07:20:54 +00:00
|
|
|
set(memory.data(), memory.size());
|
|
|
|
}
|
|
|
|
|
|
|
|
~AsynchronousWriteBuffer() override
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
if (started)
|
|
|
|
pool.wait();
|
|
|
|
|
|
|
|
swapBuffers();
|
|
|
|
out.next();
|
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
tryLogCurrentException(__PRETTY_FUNCTION__);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-28 14:29:40 +00:00
|
|
|
/// That is executed in a separate thread
|
2017-04-01 07:20:54 +00:00
|
|
|
void thread()
|
|
|
|
{
|
|
|
|
out.next();
|
|
|
|
}
|
2012-01-30 19:18:25 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|