1 // Copyright (c) Facebook, Inc. and its affiliates. 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 #pragma once 7 8 #ifndef ROCKSDB_LITE 9 10 #include <utility> 11 12 #include "rocksdb/file_system.h" 13 14 namespace ROCKSDB_NAMESPACE { 15 16 // A FileSystem simulates hybrid file system by ingesting latency and limit 17 // IOPs. 18 // This class is only used for development purpose and should not be used 19 // in production. 20 // Right now we ingest 15ms latency and allow 100 requests per second when 21 // the file is for warm temperature. 22 // When the object is destroyed, the list of warm files are written to a 23 // file, which can be used to reopen a FileSystem and still recover the 24 // list. This is to allow the information to preserve between db_bench 25 // runs. 26 class SimulatedHybridFileSystem : public FileSystemWrapper { 27 public: 28 // metadata_file_name stores metadata of the files, so that it can be 29 // loaded after process restarts. If the file doesn't exist, create 30 // one. The file is written when the class is destroyed. 31 explicit SimulatedHybridFileSystem(const std::shared_ptr<FileSystem>& base, 32 const std::string& metadata_file_name); 33 34 ~SimulatedHybridFileSystem() override; 35 36 public: 37 IOStatus NewRandomAccessFile(const std::string& fname, 38 const FileOptions& file_opts, 39 std::unique_ptr<FSRandomAccessFile>* result, 40 IODebugContext* dbg) override; 41 IOStatus NewWritableFile(const std::string& fname, 42 const FileOptions& file_opts, 43 std::unique_ptr<FSWritableFile>* result, 44 IODebugContext* dbg) override; 45 IOStatus DeleteFile(const std::string& fname, const IOOptions& options, 46 IODebugContext* dbg) override; 47 Name()48 const char* Name() const override { return name_.c_str(); } 49 50 private: 51 // Limit 100 requests per second. Rate limiter is designed to byte but 52 // we use it as fixed bytes is one request. 53 std::shared_ptr<RateLimiter> rate_limiter_; 54 std::mutex mutex_; 55 std::unordered_set<std::string> warm_file_set_; 56 std::string metadata_file_name_; 57 std::string name_; 58 }; 59 60 // Simulated random access file that can control IOPs and latency to simulate 61 // specific storage media 62 class SimulatedHybridRaf : public FSRandomAccessFileOwnerWrapper { 63 public: SimulatedHybridRaf(std::unique_ptr<FSRandomAccessFile> && t,std::shared_ptr<RateLimiter> rate_limiter,Temperature temperature)64 SimulatedHybridRaf(std::unique_ptr<FSRandomAccessFile>&& t, 65 std::shared_ptr<RateLimiter> rate_limiter, 66 Temperature temperature) 67 : FSRandomAccessFileOwnerWrapper(std::move(t)), 68 rate_limiter_(rate_limiter), 69 temperature_(temperature) {} 70 ~SimulatedHybridRaf()71 ~SimulatedHybridRaf() override {} 72 73 IOStatus Read(uint64_t offset, size_t n, const IOOptions& options, 74 Slice* result, char* scratch, 75 IODebugContext* dbg) const override; 76 77 IOStatus MultiRead(FSReadRequest* reqs, size_t num_reqs, 78 const IOOptions& options, IODebugContext* dbg) override; 79 80 IOStatus Prefetch(uint64_t offset, size_t n, const IOOptions& options, 81 IODebugContext* dbg) override; 82 83 private: 84 std::shared_ptr<RateLimiter> rate_limiter_; 85 Temperature temperature_; 86 87 void RequestRateLimit(int64_t num_requests) const; 88 }; 89 } // namespace ROCKSDB_NAMESPACE 90 91 #endif // ROCKSDB_LITE 92