ClickHouse/src/IO/SynchronousReader.h

67 lines
1.6 KiB
C++
Raw Normal View History

2021-07-26 00:34:36 +00:00
#pragma once
#include <IO/AsynchronousReader.h>
#include <Common/assert_cast.h>
#include <Common/Exception.h>
#include <common/errnoToString.h>
#include <unordered_map>
#include <mutex>
#include <unistd.h>
#include <fcntl.h>
namespace DB
{
namespace ErrorCodes
{
extern const int CANNOT_READ_FROM_FILE_DESCRIPTOR;
extern const int CANNOT_ADVISE;
}
/** Implementation of IAsynchronousReader that in fact synchronous.
* The only addition is posix_fadvise.
*/
class SynchronousReader final : public IAsynchronousReader
{
public:
2021-08-04 00:07:04 +00:00
std::future<Result> submit(Request request) override
2021-07-26 00:34:36 +00:00
{
int fd = assert_cast<const LocalFileDescriptor &>(*request.descriptor).fd;
2021-08-05 21:01:13 +00:00
#if defined(POSIX_FADV_WILLNEED)
2021-07-26 00:34:36 +00:00
if (0 != posix_fadvise(fd, request.offset, request.size, POSIX_FADV_WILLNEED))
throwFromErrno("Cannot posix_fadvise", ErrorCodes::CANNOT_ADVISE);
2021-07-27 23:59:56 +00:00
#endif
2021-07-26 00:34:36 +00:00
2021-08-04 00:07:04 +00:00
return std::async(std::launch::deferred, [fd, request]
2021-07-26 00:34:36 +00:00
{
2021-08-04 00:07:04 +00:00
/// TODO Instrumentation.
2021-07-26 00:34:36 +00:00
2021-08-04 00:07:04 +00:00
size_t bytes_read = 0;
while (!bytes_read)
{
ssize_t res = ::pread(fd, request.buf, request.size, request.offset);
if (!res)
break;
2021-07-26 00:34:36 +00:00
2021-08-04 00:07:04 +00:00
if (-1 == res && errno != EINTR)
throwFromErrno(fmt::format("Cannot read from file {}", fd), ErrorCodes::CANNOT_READ_FROM_FILE_DESCRIPTOR);
2021-07-26 00:34:36 +00:00
2021-08-04 00:07:04 +00:00
if (res > 0)
bytes_read += res;
2021-07-26 00:34:36 +00:00
}
2021-08-04 00:07:04 +00:00
return bytes_read;
});
2021-07-26 00:34:36 +00:00
}
~SynchronousReader() override
{
/// Nothing to do, no requests are processed in background.
}
};
}