summaryrefslogtreecommitdiffstats
path: root/src/rocksdb/tools/simulated_hybrid_file_system.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/rocksdb/tools/simulated_hybrid_file_system.h126
1 files changed, 126 insertions, 0 deletions
diff --git a/src/rocksdb/tools/simulated_hybrid_file_system.h b/src/rocksdb/tools/simulated_hybrid_file_system.h
new file mode 100644
index 000000000..251d89df7
--- /dev/null
+++ b/src/rocksdb/tools/simulated_hybrid_file_system.h
@@ -0,0 +1,126 @@
+// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+
+#pragma once
+
+#ifndef ROCKSDB_LITE
+
+#include <utility>
+
+#include "rocksdb/file_system.h"
+
+namespace ROCKSDB_NAMESPACE {
+
+// A FileSystem simulates hybrid file system by ingesting latency and limit
+// IOPs.
+// This class is only used for development purpose and should not be used
+// in production.
+// Right now we ingest 15ms latency and allow 100 requests per second when
+// the file is for warm temperature.
+// When the object is destroyed, the list of warm files are written to a
+// file, which can be used to reopen a FileSystem and still recover the
+// list. This is to allow the information to preserve between db_bench
+// runs.
+class SimulatedHybridFileSystem : public FileSystemWrapper {
+ public:
+ // metadata_file_name stores metadata of the files, so that it can be
+ // loaded after process restarts. If the file doesn't exist, create
+ // one. The file is written when the class is destroyed.
+ // throughput_multiplier: multiplier of throughput. For example, 1 is to
+ // simulate single disk spindle. 4 is to simualte 4 disk spindles.
+ // is_full_fs_warm: if true, all files are all included in slow I/O
+ // simulation.
+ SimulatedHybridFileSystem(const std::shared_ptr<FileSystem>& base,
+ const std::string& metadata_file_name,
+ int throughput_multiplier, bool is_full_fs_warm);
+
+ ~SimulatedHybridFileSystem() override;
+
+ public:
+ IOStatus NewRandomAccessFile(const std::string& fname,
+ const FileOptions& file_opts,
+ std::unique_ptr<FSRandomAccessFile>* result,
+ IODebugContext* dbg) override;
+ IOStatus NewWritableFile(const std::string& fname,
+ const FileOptions& file_opts,
+ std::unique_ptr<FSWritableFile>* result,
+ IODebugContext* dbg) override;
+ IOStatus DeleteFile(const std::string& fname, const IOOptions& options,
+ IODebugContext* dbg) override;
+
+ const char* Name() const override { return name_.c_str(); }
+
+ private:
+ // Limit 100 requests per second. Rate limiter is designed to byte but
+ // we use it as fixed bytes is one request.
+ std::shared_ptr<RateLimiter> rate_limiter_;
+ std::mutex mutex_;
+ std::unordered_set<std::string> warm_file_set_;
+ std::string metadata_file_name_;
+ std::string name_;
+ bool is_full_fs_warm_;
+};
+
+// Simulated random access file that can control IOPs and latency to simulate
+// specific storage media
+class SimulatedHybridRaf : public FSRandomAccessFileOwnerWrapper {
+ public:
+ SimulatedHybridRaf(std::unique_ptr<FSRandomAccessFile>&& t,
+ std::shared_ptr<RateLimiter> rate_limiter,
+ Temperature temperature)
+ : FSRandomAccessFileOwnerWrapper(std::move(t)),
+ rate_limiter_(rate_limiter),
+ temperature_(temperature) {}
+
+ ~SimulatedHybridRaf() override {}
+
+ IOStatus Read(uint64_t offset, size_t n, const IOOptions& options,
+ Slice* result, char* scratch,
+ IODebugContext* dbg) const override;
+
+ IOStatus MultiRead(FSReadRequest* reqs, size_t num_reqs,
+ const IOOptions& options, IODebugContext* dbg) override;
+
+ IOStatus Prefetch(uint64_t offset, size_t n, const IOOptions& options,
+ IODebugContext* dbg) override;
+
+ private:
+ std::shared_ptr<RateLimiter> rate_limiter_;
+ Temperature temperature_;
+
+ void SimulateIOWait(int64_t num_requests) const;
+};
+
+class SimulatedWritableFile : public FSWritableFileWrapper {
+ public:
+ SimulatedWritableFile(std::unique_ptr<FSWritableFile>&& t,
+ std::shared_ptr<RateLimiter> rate_limiter)
+ : FSWritableFileWrapper(t.get()),
+ file_guard_(std::move(t)),
+ rate_limiter_(rate_limiter) {}
+ IOStatus Append(const Slice& data, const IOOptions&,
+ IODebugContext*) override;
+ IOStatus Append(const Slice& data, const IOOptions& options,
+ const DataVerificationInfo& verification_info,
+ IODebugContext* dbg) override;
+ IOStatus Sync(const IOOptions& options, IODebugContext* dbg) override;
+ IOStatus PositionedAppend(const Slice& data, uint64_t offset,
+ const IOOptions& options,
+ IODebugContext* dbg) override;
+ IOStatus PositionedAppend(const Slice& data, uint64_t offset,
+ const IOOptions& options,
+ const DataVerificationInfo& verification_info,
+ IODebugContext* dbg) override;
+
+ private:
+ std::unique_ptr<FSWritableFile> file_guard_;
+ std::shared_ptr<RateLimiter> rate_limiter_;
+ size_t unsynced_bytes = 0;
+
+ void SimulateIOWait(int64_t num_requests) const;
+};
+} // namespace ROCKSDB_NAMESPACE
+
+#endif // ROCKSDB_LITE