ClickHouse/dbms/src/IO/AsynchronousWriteBuffer.h

79 lines
1.7 KiB
C++
Raw Normal View History

#pragma once
#include <math.h>
#include <vector>
#include <common/ThreadPool.h>
#include <IO/WriteBuffer.h>
namespace DB
{
2017-05-28 14:29:40 +00:00
/** Writes data asynchronously using double buffering.
*/
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-05-28 14:29:40 +00:00
/// Swap the main and duplicate buffers.
void swapBuffers()
{
buffer().swap(out.buffer());
std::swap(position(), out.position());
}
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.
pool.schedule([this] { thread(); });
}
public:
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.
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
void thread()
{
out.next();
}
};
}