/src/rocksdb/utilities/counted_fs.h
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) 2016-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 | | #pragma once |
7 | | |
8 | | #include <atomic> |
9 | | #include <memory> |
10 | | |
11 | | #include "rocksdb/file_system.h" |
12 | | #include "rocksdb/io_status.h" |
13 | | #include "rocksdb/rocksdb_namespace.h" |
14 | | |
15 | | namespace ROCKSDB_NAMESPACE { |
16 | | class Logger; |
17 | | |
18 | | struct OpCounter { |
19 | | std::atomic<int> ops; |
20 | | std::atomic<uint64_t> bytes; |
21 | | |
22 | 0 | OpCounter() : ops(0), bytes(0) {} |
23 | | |
24 | 0 | void Reset() { |
25 | 0 | ops = 0; |
26 | 0 | bytes = 0; |
27 | 0 | } |
28 | 0 | void RecordOp(const IOStatus& io_s, size_t added_bytes) { |
29 | 0 | if (!io_s.IsNotSupported()) { |
30 | 0 | ops.fetch_add(1, std::memory_order_relaxed); |
31 | 0 | } |
32 | 0 | if (io_s.ok()) { |
33 | 0 | bytes.fetch_add(added_bytes, std::memory_order_relaxed); |
34 | 0 | } |
35 | 0 | } |
36 | | }; |
37 | | |
38 | | struct FileOpCounters { |
39 | 0 | static const char* kName() { return "FileOpCounters"; } |
40 | | |
41 | | std::atomic<int> opens; |
42 | | std::atomic<int> closes; |
43 | | std::atomic<int> deletes; |
44 | | std::atomic<int> renames; |
45 | | std::atomic<int> flushes; |
46 | | std::atomic<int> syncs; |
47 | | std::atomic<int> dsyncs; |
48 | | std::atomic<int> fsyncs; |
49 | | std::atomic<int> dir_opens; |
50 | | std::atomic<int> dir_closes; |
51 | | OpCounter reads; |
52 | | OpCounter writes; |
53 | | |
54 | | FileOpCounters() |
55 | | : opens(0), |
56 | | closes(0), |
57 | | deletes(0), |
58 | | renames(0), |
59 | | flushes(0), |
60 | | syncs(0), |
61 | | dsyncs(0), |
62 | | fsyncs(0), |
63 | | dir_opens(0), |
64 | 0 | dir_closes(0) {} |
65 | | |
66 | 0 | void Reset() { |
67 | 0 | opens = 0; |
68 | 0 | closes = 0; |
69 | 0 | deletes = 0; |
70 | 0 | renames = 0; |
71 | 0 | flushes = 0; |
72 | 0 | syncs = 0; |
73 | 0 | dsyncs = 0; |
74 | 0 | fsyncs = 0; |
75 | 0 | dir_opens = 0; |
76 | 0 | dir_closes = 0; |
77 | 0 | reads.Reset(); |
78 | 0 | writes.Reset(); |
79 | 0 | } |
80 | | std::string PrintCounters() const; |
81 | | }; |
82 | | |
83 | | // A FileSystem class that counts operations (reads, writes, opens, closes, etc) |
84 | | class CountedFileSystem : public FileSystemWrapper { |
85 | | public: |
86 | | private: |
87 | | FileOpCounters counters_; |
88 | | |
89 | | public: |
90 | | explicit CountedFileSystem(const std::shared_ptr<FileSystem>& base); |
91 | 0 | static const char* kClassName() { return "CountedFileSystem"; } |
92 | 0 | const char* Name() const override { return kClassName(); } |
93 | | |
94 | | IOStatus NewSequentialFile(const std::string& f, const FileOptions& options, |
95 | | std::unique_ptr<FSSequentialFile>* r, |
96 | | IODebugContext* dbg) override; |
97 | | |
98 | | IOStatus NewRandomAccessFile(const std::string& f, |
99 | | const FileOptions& file_opts, |
100 | | std::unique_ptr<FSRandomAccessFile>* r, |
101 | | IODebugContext* dbg) override; |
102 | | |
103 | | IOStatus NewWritableFile(const std::string& f, const FileOptions& options, |
104 | | std::unique_ptr<FSWritableFile>* r, |
105 | | IODebugContext* dbg) override; |
106 | | IOStatus ReopenWritableFile(const std::string& fname, |
107 | | const FileOptions& options, |
108 | | std::unique_ptr<FSWritableFile>* result, |
109 | | IODebugContext* dbg) override; |
110 | | |
111 | | IOStatus ReuseWritableFile(const std::string& fname, |
112 | | const std::string& old_fname, |
113 | | const FileOptions& file_opts, |
114 | | std::unique_ptr<FSWritableFile>* result, |
115 | | IODebugContext* dbg) override; |
116 | | IOStatus NewRandomRWFile(const std::string& name, const FileOptions& options, |
117 | | std::unique_ptr<FSRandomRWFile>* result, |
118 | | IODebugContext* dbg) override; |
119 | | |
120 | | IOStatus NewDirectory(const std::string& name, const IOOptions& io_opts, |
121 | | std::unique_ptr<FSDirectory>* result, |
122 | | IODebugContext* dbg) override; |
123 | | |
124 | | IOStatus DeleteFile(const std::string& fname, const IOOptions& options, |
125 | 0 | IODebugContext* dbg) override { |
126 | 0 | IOStatus s = target()->DeleteFile(fname, options, dbg); |
127 | 0 | if (s.ok()) { |
128 | 0 | counters_.deletes++; |
129 | 0 | } |
130 | 0 | return s; |
131 | 0 | } |
132 | | |
133 | | IOStatus RenameFile(const std::string& s, const std::string& t, |
134 | 0 | const IOOptions& options, IODebugContext* dbg) override { |
135 | 0 | IOStatus st = target()->RenameFile(s, t, options, dbg); |
136 | 0 | if (st.ok()) { |
137 | 0 | counters_.renames++; |
138 | 0 | } |
139 | 0 | return st; |
140 | 0 | } |
141 | | |
142 | 0 | const FileOpCounters* counters() const { return &counters_; } |
143 | | |
144 | 0 | FileOpCounters* counters() { return &counters_; } |
145 | | |
146 | 0 | const void* GetOptionsPtr(const std::string& name) const override { |
147 | 0 | if (name == FileOpCounters::kName()) { |
148 | 0 | return counters(); |
149 | 0 | } else { |
150 | 0 | return FileSystemWrapper::GetOptionsPtr(name); |
151 | 0 | } |
152 | 0 | } |
153 | | |
154 | | // Prints the counters to a string |
155 | 0 | std::string PrintCounters() const { return counters_.PrintCounters(); } |
156 | 0 | void ResetCounters() { counters_.Reset(); } |
157 | | }; |
158 | | } // namespace ROCKSDB_NAMESPACE |