From e7ff7e05683021233501e8e477d6282bca3728c0 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Wed, 6 May 2020 19:15:22 -0700 Subject: [PATCH] ircd::db::env: Implement rocksdb MultiRead() environment backend. --- ircd/db_env.cc | 100 +++++++++++++++++++++++++++++++++++++++++++++++++ ircd/db_env.h | 9 +++++ 2 files changed, 109 insertions(+) diff --git a/ircd/db_env.cc b/ircd/db_env.cc index dd2c108ff..da9d5f201 100644 --- a/ircd/db_env.cc +++ b/ircd/db_env.cc @@ -3340,6 +3340,106 @@ catch(const std::exception &e) return error_to_status{e}; } +#ifdef IRCD_DB_HAS_ENV_MULTIREAD +rocksdb::Status +ircd::db::database::env::random_access_file::MultiRead(rocksdb::ReadRequest *const req, + size_t num) +noexcept try +{ + assert(req); + const ctx::uninterruptible::nothrow ui; + + fs::read_op op[num]; + mutable_buffer buf[num]; + fs::read_opts opts[num]; + for(size_t i(0); i < num; ++i) + { + opts[i].offset = req[i].offset; + opts[i].priority = ionice; + opts[i].aio = this->aio; + opts[i].all = false; + buf[i] = + { + req[i].scratch, req[i].len + }; + + op[i].fd = std::addressof(this->fd); + op[i].opts = opts + i; + op[i].bufs = + { + buf + i, 1 + }; + + #ifdef RB_DEBUG_DB_ENV + log::debug + { + log, "[%s] rfile:%p multiread:%zu:%zu offset:%zu length:%zu scratch:%p", + d.name, + this, + i, + num, + req[i].offset, + req[i].len, + req[i].scratch, + }; + #endif + + assert(!this->opts.direct || buffer::aligned(buf[i], _buffer_align)); + } + + const auto bytes + { + fs::read({op, num}) + }; + + for(size_t i(0); i < num; ++i) try + { + assert(op[i].ret <= size(buf[i])); + const const_buffer read(buf[i], op[i].ret); + req[i].result = slice(read); + + if(op[i].eptr) + std::rethrow_exception(op[i].eptr); + + req[i].status = Status::OK(); + } + catch(const std::exception &e) + { + req[i].status = error_to_status{e}; + } + + return Status::OK(); +} +catch(const std::system_error &e) +{ + log::error + { + log, "[%s] rfile:%p multiread:%p num:%zu :%s", + d.name, + this, + req, + num, + e.what(), + }; + + return error_to_status{e}; +} +catch(const std::exception &e) +{ + log::critical + { + log, "[%s] rfile:%p multiread:%p num:%zu :%s", + d.name, + this, + req, + num, + e.what(), + }; + + return error_to_status{e}; +} +#endif IRCD_DB_HAS_ENV_MULTIREAD + rocksdb::Status ircd::db::database::env::random_access_file::Read(uint64_t offset, size_t length, diff --git a/ircd/db_env.h b/ircd/db_env.h index 0e143a7be..9c9a25be0 100644 --- a/ircd/db_env.h +++ b/ircd/db_env.h @@ -14,6 +14,12 @@ #define IRCD_DB_HAS_ENV_PRIO_USER #endif +#if ROCKSDB_MAJOR > 6 \ +|| (ROCKSDB_MAJOR == 6 && ROCKSDB_MINOR > 3) \ +|| (ROCKSDB_MAJOR == 6 && ROCKSDB_MINOR == 3 && ROCKSDB_PATCH >= 6) + #define IRCD_DB_HAS_ENV_MULTIREAD +#endif + /// Internal environment hookup. /// struct ircd::db::database::env final @@ -143,6 +149,9 @@ struct ircd::db::database::env::random_access_file final void Hint(AccessPattern pattern) noexcept override; Status InvalidateCache(size_t offset, size_t length) noexcept override; Status Read(uint64_t offset, size_t n, Slice *result, char *scratch) const noexcept override; + #ifdef IRCD_DB_HAS_ENV_MULTIREAD + Status MultiRead(rocksdb::ReadRequest *, size_t num) noexcept override; + #endif Status Prefetch(uint64_t offset, size_t n) noexcept override; random_access_file(database *const &d, const std::string &name, const EnvOptions &);