| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461 |
- // Copyright (c) 2019-present, Facebook, Inc. 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
- #include "rocksdb/file_system.h"
- #include "rocksdb/system_clock.h"
- #include "trace_replay/io_tracer.h"
- namespace ROCKSDB_NAMESPACE {
- // FileSystemTracingWrapper is a wrapper class above FileSystem that forwards
- // the call to the underlying storage system. It then invokes IOTracer to record
- // file operations and other contextual information in a binary format for
- // tracing. It overrides methods we are interested in tracing and extends
- // FileSystemWrapper, which forwards all methods that are not explicitly
- // overridden.
- class FileSystemTracingWrapper : public FileSystemWrapper {
- public:
- FileSystemTracingWrapper(const std::shared_ptr<FileSystem>& t,
- const std::shared_ptr<IOTracer>& io_tracer)
- : FileSystemWrapper(t),
- io_tracer_(io_tracer),
- clock_(SystemClock::Default().get()) {}
- ~FileSystemTracingWrapper() override {}
- static const char* kClassName() { return "FileSystemTracing"; }
- const char* Name() const override { return kClassName(); }
- IOStatus NewSequentialFile(const std::string& fname,
- const FileOptions& file_opts,
- std::unique_ptr<FSSequentialFile>* result,
- IODebugContext* dbg) override;
- 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 ReopenWritableFile(const std::string& fname,
- const FileOptions& file_opts,
- std::unique_ptr<FSWritableFile>* result,
- IODebugContext* dbg) override;
- IOStatus ReuseWritableFile(const std::string& fname,
- const std::string& old_fname,
- const FileOptions& file_opts,
- std::unique_ptr<FSWritableFile>* result,
- IODebugContext* dbg) override;
- IOStatus NewRandomRWFile(const std::string& fname, const FileOptions& options,
- std::unique_ptr<FSRandomRWFile>* result,
- IODebugContext* dbg) override;
- IOStatus NewDirectory(const std::string& name, const IOOptions& io_opts,
- std::unique_ptr<FSDirectory>* result,
- IODebugContext* dbg) override;
- IOStatus GetChildren(const std::string& dir, const IOOptions& io_opts,
- std::vector<std::string>* r,
- IODebugContext* dbg) override;
- IOStatus DeleteFile(const std::string& fname, const IOOptions& options,
- IODebugContext* dbg) override;
- IOStatus CreateDir(const std::string& dirname, const IOOptions& options,
- IODebugContext* dbg) override;
- IOStatus CreateDirIfMissing(const std::string& dirname,
- const IOOptions& options,
- IODebugContext* dbg) override;
- IOStatus DeleteDir(const std::string& dirname, const IOOptions& options,
- IODebugContext* dbg) override;
- IOStatus GetFileSize(const std::string& fname, const IOOptions& options,
- uint64_t* file_size, IODebugContext* dbg) override;
- IOStatus Truncate(const std::string& fname, size_t size,
- const IOOptions& options, IODebugContext* dbg) override;
- private:
- std::shared_ptr<IOTracer> io_tracer_;
- SystemClock* clock_;
- };
- // The FileSystemPtr is a wrapper class that takes pointer to storage systems
- // (such as posix filesystems). It overloads operator -> and returns a pointer
- // of either FileSystem or FileSystemTracingWrapper based on whether tracing is
- // enabled or not. It is added to bypass FileSystemTracingWrapper when tracing
- // is disabled.
- class FileSystemPtr {
- public:
- FileSystemPtr(std::shared_ptr<FileSystem> fs,
- const std::shared_ptr<IOTracer>& io_tracer)
- : fs_(fs), io_tracer_(io_tracer) {
- fs_tracer_ = std::make_shared<FileSystemTracingWrapper>(fs_, io_tracer_);
- }
- std::shared_ptr<FileSystem> operator->() const {
- if (io_tracer_ && io_tracer_->is_tracing_enabled()) {
- return fs_tracer_;
- } else {
- return fs_;
- }
- }
- /* Returns the underlying File System pointer */
- FileSystem* get() const {
- if (io_tracer_ && io_tracer_->is_tracing_enabled()) {
- return fs_tracer_.get();
- } else {
- return fs_.get();
- }
- }
- private:
- std::shared_ptr<FileSystem> fs_;
- std::shared_ptr<IOTracer> io_tracer_;
- std::shared_ptr<FileSystemTracingWrapper> fs_tracer_;
- };
- // FSSequentialFileTracingWrapper is a wrapper class above FSSequentialFile that
- // forwards the call to the underlying storage system. It then invokes IOTracer
- // to record file operations and other contextual information in a binary format
- // for tracing. It overrides methods we are interested in tracing and extends
- // FSSequentialFileWrapper, which forwards all methods that are not explicitly
- // overridden.
- class FSSequentialFileTracingWrapper : public FSSequentialFileOwnerWrapper {
- public:
- FSSequentialFileTracingWrapper(std::unique_ptr<FSSequentialFile>&& t,
- std::shared_ptr<IOTracer> io_tracer,
- const std::string& file_name)
- : FSSequentialFileOwnerWrapper(std::move(t)),
- io_tracer_(io_tracer),
- clock_(SystemClock::Default().get()),
- file_name_(file_name) {}
- ~FSSequentialFileTracingWrapper() override {}
- IOStatus Read(size_t n, const IOOptions& options, Slice* result,
- char* scratch, IODebugContext* dbg) override;
- IOStatus InvalidateCache(size_t offset, size_t length) override;
- IOStatus PositionedRead(uint64_t offset, size_t n, const IOOptions& options,
- Slice* result, char* scratch,
- IODebugContext* dbg) override;
- private:
- std::shared_ptr<IOTracer> io_tracer_;
- SystemClock* clock_;
- std::string file_name_;
- };
- // The FSSequentialFilePtr is a wrapper class that takes pointer to storage
- // systems (such as posix filesystems). It overloads operator -> and returns a
- // pointer of either FSSequentialFile or FSSequentialFileTracingWrapper based on
- // whether tracing is enabled or not. It is added to bypass
- // FSSequentialFileTracingWrapper when tracing is disabled.
- class FSSequentialFilePtr {
- public:
- FSSequentialFilePtr() = delete;
- FSSequentialFilePtr(std::unique_ptr<FSSequentialFile>&& fs,
- const std::shared_ptr<IOTracer>& io_tracer,
- const std::string& file_name)
- : io_tracer_(io_tracer),
- fs_tracer_(std::move(fs), io_tracer_,
- file_name.substr(file_name.find_last_of("/\\") +
- 1) /* pass file name */) {}
- FSSequentialFile* operator->() const {
- if (io_tracer_ && io_tracer_->is_tracing_enabled()) {
- return const_cast<FSSequentialFileTracingWrapper*>(&fs_tracer_);
- } else {
- return fs_tracer_.target();
- }
- }
- FSSequentialFile* get() const {
- if (io_tracer_ && io_tracer_->is_tracing_enabled()) {
- return const_cast<FSSequentialFileTracingWrapper*>(&fs_tracer_);
- } else {
- return fs_tracer_.target();
- }
- }
- private:
- std::shared_ptr<IOTracer> io_tracer_;
- FSSequentialFileTracingWrapper fs_tracer_;
- };
- // FSRandomAccessFileTracingWrapper is a wrapper class above FSRandomAccessFile
- // that forwards the call to the underlying storage system. It then invokes
- // IOTracer to record file operations and other contextual information in a
- // binary format for tracing. It overrides methods we are interested in tracing
- // and extends FSRandomAccessFileWrapper, which forwards all methods that are
- // not explicitly overridden.
- class FSRandomAccessFileTracingWrapper : public FSRandomAccessFileOwnerWrapper {
- public:
- FSRandomAccessFileTracingWrapper(std::unique_ptr<FSRandomAccessFile>&& t,
- std::shared_ptr<IOTracer> io_tracer,
- const std::string& file_name)
- : FSRandomAccessFileOwnerWrapper(std::move(t)),
- io_tracer_(io_tracer),
- clock_(SystemClock::Default().get()),
- file_name_(file_name) {}
- ~FSRandomAccessFileTracingWrapper() 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;
- IOStatus InvalidateCache(size_t offset, size_t length) override;
- IOStatus ReadAsync(FSReadRequest& req, const IOOptions& opts,
- std::function<void(FSReadRequest&, void*)> cb,
- void* cb_arg, void** io_handle, IOHandleDeleter* del_fn,
- IODebugContext* dbg) override;
- void ReadAsyncCallback(FSReadRequest& req, void* cb_arg);
- private:
- std::shared_ptr<IOTracer> io_tracer_;
- SystemClock* clock_;
- // Stores file name instead of full path.
- std::string file_name_;
- struct ReadAsyncCallbackInfo {
- uint64_t start_time_;
- std::function<void(FSReadRequest&, void*)> cb_;
- void* cb_arg_;
- std::string file_op_;
- };
- };
- // The FSRandomAccessFilePtr is a wrapper class that takes pointer to storage
- // systems (such as posix filesystems). It overloads operator -> and returns a
- // pointer of either FSRandomAccessFile or FSRandomAccessFileTracingWrapper
- // based on whether tracing is enabled or not. It is added to bypass
- // FSRandomAccessFileTracingWrapper when tracing is disabled.
- class FSRandomAccessFilePtr {
- public:
- FSRandomAccessFilePtr(std::unique_ptr<FSRandomAccessFile>&& fs,
- const std::shared_ptr<IOTracer>& io_tracer,
- const std::string& file_name)
- : io_tracer_(io_tracer),
- fs_tracer_(std::move(fs), io_tracer_,
- file_name.substr(file_name.find_last_of("/\\") +
- 1) /* pass file name */) {}
- FSRandomAccessFile* operator->() const {
- if (io_tracer_ && io_tracer_->is_tracing_enabled()) {
- return const_cast<FSRandomAccessFileTracingWrapper*>(&fs_tracer_);
- } else {
- return fs_tracer_.target();
- }
- }
- FSRandomAccessFile* get() const {
- if (io_tracer_ && io_tracer_->is_tracing_enabled()) {
- return const_cast<FSRandomAccessFileTracingWrapper*>(&fs_tracer_);
- } else {
- return fs_tracer_.target();
- }
- }
- private:
- std::shared_ptr<IOTracer> io_tracer_;
- FSRandomAccessFileTracingWrapper fs_tracer_;
- };
- // FSWritableFileTracingWrapper is a wrapper class above FSWritableFile that
- // forwards the call to the underlying storage system. It then invokes IOTracer
- // to record file operations and other contextual information in a binary format
- // for tracing. It overrides methods we are interested in tracing and extends
- // FSWritableFileWrapper, which forwards all methods that are not explicitly
- // overridden.
- class FSWritableFileTracingWrapper : public FSWritableFileOwnerWrapper {
- public:
- FSWritableFileTracingWrapper(std::unique_ptr<FSWritableFile>&& t,
- std::shared_ptr<IOTracer> io_tracer,
- const std::string& file_name)
- : FSWritableFileOwnerWrapper(std::move(t)),
- io_tracer_(io_tracer),
- clock_(SystemClock::Default().get()),
- file_name_(file_name) {}
- ~FSWritableFileTracingWrapper() override {}
- IOStatus Append(const Slice& data, const IOOptions& options,
- IODebugContext* dbg) override;
- IOStatus Append(const Slice& data, const IOOptions& options,
- const DataVerificationInfo& /*verification_info*/,
- IODebugContext* dbg) override {
- return Append(data, options, dbg);
- }
- 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 {
- return PositionedAppend(data, offset, options, dbg);
- }
- IOStatus Truncate(uint64_t size, const IOOptions& options,
- IODebugContext* dbg) override;
- IOStatus Close(const IOOptions& options, IODebugContext* dbg) override;
- uint64_t GetFileSize(const IOOptions& options, IODebugContext* dbg) override;
- IOStatus InvalidateCache(size_t offset, size_t length) override;
- private:
- std::shared_ptr<IOTracer> io_tracer_;
- SystemClock* clock_;
- // Stores file name instead of full path.
- std::string file_name_;
- };
- // The FSWritableFilePtr is a wrapper class that takes pointer to storage
- // systems (such as posix filesystems). It overloads operator -> and returns a
- // pointer of either FSWritableFile or FSWritableFileTracingWrapper based on
- // whether tracing is enabled or not. It is added to bypass
- // FSWritableFileTracingWrapper when tracing is disabled.
- class FSWritableFilePtr {
- public:
- FSWritableFilePtr(std::unique_ptr<FSWritableFile>&& fs,
- const std::shared_ptr<IOTracer>& io_tracer,
- const std::string& file_name)
- : io_tracer_(io_tracer) {
- fs_tracer_.reset(new FSWritableFileTracingWrapper(
- std::move(fs), io_tracer_,
- file_name.substr(file_name.find_last_of("/\\") +
- 1) /* pass file name */));
- }
- FSWritableFile* operator->() const {
- if (io_tracer_ && io_tracer_->is_tracing_enabled()) {
- return fs_tracer_.get();
- } else {
- return fs_tracer_->target();
- }
- }
- FSWritableFile* get() const {
- if (io_tracer_ && io_tracer_->is_tracing_enabled()) {
- return fs_tracer_.get();
- } else if (fs_tracer_) {
- return fs_tracer_->target();
- } else {
- return nullptr;
- }
- }
- void reset() {
- fs_tracer_.reset();
- io_tracer_ = nullptr;
- }
- private:
- std::shared_ptr<IOTracer> io_tracer_;
- std::unique_ptr<FSWritableFileTracingWrapper> fs_tracer_;
- };
- // FSRandomRWFileTracingWrapper is a wrapper class above FSRandomRWFile that
- // forwards the call to the underlying storage system. It then invokes IOTracer
- // to record file operations and other contextual information in a binary format
- // for tracing. It overrides methods we are interested in tracing and extends
- // FSRandomRWFileWrapper, which forwards all methods that are not explicitly
- // overridden.
- class FSRandomRWFileTracingWrapper : public FSRandomRWFileOwnerWrapper {
- public:
- FSRandomRWFileTracingWrapper(std::unique_ptr<FSRandomRWFile>&& t,
- std::shared_ptr<IOTracer> io_tracer,
- const std::string& file_name)
- : FSRandomRWFileOwnerWrapper(std::move(t)),
- io_tracer_(io_tracer),
- clock_(SystemClock::Default().get()),
- file_name_(file_name) {}
- ~FSRandomRWFileTracingWrapper() override {}
- IOStatus Write(uint64_t offset, const Slice& data, const IOOptions& options,
- IODebugContext* dbg) override;
- IOStatus Read(uint64_t offset, size_t n, const IOOptions& options,
- Slice* result, char* scratch,
- IODebugContext* dbg) const override;
- IOStatus Flush(const IOOptions& options, IODebugContext* dbg) override;
- IOStatus Close(const IOOptions& options, IODebugContext* dbg) override;
- IOStatus Sync(const IOOptions& options, IODebugContext* dbg) override;
- IOStatus Fsync(const IOOptions& options, IODebugContext* dbg) override;
- private:
- std::shared_ptr<IOTracer> io_tracer_;
- SystemClock* clock_;
- // Stores file name instead of full path.
- std::string file_name_;
- };
- // The FSRandomRWFilePtr is a wrapper class that takes pointer to storage
- // systems (such as posix filesystems). It overloads operator -> and returns a
- // pointer of either FSRandomRWFile or FSRandomRWFileTracingWrapper based on
- // whether tracing is enabled or not. It is added to bypass
- // FSRandomRWFileTracingWrapper when tracing is disabled.
- class FSRandomRWFilePtr {
- public:
- FSRandomRWFilePtr(std::unique_ptr<FSRandomRWFile>&& fs,
- std::shared_ptr<IOTracer> io_tracer,
- const std::string& file_name)
- : io_tracer_(io_tracer),
- fs_tracer_(std::move(fs), io_tracer_,
- file_name.substr(file_name.find_last_of("/\\") +
- 1) /* pass file name */) {}
- FSRandomRWFile* operator->() const {
- if (io_tracer_ && io_tracer_->is_tracing_enabled()) {
- return const_cast<FSRandomRWFileTracingWrapper*>(&fs_tracer_);
- } else {
- return fs_tracer_.target();
- }
- }
- FSRandomRWFile* get() const {
- if (io_tracer_ && io_tracer_->is_tracing_enabled()) {
- return const_cast<FSRandomRWFileTracingWrapper*>(&fs_tracer_);
- } else {
- return fs_tracer_.target();
- }
- }
- private:
- std::shared_ptr<IOTracer> io_tracer_;
- FSRandomRWFileTracingWrapper fs_tracer_;
- };
- } // namespace ROCKSDB_NAMESPACE
|