random_access_file_reader.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
  2. // This source code is licensed under both the GPLv2 (found in the
  3. // COPYING file in the root directory) and Apache 2.0 License
  4. // (found in the LICENSE.Apache file in the root directory).
  5. //
  6. // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
  7. // Use of this source code is governed by a BSD-style license that can be
  8. // found in the LICENSE file. See the AUTHORS file for names of contributors.
  9. #pragma once
  10. #include <atomic>
  11. #include <sstream>
  12. #include <string>
  13. #include "port/port.h"
  14. #include "rocksdb/env.h"
  15. #include "rocksdb/file_system.h"
  16. #include "rocksdb/listener.h"
  17. #include "rocksdb/rate_limiter.h"
  18. #include "util/aligned_buffer.h"
  19. namespace ROCKSDB_NAMESPACE {
  20. class Statistics;
  21. class HistogramImpl;
  22. // RandomAccessFileReader is a wrapper on top of Env::RnadomAccessFile. It is
  23. // responsible for:
  24. // - Handling Buffered and Direct reads appropriately.
  25. // - Rate limiting compaction reads.
  26. // - Notifying any interested listeners on the completion of a read.
  27. // - Updating IO stats.
  28. class RandomAccessFileReader {
  29. private:
  30. #ifndef ROCKSDB_LITE
  31. void NotifyOnFileReadFinish(uint64_t offset, size_t length,
  32. const FileOperationInfo::TimePoint& start_ts,
  33. const FileOperationInfo::TimePoint& finish_ts,
  34. const Status& status) const {
  35. FileOperationInfo info(file_name_, start_ts, finish_ts);
  36. info.offset = offset;
  37. info.length = length;
  38. info.status = status;
  39. for (auto& listener : listeners_) {
  40. listener->OnFileReadFinish(info);
  41. }
  42. }
  43. #endif // ROCKSDB_LITE
  44. bool ShouldNotifyListeners() const { return !listeners_.empty(); }
  45. std::unique_ptr<FSRandomAccessFile> file_;
  46. std::string file_name_;
  47. Env* env_;
  48. Statistics* stats_;
  49. uint32_t hist_type_;
  50. HistogramImpl* file_read_hist_;
  51. RateLimiter* rate_limiter_;
  52. std::vector<std::shared_ptr<EventListener>> listeners_;
  53. public:
  54. explicit RandomAccessFileReader(
  55. std::unique_ptr<FSRandomAccessFile>&& raf, std::string _file_name,
  56. Env* env = nullptr, Statistics* stats = nullptr, uint32_t hist_type = 0,
  57. HistogramImpl* file_read_hist = nullptr,
  58. RateLimiter* rate_limiter = nullptr,
  59. const std::vector<std::shared_ptr<EventListener>>& listeners = {})
  60. : file_(std::move(raf)),
  61. file_name_(std::move(_file_name)),
  62. env_(env),
  63. stats_(stats),
  64. hist_type_(hist_type),
  65. file_read_hist_(file_read_hist),
  66. rate_limiter_(rate_limiter),
  67. listeners_() {
  68. #ifndef ROCKSDB_LITE
  69. std::for_each(listeners.begin(), listeners.end(),
  70. [this](const std::shared_ptr<EventListener>& e) {
  71. if (e->ShouldBeNotifiedOnFileIO()) {
  72. listeners_.emplace_back(e);
  73. }
  74. });
  75. #else // !ROCKSDB_LITE
  76. (void)listeners;
  77. #endif
  78. }
  79. RandomAccessFileReader(RandomAccessFileReader&& o) ROCKSDB_NOEXCEPT {
  80. *this = std::move(o);
  81. }
  82. RandomAccessFileReader& operator=(RandomAccessFileReader&& o)
  83. ROCKSDB_NOEXCEPT {
  84. file_ = std::move(o.file_);
  85. env_ = std::move(o.env_);
  86. stats_ = std::move(o.stats_);
  87. hist_type_ = std::move(o.hist_type_);
  88. file_read_hist_ = std::move(o.file_read_hist_);
  89. rate_limiter_ = std::move(o.rate_limiter_);
  90. return *this;
  91. }
  92. RandomAccessFileReader(const RandomAccessFileReader&) = delete;
  93. RandomAccessFileReader& operator=(const RandomAccessFileReader&) = delete;
  94. Status Read(uint64_t offset, size_t n, Slice* result, char* scratch,
  95. bool for_compaction = false) const;
  96. Status MultiRead(FSReadRequest* reqs, size_t num_reqs) const;
  97. Status Prefetch(uint64_t offset, size_t n) const {
  98. return file_->Prefetch(offset, n, IOOptions(), nullptr);
  99. }
  100. FSRandomAccessFile* file() { return file_.get(); }
  101. std::string file_name() const { return file_name_; }
  102. bool use_direct_io() const { return file_->use_direct_io(); }
  103. };
  104. } // namespace ROCKSDB_NAMESPACE