ClickHouse/dbms/include/DB/IO/ReadBufferAIO.h

105 lines
3.8 KiB
C
Raw Normal View History

#pragma once
2015-04-10 17:51:39 +00:00
#include <DB/IO/ReadBufferFromFileBase.h>
#include <DB/IO/ReadBuffer.h>
#include <DB/IO/BufferWithOwnMemory.h>
2015-04-10 17:51:39 +00:00
#include <DB/Core/Defines.h>
#include <statdaemons/AIO.h>
#include <string>
#include <limits>
#include <unistd.h>
#include <fcntl.h>
2015-04-10 17:51:39 +00:00
#include <sys/uio.h>
namespace DB
{
/** Класс для асинхронного чтения данных.
*/
2015-04-10 17:51:39 +00:00
class ReadBufferAIO : public ReadBufferFromFileBase
{
public:
2015-04-10 17:51:39 +00:00
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_);
2015-04-10 17:51:39 +00:00
off_t getPositionInFile() override { return first_unread_pos_in_file - (working_buffer.end() - pos); }
std::string getFileName() const noexcept override { return filename; }
int getFD() const noexcept override { return fd; }
private:
2015-04-10 17:51:39 +00:00
///
bool nextImpl() override;
///
off_t doSeek(off_t off, int whence) override;
/// Синхронно читать данные.
void synchronousRead();
/// Получить данные от асинхронного запроса.
void receive();
/// Игнорировать данные от асинхронного запроса.
void skip();
/// Ждать окончания текущей асинхронной задачи.
2015-04-10 17:51:39 +00:00
bool waitForAIOCompletion();
/// Подготовить запрос.
void prepare();
/// Подготовить к чтению дублирующий буфер содержащий данные от
/// последнего запроса.
void finalize();
private:
/// Буфер для асинхронных операций чтения данных.
BufferWithOwnMemory<ReadBuffer> fill_buffer;
2015-04-10 17:51:39 +00:00
/// Описание асинхронного запроса на чтение.
iocb request;
std::vector<iocb *> request_ptrs{&request};
std::vector<io_event> events{1};
AIOContext aio_context{1};
const std::string filename;
2015-04-10 17:51:39 +00:00
/// Максимальное количество байтов, которое можно прочитать.
size_t max_bytes_read = std::numeric_limits<size_t>::max();
2015-04-10 17:51:39 +00:00
/// Количество запрашиваемых байтов.
size_t requested_byte_count = 0;
2015-04-10 17:51:39 +00:00
/// Количество прочитанных байтов при последнем запросе.
ssize_t bytes_read = 0;
/// Итоговое количество прочитанных байтов.
size_t total_bytes_read = 0;
/// Позиция первого непрочитанного байта в файле.
off_t first_unread_pos_in_file = 0;
/// Начальная позиция выровненного региона диска, из которого читаются данные.
off_t region_aligned_begin = 0;
/// Левое смещение для выравнения региона диска.
size_t region_left_padding = 0;
/// Размер выровненного региона диска.
size_t region_aligned_size = 0;
/// Файловый дескриптор для чтения.
int fd = -1;
2015-04-10 17:51:39 +00:00
/// Буфер, в который пишутся полученные данные.
Position buffer_begin = nullptr;
/// Асинхронная операция чтения ещё не завершилась.
bool is_pending_read = false;
/// Конец файла достигнут.
bool is_eof = false;
2015-04-10 17:51:39 +00:00
/// Был отправлен хоть один запрос на чтение.
bool is_started = false;
2015-04-10 17:51:39 +00:00
/// Является ли операция асинхронной?
bool is_aio = false;
/// Асинхронная операция завершилась неудачно?
bool aio_failed = false;
};
}