ClickHouse/dbms/src/IO/ReadBufferAIO.h

110 lines
3.2 KiB
C++
Raw Normal View History

#pragma once
#include <IO/ReadBufferFromFileBase.h>
#include <IO/ReadBuffer.h>
#include <IO/BufferWithOwnMemory.h>
#include <Core/Defines.h>
#include <Common/AIO.h>
#include <Common/CurrentMetrics.h>
#include <string>
#include <limits>
#include <unistd.h>
#include <fcntl.h>
namespace CurrentMetrics
{
extern const Metric OpenFileForRead;
}
namespace DB
{
2017-05-28 14:29:40 +00:00
/** Class for asynchronous data reading.
*/
class ReadBufferAIO : public ReadBufferFromFileBase
{
public:
ReadBufferAIO(const std::string & filename_, size_t buffer_size_ = DBMS_DEFAULT_BUFFER_SIZE, int flags_ = -1,
char * existing_memory_ = nullptr);
~ReadBufferAIO() override;
ReadBufferAIO(const ReadBufferAIO &) = delete;
ReadBufferAIO & operator=(const ReadBufferAIO &) = delete;
void setMaxBytes(size_t max_bytes_read_);
off_t getPositionInFile() override { return first_unread_pos_in_file - (working_buffer.end() - pos); }
std::string getFileName() const override { return filename; }
int getFD() const override { return fd; }
private:
///
bool nextImpl() override;
///
off_t doSeek(off_t off, int whence) override;
2017-05-28 14:29:40 +00:00
/// Synchronously read the data.
void synchronousRead();
2017-05-28 14:29:40 +00:00
/// Get data from an asynchronous request.
void receive();
2017-05-28 14:29:40 +00:00
/// Ignore data from an asynchronous request.
void skip();
2017-05-28 14:29:40 +00:00
/// Wait for the end of the current asynchronous task.
bool waitForAIOCompletion();
2017-05-28 14:29:40 +00:00
/// Prepare the request.
void prepare();
2017-05-28 14:29:40 +00:00
/// Prepare for reading a duplicate buffer containing data from
/// of the last request.
void finalize();
private:
2017-05-28 14:29:40 +00:00
/// Buffer for asynchronous data read operations.
BufferWithOwnMemory<ReadBuffer> fill_buffer;
2017-05-28 14:29:40 +00:00
/// Description of the asynchronous read request.
iocb request{};
std::future<ssize_t> future_bytes_read;
const std::string filename;
2017-05-28 14:29:40 +00:00
/// The maximum number of bytes that can be read.
size_t max_bytes_read = std::numeric_limits<size_t>::max();
2017-05-28 14:29:40 +00:00
/// Number of bytes requested.
size_t requested_byte_count = 0;
2017-05-28 14:29:40 +00:00
/// The number of bytes read at the last request.
ssize_t bytes_read = 0;
2017-05-28 14:29:40 +00:00
/// The total number of bytes read.
size_t total_bytes_read = 0;
2017-05-28 14:29:40 +00:00
/// The position of the first unread byte in the file.
off_t first_unread_pos_in_file = 0;
2017-05-28 14:29:40 +00:00
/// The starting position of the aligned region of the disk from which the data is read.
off_t region_aligned_begin = 0;
2017-05-28 14:29:40 +00:00
/// Left offset to align the region of the disk.
size_t region_left_padding = 0;
2017-05-28 14:29:40 +00:00
/// The size of the aligned region of the disk.
size_t region_aligned_size = 0;
2017-05-28 14:29:40 +00:00
/// The file descriptor for read.
int fd = -1;
2017-05-28 14:29:40 +00:00
/// The buffer to which the received data is written.
Position buffer_begin = nullptr;
2017-05-28 14:29:40 +00:00
/// The asynchronous read operation is not yet completed.
bool is_pending_read = false;
2017-05-28 14:29:40 +00:00
/// The end of the file is reached.
bool is_eof = false;
2017-05-28 14:29:40 +00:00
/// At least one read request was sent.
bool is_started = false;
2017-05-28 14:29:40 +00:00
/// Is the operation asynchronous?
bool is_aio = false;
2017-05-28 14:29:40 +00:00
/// Did the asynchronous operation fail?
bool aio_failed = false;
CurrentMetrics::Increment metric_increment{CurrentMetrics::OpenFileForRead};
};
}