From 864d01e564c4b5b08fb2b707dcb6a8246942cd2f Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Fri, 27 Aug 2021 03:35:04 +0300 Subject: [PATCH] Add pread_fake_async method --- src/IO/ReadSettings.h | 53 ++++++++++++++++--------- src/IO/createReadBufferFromFileBase.cpp | 6 +++ src/Interpreters/Context.cpp | 11 +---- 3 files changed, 41 insertions(+), 29 deletions(-) diff --git a/src/IO/ReadSettings.h b/src/IO/ReadSettings.h index 9ea12e20999..76a8a692f48 100644 --- a/src/IO/ReadSettings.h +++ b/src/IO/ReadSettings.h @@ -1,35 +1,50 @@ #pragma once #include +#include #include namespace DB { +#define FOR_EACH_READ_METHOD(M) \ + /** Simple synchronous reads with 'read'. \ + Can use direct IO after specified size. Can use prefetch by asking OS to perform readahead. */ \ + M(read) \ + \ + /** Simple synchronous reads with 'pread'. \ + In contrast to 'read', shares single file descriptor from multiple threads. \ + Can use direct IO after specified size. Can use prefetch by asking OS to perform readahead. */ \ + M(pread) \ + \ + /** Use mmap after specified size or simple synchronous reads with 'pread'. \ + Can use prefetch by asking OS to perform readahead. */ \ + M(mmap) \ + \ + /** Checks if data is in page cache with 'preadv2' on modern Linux kernels. \ + If data is in page cache, read from the same thread. \ + If not, offload IO to separate threadpool. \ + Can do prefetch with double buffering. \ + Can use specified priorities and limit the number of concurrent reads. */ \ + M(pread_threadpool) \ + \ + /** It's using asynchronous reader with fake backend that in fact synchronous. \ + Only used for testing purposes. */ \ + M(pread_fake_async) \ + + enum class ReadMethod { - /// Simple synchronous reads with 'read'. - /// Can use direct IO after specified size. Can use prefetch by asking OS to perform readahead. - read, - - /// Simple synchronous reads with 'pread'. - /// In contrast to 'read', shares single file descriptor from multiple threads. - /// Can use direct IO after specified size. Can use prefetch by asking OS to perform readahead. - pread, - - /// Use mmap after specified size or simple synchronous reads with 'pread'. - /// Can use prefetch by asking OS to perform readahead. - mmap, - - /// Checks if data is in page cache with 'preadv2' on modern Linux kernels. - /// If data is in page cache, read from the same thread. - /// If not, offload IO to separate threadpool. - /// Can do prefetch with double buffering. - /// Can use specified priorities and limit the number of concurrent reads. - pread_threadpool +#define DEFINE_READ_METHOD(NAME) NAME, + FOR_EACH_READ_METHOD(DEFINE_READ_METHOD) +#undef DEFINE_READ_METHOD }; +const char * toString(ReadMethod read_method); +ReadMethod parseReadMethod(const std::string & name); + + class MMappedFileCache; struct ReadSettings diff --git a/src/IO/createReadBufferFromFileBase.cpp b/src/IO/createReadBufferFromFileBase.cpp index 4e562851ae3..b39b3b384c4 100644 --- a/src/IO/createReadBufferFromFileBase.cpp +++ b/src/IO/createReadBufferFromFileBase.cpp @@ -64,6 +64,12 @@ std::unique_ptr createReadBufferFromFileBase( { res = std::make_unique(filename, buffer_size, actual_flags, existing_memory, alignment); } + else if (settings.local_fs_method == ReadMethod::pread_fake_async) + { + static AsynchronousReaderPtr reader = std::make_shared(); + res = std::make_unique( + reader, settings.priority, filename, buffer_size, actual_flags, existing_memory, alignment); + } else if (settings.local_fs_method == ReadMethod::pread_threadpool) { static AsynchronousReaderPtr reader = std::make_shared(16, 1000000); diff --git a/src/Interpreters/Context.cpp b/src/Interpreters/Context.cpp index 8a651bac526..a43bcb597c6 100644 --- a/src/Interpreters/Context.cpp +++ b/src/Interpreters/Context.cpp @@ -2697,16 +2697,7 @@ ReadSettings Context::getReadSettings() const { ReadSettings res; - if (settings.local_filesystem_read_method.value == "read") - res.local_fs_method = ReadMethod::read; - else if (settings.local_filesystem_read_method.value == "pread") - res.local_fs_method = ReadMethod::pread; - else if (settings.local_filesystem_read_method.value == "mmap") - res.local_fs_method = ReadMethod::mmap; - else if (settings.local_filesystem_read_method.value == "pread_threadpool") - res.local_fs_method = ReadMethod::pread_threadpool; - else - throw Exception(ErrorCodes::UNKNOWN_READ_METHOD, "Unknown read method '{}'", settings.local_filesystem_read_method.value); + res.local_fs_method = parseReadMethod(settings.local_filesystem_read_method.value); res.local_fs_prefetch = settings.local_filesystem_read_prefetch; res.remote_fs_prefetch = settings.remote_filesystem_read_prefetch;