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 "monitoring/perf_context_imp.h"
7 #include "rocksdb/env.h"
8 #include "rocksdb/status.h"
9 
10 namespace ROCKSDB_NAMESPACE {
11 
12 #ifndef ROCKSDB_LITE
13 
14 // An environment that measures function call times for filesystem
15 // operations, reporting results to variables in PerfContext.
16 class TimedEnv : public EnvWrapper {
17  public:
TimedEnv(Env * base_env)18   explicit TimedEnv(Env* base_env) : EnvWrapper(base_env) {}
19 
NewSequentialFile(const std::string & fname,std::unique_ptr<SequentialFile> * result,const EnvOptions & options)20   Status NewSequentialFile(const std::string& fname,
21                            std::unique_ptr<SequentialFile>* result,
22                            const EnvOptions& options) override {
23     PERF_TIMER_GUARD(env_new_sequential_file_nanos);
24     return EnvWrapper::NewSequentialFile(fname, result, options);
25   }
26 
NewRandomAccessFile(const std::string & fname,std::unique_ptr<RandomAccessFile> * result,const EnvOptions & options)27   Status NewRandomAccessFile(const std::string& fname,
28                              std::unique_ptr<RandomAccessFile>* result,
29                              const EnvOptions& options) override {
30     PERF_TIMER_GUARD(env_new_random_access_file_nanos);
31     return EnvWrapper::NewRandomAccessFile(fname, result, options);
32   }
33 
NewWritableFile(const std::string & fname,std::unique_ptr<WritableFile> * result,const EnvOptions & options)34   Status NewWritableFile(const std::string& fname,
35                          std::unique_ptr<WritableFile>* result,
36                          const EnvOptions& options) override {
37     PERF_TIMER_GUARD(env_new_writable_file_nanos);
38     return EnvWrapper::NewWritableFile(fname, result, options);
39   }
40 
ReuseWritableFile(const std::string & fname,const std::string & old_fname,std::unique_ptr<WritableFile> * result,const EnvOptions & options)41   Status ReuseWritableFile(const std::string& fname,
42                            const std::string& old_fname,
43                            std::unique_ptr<WritableFile>* result,
44                            const EnvOptions& options) override {
45     PERF_TIMER_GUARD(env_reuse_writable_file_nanos);
46     return EnvWrapper::ReuseWritableFile(fname, old_fname, result, options);
47   }
48 
NewRandomRWFile(const std::string & fname,std::unique_ptr<RandomRWFile> * result,const EnvOptions & options)49   Status NewRandomRWFile(const std::string& fname,
50                          std::unique_ptr<RandomRWFile>* result,
51                          const EnvOptions& options) override {
52     PERF_TIMER_GUARD(env_new_random_rw_file_nanos);
53     return EnvWrapper::NewRandomRWFile(fname, result, options);
54   }
55 
NewDirectory(const std::string & name,std::unique_ptr<Directory> * result)56   Status NewDirectory(const std::string& name,
57                       std::unique_ptr<Directory>* result) override {
58     PERF_TIMER_GUARD(env_new_directory_nanos);
59     return EnvWrapper::NewDirectory(name, result);
60   }
61 
FileExists(const std::string & fname)62   Status FileExists(const std::string& fname) override {
63     PERF_TIMER_GUARD(env_file_exists_nanos);
64     return EnvWrapper::FileExists(fname);
65   }
66 
GetChildren(const std::string & dir,std::vector<std::string> * result)67   Status GetChildren(const std::string& dir,
68                      std::vector<std::string>* result) override {
69     PERF_TIMER_GUARD(env_get_children_nanos);
70     return EnvWrapper::GetChildren(dir, result);
71   }
72 
GetChildrenFileAttributes(const std::string & dir,std::vector<FileAttributes> * result)73   Status GetChildrenFileAttributes(
74       const std::string& dir, std::vector<FileAttributes>* result) override {
75     PERF_TIMER_GUARD(env_get_children_file_attributes_nanos);
76     return EnvWrapper::GetChildrenFileAttributes(dir, result);
77   }
78 
DeleteFile(const std::string & fname)79   Status DeleteFile(const std::string& fname) override {
80     PERF_TIMER_GUARD(env_delete_file_nanos);
81     return EnvWrapper::DeleteFile(fname);
82   }
83 
CreateDir(const std::string & dirname)84   Status CreateDir(const std::string& dirname) override {
85     PERF_TIMER_GUARD(env_create_dir_nanos);
86     return EnvWrapper::CreateDir(dirname);
87   }
88 
CreateDirIfMissing(const std::string & dirname)89   Status CreateDirIfMissing(const std::string& dirname) override {
90     PERF_TIMER_GUARD(env_create_dir_if_missing_nanos);
91     return EnvWrapper::CreateDirIfMissing(dirname);
92   }
93 
DeleteDir(const std::string & dirname)94   Status DeleteDir(const std::string& dirname) override {
95     PERF_TIMER_GUARD(env_delete_dir_nanos);
96     return EnvWrapper::DeleteDir(dirname);
97   }
98 
GetFileSize(const std::string & fname,uint64_t * file_size)99   Status GetFileSize(const std::string& fname, uint64_t* file_size) override {
100     PERF_TIMER_GUARD(env_get_file_size_nanos);
101     return EnvWrapper::GetFileSize(fname, file_size);
102   }
103 
GetFileModificationTime(const std::string & fname,uint64_t * file_mtime)104   Status GetFileModificationTime(const std::string& fname,
105                                  uint64_t* file_mtime) override {
106     PERF_TIMER_GUARD(env_get_file_modification_time_nanos);
107     return EnvWrapper::GetFileModificationTime(fname, file_mtime);
108   }
109 
RenameFile(const std::string & src,const std::string & dst)110   Status RenameFile(const std::string& src, const std::string& dst) override {
111     PERF_TIMER_GUARD(env_rename_file_nanos);
112     return EnvWrapper::RenameFile(src, dst);
113   }
114 
LinkFile(const std::string & src,const std::string & dst)115   Status LinkFile(const std::string& src, const std::string& dst) override {
116     PERF_TIMER_GUARD(env_link_file_nanos);
117     return EnvWrapper::LinkFile(src, dst);
118   }
119 
LockFile(const std::string & fname,FileLock ** lock)120   Status LockFile(const std::string& fname, FileLock** lock) override {
121     PERF_TIMER_GUARD(env_lock_file_nanos);
122     return EnvWrapper::LockFile(fname, lock);
123   }
124 
UnlockFile(FileLock * lock)125   Status UnlockFile(FileLock* lock) override {
126     PERF_TIMER_GUARD(env_unlock_file_nanos);
127     return EnvWrapper::UnlockFile(lock);
128   }
129 
NewLogger(const std::string & fname,std::shared_ptr<Logger> * result)130   Status NewLogger(const std::string& fname,
131                    std::shared_ptr<Logger>* result) override {
132     PERF_TIMER_GUARD(env_new_logger_nanos);
133     return EnvWrapper::NewLogger(fname, result);
134   }
135 };
136 
NewTimedEnv(Env * base_env)137 Env* NewTimedEnv(Env* base_env) { return new TimedEnv(base_env); }
138 
139 #else  // ROCKSDB_LITE
140 
141 Env* NewTimedEnv(Env* /*base_env*/) { return nullptr; }
142 
143 #endif  // !ROCKSDB_LITE
144 
145 }  // namespace ROCKSDB_NAMESPACE
146