1 // Copyright (c) 2017-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 #include "env/composite_env_wrapper.h"
7 #include "monitoring/perf_context_imp.h"
8 #include "rocksdb/env.h"
9 #include "rocksdb/file_system.h"
10 #include "rocksdb/status.h"
11
12 namespace ROCKSDB_NAMESPACE {
13
14 #ifndef ROCKSDB_LITE
15 namespace {
16 class TimedFileSystem : public FileSystemWrapper {
17 public:
TimedFileSystem(const std::shared_ptr<FileSystem> & base)18 explicit TimedFileSystem(const std::shared_ptr<FileSystem>& base)
19 : FileSystemWrapper(base) {}
20
Name() const21 const char* Name() const override { return "TimedFS"; }
NewSequentialFile(const std::string & fname,const FileOptions & options,std::unique_ptr<FSSequentialFile> * result,IODebugContext * dbg)22 IOStatus NewSequentialFile(const std::string& fname,
23 const FileOptions& options,
24 std::unique_ptr<FSSequentialFile>* result,
25 IODebugContext* dbg) override {
26 PERF_TIMER_GUARD(env_new_sequential_file_nanos);
27 return FileSystemWrapper::NewSequentialFile(fname, options, result, dbg);
28 }
29
NewRandomAccessFile(const std::string & fname,const FileOptions & options,std::unique_ptr<FSRandomAccessFile> * result,IODebugContext * dbg)30 IOStatus NewRandomAccessFile(const std::string& fname,
31 const FileOptions& options,
32 std::unique_ptr<FSRandomAccessFile>* result,
33 IODebugContext* dbg) override {
34 PERF_TIMER_GUARD(env_new_random_access_file_nanos);
35 return FileSystemWrapper::NewRandomAccessFile(fname, options, result, dbg);
36 }
37
NewWritableFile(const std::string & fname,const FileOptions & options,std::unique_ptr<FSWritableFile> * result,IODebugContext * dbg)38 IOStatus NewWritableFile(const std::string& fname, const FileOptions& options,
39 std::unique_ptr<FSWritableFile>* result,
40 IODebugContext* dbg) override {
41 PERF_TIMER_GUARD(env_new_writable_file_nanos);
42 return FileSystemWrapper::NewWritableFile(fname, options, result, dbg);
43 }
44
ReuseWritableFile(const std::string & fname,const std::string & old_fname,const FileOptions & options,std::unique_ptr<FSWritableFile> * result,IODebugContext * dbg)45 IOStatus ReuseWritableFile(const std::string& fname,
46 const std::string& old_fname,
47 const FileOptions& options,
48 std::unique_ptr<FSWritableFile>* result,
49 IODebugContext* dbg) override {
50 PERF_TIMER_GUARD(env_reuse_writable_file_nanos);
51 return FileSystemWrapper::ReuseWritableFile(fname, old_fname, options,
52 result, dbg);
53 }
54
NewRandomRWFile(const std::string & fname,const FileOptions & options,std::unique_ptr<FSRandomRWFile> * result,IODebugContext * dbg)55 IOStatus NewRandomRWFile(const std::string& fname, const FileOptions& options,
56 std::unique_ptr<FSRandomRWFile>* result,
57 IODebugContext* dbg) override {
58 PERF_TIMER_GUARD(env_new_random_rw_file_nanos);
59 return FileSystemWrapper::NewRandomRWFile(fname, options, result, dbg);
60 }
61
NewDirectory(const std::string & name,const IOOptions & options,std::unique_ptr<FSDirectory> * result,IODebugContext * dbg)62 IOStatus NewDirectory(const std::string& name, const IOOptions& options,
63 std::unique_ptr<FSDirectory>* result,
64 IODebugContext* dbg) override {
65 PERF_TIMER_GUARD(env_new_directory_nanos);
66 return FileSystemWrapper::NewDirectory(name, options, result, dbg);
67 }
68
FileExists(const std::string & fname,const IOOptions & options,IODebugContext * dbg)69 IOStatus FileExists(const std::string& fname, const IOOptions& options,
70 IODebugContext* dbg) override {
71 PERF_TIMER_GUARD(env_file_exists_nanos);
72 return FileSystemWrapper::FileExists(fname, options, dbg);
73 }
74
GetChildren(const std::string & dir,const IOOptions & options,std::vector<std::string> * result,IODebugContext * dbg)75 IOStatus GetChildren(const std::string& dir, const IOOptions& options,
76 std::vector<std::string>* result,
77 IODebugContext* dbg) override {
78 PERF_TIMER_GUARD(env_get_children_nanos);
79 return FileSystemWrapper::GetChildren(dir, options, result, dbg);
80 }
81
GetChildrenFileAttributes(const std::string & dir,const IOOptions & options,std::vector<FileAttributes> * result,IODebugContext * dbg)82 IOStatus GetChildrenFileAttributes(const std::string& dir,
83 const IOOptions& options,
84 std::vector<FileAttributes>* result,
85 IODebugContext* dbg) override {
86 PERF_TIMER_GUARD(env_get_children_file_attributes_nanos);
87 return FileSystemWrapper::GetChildrenFileAttributes(dir, options, result,
88 dbg);
89 }
90
DeleteFile(const std::string & fname,const IOOptions & options,IODebugContext * dbg)91 IOStatus DeleteFile(const std::string& fname, const IOOptions& options,
92 IODebugContext* dbg) override {
93 PERF_TIMER_GUARD(env_delete_file_nanos);
94 return FileSystemWrapper::DeleteFile(fname, options, dbg);
95 }
96
CreateDir(const std::string & dirname,const IOOptions & options,IODebugContext * dbg)97 IOStatus CreateDir(const std::string& dirname, const IOOptions& options,
98 IODebugContext* dbg) override {
99 PERF_TIMER_GUARD(env_create_dir_nanos);
100 return FileSystemWrapper::CreateDir(dirname, options, dbg);
101 }
102
CreateDirIfMissing(const std::string & dirname,const IOOptions & options,IODebugContext * dbg)103 IOStatus CreateDirIfMissing(const std::string& dirname,
104 const IOOptions& options,
105 IODebugContext* dbg) override {
106 PERF_TIMER_GUARD(env_create_dir_if_missing_nanos);
107 return FileSystemWrapper::CreateDirIfMissing(dirname, options, dbg);
108 }
109
DeleteDir(const std::string & dirname,const IOOptions & options,IODebugContext * dbg)110 IOStatus DeleteDir(const std::string& dirname, const IOOptions& options,
111 IODebugContext* dbg) override {
112 PERF_TIMER_GUARD(env_delete_dir_nanos);
113 return FileSystemWrapper::DeleteDir(dirname, options, dbg);
114 }
115
GetFileSize(const std::string & fname,const IOOptions & options,uint64_t * file_size,IODebugContext * dbg)116 IOStatus GetFileSize(const std::string& fname, const IOOptions& options,
117 uint64_t* file_size, IODebugContext* dbg) override {
118 PERF_TIMER_GUARD(env_get_file_size_nanos);
119 return FileSystemWrapper::GetFileSize(fname, options, file_size, dbg);
120 }
121
GetFileModificationTime(const std::string & fname,const IOOptions & options,uint64_t * file_mtime,IODebugContext * dbg)122 IOStatus GetFileModificationTime(const std::string& fname,
123 const IOOptions& options,
124 uint64_t* file_mtime,
125 IODebugContext* dbg) override {
126 PERF_TIMER_GUARD(env_get_file_modification_time_nanos);
127 return FileSystemWrapper::GetFileModificationTime(fname, options,
128 file_mtime, dbg);
129 }
130
RenameFile(const std::string & src,const std::string & dst,const IOOptions & options,IODebugContext * dbg)131 IOStatus RenameFile(const std::string& src, const std::string& dst,
132 const IOOptions& options, IODebugContext* dbg) override {
133 PERF_TIMER_GUARD(env_rename_file_nanos);
134 return FileSystemWrapper::RenameFile(src, dst, options, dbg);
135 }
136
LinkFile(const std::string & src,const std::string & dst,const IOOptions & options,IODebugContext * dbg)137 IOStatus LinkFile(const std::string& src, const std::string& dst,
138 const IOOptions& options, IODebugContext* dbg) override {
139 PERF_TIMER_GUARD(env_link_file_nanos);
140 return FileSystemWrapper::LinkFile(src, dst, options, dbg);
141 }
142
LockFile(const std::string & fname,const IOOptions & options,FileLock ** lock,IODebugContext * dbg)143 IOStatus LockFile(const std::string& fname, const IOOptions& options,
144 FileLock** lock, IODebugContext* dbg) override {
145 PERF_TIMER_GUARD(env_lock_file_nanos);
146 return FileSystemWrapper::LockFile(fname, options, lock, dbg);
147 }
148
UnlockFile(FileLock * lock,const IOOptions & options,IODebugContext * dbg)149 IOStatus UnlockFile(FileLock* lock, const IOOptions& options,
150 IODebugContext* dbg) override {
151 PERF_TIMER_GUARD(env_unlock_file_nanos);
152 return FileSystemWrapper::UnlockFile(lock, options, dbg);
153 }
154
NewLogger(const std::string & fname,const IOOptions & options,std::shared_ptr<Logger> * result,IODebugContext * dbg)155 IOStatus NewLogger(const std::string& fname, const IOOptions& options,
156 std::shared_ptr<Logger>* result,
157 IODebugContext* dbg) override {
158 PERF_TIMER_GUARD(env_new_logger_nanos);
159 return FileSystemWrapper::NewLogger(fname, options, result, dbg);
160 }
161 };
162 } // namespace
163
NewTimedFileSystem(const std::shared_ptr<FileSystem> & base)164 std::shared_ptr<FileSystem> NewTimedFileSystem(
165 const std::shared_ptr<FileSystem>& base) {
166 return std::make_shared<TimedFileSystem>(base);
167 }
168
169 // An environment that measures function call times for filesystem
170 // operations, reporting results to variables in PerfContext.
NewTimedEnv(Env * base_env)171 Env* NewTimedEnv(Env* base_env) {
172 std::shared_ptr<FileSystem> timed_fs =
173 NewTimedFileSystem(base_env->GetFileSystem());
174 return new CompositeEnvWrapper(base_env, timed_fs);
175 }
176
177 #else // ROCKSDB_LITE
178
179 Env* NewTimedEnv(Env* /*base_env*/) { return nullptr; }
180
181 #endif // !ROCKSDB_LITE
182
183 } // namespace ROCKSDB_NAMESPACE
184