1 //  Copyright (c) 2011-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 
7 #include <sstream>
8 #include "monitoring/perf_context_imp.h"
9 
10 namespace ROCKSDB_NAMESPACE {
11 
12 #if defined(NPERF_CONTEXT) || !defined(ROCKSDB_SUPPORT_THREAD_LOCAL)
13 PerfContext perf_context;
14 #else
15 #if defined(OS_SOLARIS)
16 __thread PerfContext perf_context_;
17 #else
18 thread_local PerfContext perf_context;
19 #endif
20 #endif
21 
get_perf_context()22 PerfContext* get_perf_context() {
23 #if defined(NPERF_CONTEXT) || !defined(ROCKSDB_SUPPORT_THREAD_LOCAL)
24   return &perf_context;
25 #else
26 #if defined(OS_SOLARIS)
27   return &perf_context_;
28 #else
29   return &perf_context;
30 #endif
31 #endif
32 }
33 
~PerfContext()34 PerfContext::~PerfContext() {
35 #if !defined(NPERF_CONTEXT) && defined(ROCKSDB_SUPPORT_THREAD_LOCAL) && !defined(OS_SOLARIS)
36   ClearPerLevelPerfContext();
37 #endif
38 }
39 
PerfContext(const PerfContext & other)40 PerfContext::PerfContext(const PerfContext& other) {
41 #ifndef NPERF_CONTEXT
42   user_key_comparison_count = other.user_key_comparison_count;
43   block_cache_hit_count = other.block_cache_hit_count;
44   block_read_count = other.block_read_count;
45   block_read_byte = other.block_read_byte;
46   block_read_time = other.block_read_time;
47   block_cache_index_hit_count = other.block_cache_index_hit_count;
48   index_block_read_count = other.index_block_read_count;
49   block_cache_filter_hit_count = other.block_cache_filter_hit_count;
50   filter_block_read_count = other.filter_block_read_count;
51   compression_dict_block_read_count = other.compression_dict_block_read_count;
52   block_checksum_time = other.block_checksum_time;
53   block_decompress_time = other.block_decompress_time;
54   get_read_bytes = other.get_read_bytes;
55   multiget_read_bytes = other.multiget_read_bytes;
56   iter_read_bytes = other.iter_read_bytes;
57   internal_key_skipped_count = other.internal_key_skipped_count;
58   internal_delete_skipped_count = other.internal_delete_skipped_count;
59   internal_recent_skipped_count = other.internal_recent_skipped_count;
60   internal_merge_count = other.internal_merge_count;
61   write_wal_time = other.write_wal_time;
62   get_snapshot_time = other.get_snapshot_time;
63   get_from_memtable_time = other.get_from_memtable_time;
64   get_from_memtable_count = other.get_from_memtable_count;
65   get_post_process_time = other.get_post_process_time;
66   get_from_output_files_time = other.get_from_output_files_time;
67   seek_on_memtable_time = other.seek_on_memtable_time;
68   seek_on_memtable_count = other.seek_on_memtable_count;
69   next_on_memtable_count = other.next_on_memtable_count;
70   prev_on_memtable_count = other.prev_on_memtable_count;
71   seek_child_seek_time = other.seek_child_seek_time;
72   seek_child_seek_count = other.seek_child_seek_count;
73   seek_min_heap_time = other.seek_min_heap_time;
74   seek_internal_seek_time = other.seek_internal_seek_time;
75   find_next_user_entry_time = other.find_next_user_entry_time;
76   write_pre_and_post_process_time = other.write_pre_and_post_process_time;
77   write_memtable_time = other.write_memtable_time;
78   write_delay_time = other.write_delay_time;
79   write_thread_wait_nanos = other.write_thread_wait_nanos;
80   write_scheduling_flushes_compactions_time =
81       other.write_scheduling_flushes_compactions_time;
82   db_mutex_lock_nanos = other.db_mutex_lock_nanos;
83   db_condition_wait_nanos = other.db_condition_wait_nanos;
84   merge_operator_time_nanos = other.merge_operator_time_nanos;
85   read_index_block_nanos = other.read_index_block_nanos;
86   read_filter_block_nanos = other.read_filter_block_nanos;
87   new_table_block_iter_nanos = other.new_table_block_iter_nanos;
88   new_table_iterator_nanos = other.new_table_iterator_nanos;
89   block_seek_nanos = other.block_seek_nanos;
90   find_table_nanos = other.find_table_nanos;
91   bloom_memtable_hit_count = other.bloom_memtable_hit_count;
92   bloom_memtable_miss_count = other.bloom_memtable_miss_count;
93   bloom_sst_hit_count = other.bloom_sst_hit_count;
94   bloom_sst_miss_count = other.bloom_sst_miss_count;
95   key_lock_wait_time = other.key_lock_wait_time;
96   key_lock_wait_count = other.key_lock_wait_count;
97 
98   env_new_sequential_file_nanos = other.env_new_sequential_file_nanos;
99   env_new_random_access_file_nanos = other.env_new_random_access_file_nanos;
100   env_new_writable_file_nanos = other.env_new_writable_file_nanos;
101   env_reuse_writable_file_nanos = other.env_reuse_writable_file_nanos;
102   env_new_random_rw_file_nanos = other.env_new_random_rw_file_nanos;
103   env_new_directory_nanos = other.env_new_directory_nanos;
104   env_file_exists_nanos = other.env_file_exists_nanos;
105   env_get_children_nanos = other.env_get_children_nanos;
106   env_get_children_file_attributes_nanos =
107       other.env_get_children_file_attributes_nanos;
108   env_delete_file_nanos = other.env_delete_file_nanos;
109   env_create_dir_nanos = other.env_create_dir_nanos;
110   env_create_dir_if_missing_nanos = other.env_create_dir_if_missing_nanos;
111   env_delete_dir_nanos = other.env_delete_dir_nanos;
112   env_get_file_size_nanos = other.env_get_file_size_nanos;
113   env_get_file_modification_time_nanos =
114       other.env_get_file_modification_time_nanos;
115   env_rename_file_nanos = other.env_rename_file_nanos;
116   env_link_file_nanos = other.env_link_file_nanos;
117   env_lock_file_nanos = other.env_lock_file_nanos;
118   env_unlock_file_nanos = other.env_unlock_file_nanos;
119   env_new_logger_nanos = other.env_new_logger_nanos;
120   get_cpu_nanos = other.get_cpu_nanos;
121   iter_next_cpu_nanos = other.iter_next_cpu_nanos;
122   iter_prev_cpu_nanos = other.iter_prev_cpu_nanos;
123   iter_seek_cpu_nanos = other.iter_seek_cpu_nanos;
124   if (per_level_perf_context_enabled && level_to_perf_context != nullptr) {
125     ClearPerLevelPerfContext();
126   }
127   if (other.level_to_perf_context != nullptr) {
128     level_to_perf_context = new std::map<uint32_t, PerfContextByLevel>();
129     *level_to_perf_context = *other.level_to_perf_context;
130   }
131   per_level_perf_context_enabled = other.per_level_perf_context_enabled;
132 #endif
133 }
134 
PerfContext(PerfContext && other)135 PerfContext::PerfContext(PerfContext&& other) noexcept {
136 #ifndef NPERF_CONTEXT
137   user_key_comparison_count = other.user_key_comparison_count;
138   block_cache_hit_count = other.block_cache_hit_count;
139   block_read_count = other.block_read_count;
140   block_read_byte = other.block_read_byte;
141   block_read_time = other.block_read_time;
142   block_cache_index_hit_count = other.block_cache_index_hit_count;
143   index_block_read_count = other.index_block_read_count;
144   block_cache_filter_hit_count = other.block_cache_filter_hit_count;
145   filter_block_read_count = other.filter_block_read_count;
146   compression_dict_block_read_count = other.compression_dict_block_read_count;
147   block_checksum_time = other.block_checksum_time;
148   block_decompress_time = other.block_decompress_time;
149   get_read_bytes = other.get_read_bytes;
150   multiget_read_bytes = other.multiget_read_bytes;
151   iter_read_bytes = other.iter_read_bytes;
152   internal_key_skipped_count = other.internal_key_skipped_count;
153   internal_delete_skipped_count = other.internal_delete_skipped_count;
154   internal_recent_skipped_count = other.internal_recent_skipped_count;
155   internal_merge_count = other.internal_merge_count;
156   write_wal_time = other.write_wal_time;
157   get_snapshot_time = other.get_snapshot_time;
158   get_from_memtable_time = other.get_from_memtable_time;
159   get_from_memtable_count = other.get_from_memtable_count;
160   get_post_process_time = other.get_post_process_time;
161   get_from_output_files_time = other.get_from_output_files_time;
162   seek_on_memtable_time = other.seek_on_memtable_time;
163   seek_on_memtable_count = other.seek_on_memtable_count;
164   next_on_memtable_count = other.next_on_memtable_count;
165   prev_on_memtable_count = other.prev_on_memtable_count;
166   seek_child_seek_time = other.seek_child_seek_time;
167   seek_child_seek_count = other.seek_child_seek_count;
168   seek_min_heap_time = other.seek_min_heap_time;
169   seek_internal_seek_time = other.seek_internal_seek_time;
170   find_next_user_entry_time = other.find_next_user_entry_time;
171   write_pre_and_post_process_time = other.write_pre_and_post_process_time;
172   write_memtable_time = other.write_memtable_time;
173   write_delay_time = other.write_delay_time;
174   write_thread_wait_nanos = other.write_thread_wait_nanos;
175   write_scheduling_flushes_compactions_time =
176       other.write_scheduling_flushes_compactions_time;
177   db_mutex_lock_nanos = other.db_mutex_lock_nanos;
178   db_condition_wait_nanos = other.db_condition_wait_nanos;
179   merge_operator_time_nanos = other.merge_operator_time_nanos;
180   read_index_block_nanos = other.read_index_block_nanos;
181   read_filter_block_nanos = other.read_filter_block_nanos;
182   new_table_block_iter_nanos = other.new_table_block_iter_nanos;
183   new_table_iterator_nanos = other.new_table_iterator_nanos;
184   block_seek_nanos = other.block_seek_nanos;
185   find_table_nanos = other.find_table_nanos;
186   bloom_memtable_hit_count = other.bloom_memtable_hit_count;
187   bloom_memtable_miss_count = other.bloom_memtable_miss_count;
188   bloom_sst_hit_count = other.bloom_sst_hit_count;
189   bloom_sst_miss_count = other.bloom_sst_miss_count;
190   key_lock_wait_time = other.key_lock_wait_time;
191   key_lock_wait_count = other.key_lock_wait_count;
192 
193   env_new_sequential_file_nanos = other.env_new_sequential_file_nanos;
194   env_new_random_access_file_nanos = other.env_new_random_access_file_nanos;
195   env_new_writable_file_nanos = other.env_new_writable_file_nanos;
196   env_reuse_writable_file_nanos = other.env_reuse_writable_file_nanos;
197   env_new_random_rw_file_nanos = other.env_new_random_rw_file_nanos;
198   env_new_directory_nanos = other.env_new_directory_nanos;
199   env_file_exists_nanos = other.env_file_exists_nanos;
200   env_get_children_nanos = other.env_get_children_nanos;
201   env_get_children_file_attributes_nanos =
202       other.env_get_children_file_attributes_nanos;
203   env_delete_file_nanos = other.env_delete_file_nanos;
204   env_create_dir_nanos = other.env_create_dir_nanos;
205   env_create_dir_if_missing_nanos = other.env_create_dir_if_missing_nanos;
206   env_delete_dir_nanos = other.env_delete_dir_nanos;
207   env_get_file_size_nanos = other.env_get_file_size_nanos;
208   env_get_file_modification_time_nanos =
209       other.env_get_file_modification_time_nanos;
210   env_rename_file_nanos = other.env_rename_file_nanos;
211   env_link_file_nanos = other.env_link_file_nanos;
212   env_lock_file_nanos = other.env_lock_file_nanos;
213   env_unlock_file_nanos = other.env_unlock_file_nanos;
214   env_new_logger_nanos = other.env_new_logger_nanos;
215   get_cpu_nanos = other.get_cpu_nanos;
216   iter_next_cpu_nanos = other.iter_next_cpu_nanos;
217   iter_prev_cpu_nanos = other.iter_prev_cpu_nanos;
218   iter_seek_cpu_nanos = other.iter_seek_cpu_nanos;
219   if (per_level_perf_context_enabled && level_to_perf_context != nullptr) {
220     ClearPerLevelPerfContext();
221   }
222   if (other.level_to_perf_context != nullptr) {
223     level_to_perf_context = other.level_to_perf_context;
224     other.level_to_perf_context = nullptr;
225   }
226   per_level_perf_context_enabled = other.per_level_perf_context_enabled;
227 #endif
228 }
229 
230 // TODO(Zhongyi): reduce code duplication between copy constructor and
231 // assignment operator
operator =(const PerfContext & other)232 PerfContext& PerfContext::operator=(const PerfContext& other) {
233 #ifndef NPERF_CONTEXT
234   user_key_comparison_count = other.user_key_comparison_count;
235   block_cache_hit_count = other.block_cache_hit_count;
236   block_read_count = other.block_read_count;
237   block_read_byte = other.block_read_byte;
238   block_read_time = other.block_read_time;
239   block_cache_index_hit_count = other.block_cache_index_hit_count;
240   index_block_read_count = other.index_block_read_count;
241   block_cache_filter_hit_count = other.block_cache_filter_hit_count;
242   filter_block_read_count = other.filter_block_read_count;
243   compression_dict_block_read_count = other.compression_dict_block_read_count;
244   block_checksum_time = other.block_checksum_time;
245   block_decompress_time = other.block_decompress_time;
246   get_read_bytes = other.get_read_bytes;
247   multiget_read_bytes = other.multiget_read_bytes;
248   iter_read_bytes = other.iter_read_bytes;
249   internal_key_skipped_count = other.internal_key_skipped_count;
250   internal_delete_skipped_count = other.internal_delete_skipped_count;
251   internal_recent_skipped_count = other.internal_recent_skipped_count;
252   internal_merge_count = other.internal_merge_count;
253   write_wal_time = other.write_wal_time;
254   get_snapshot_time = other.get_snapshot_time;
255   get_from_memtable_time = other.get_from_memtable_time;
256   get_from_memtable_count = other.get_from_memtable_count;
257   get_post_process_time = other.get_post_process_time;
258   get_from_output_files_time = other.get_from_output_files_time;
259   seek_on_memtable_time = other.seek_on_memtable_time;
260   seek_on_memtable_count = other.seek_on_memtable_count;
261   next_on_memtable_count = other.next_on_memtable_count;
262   prev_on_memtable_count = other.prev_on_memtable_count;
263   seek_child_seek_time = other.seek_child_seek_time;
264   seek_child_seek_count = other.seek_child_seek_count;
265   seek_min_heap_time = other.seek_min_heap_time;
266   seek_internal_seek_time = other.seek_internal_seek_time;
267   find_next_user_entry_time = other.find_next_user_entry_time;
268   write_pre_and_post_process_time = other.write_pre_and_post_process_time;
269   write_memtable_time = other.write_memtable_time;
270   write_delay_time = other.write_delay_time;
271   write_thread_wait_nanos = other.write_thread_wait_nanos;
272   write_scheduling_flushes_compactions_time =
273       other.write_scheduling_flushes_compactions_time;
274   db_mutex_lock_nanos = other.db_mutex_lock_nanos;
275   db_condition_wait_nanos = other.db_condition_wait_nanos;
276   merge_operator_time_nanos = other.merge_operator_time_nanos;
277   read_index_block_nanos = other.read_index_block_nanos;
278   read_filter_block_nanos = other.read_filter_block_nanos;
279   new_table_block_iter_nanos = other.new_table_block_iter_nanos;
280   new_table_iterator_nanos = other.new_table_iterator_nanos;
281   block_seek_nanos = other.block_seek_nanos;
282   find_table_nanos = other.find_table_nanos;
283   bloom_memtable_hit_count = other.bloom_memtable_hit_count;
284   bloom_memtable_miss_count = other.bloom_memtable_miss_count;
285   bloom_sst_hit_count = other.bloom_sst_hit_count;
286   bloom_sst_miss_count = other.bloom_sst_miss_count;
287   key_lock_wait_time = other.key_lock_wait_time;
288   key_lock_wait_count = other.key_lock_wait_count;
289 
290   env_new_sequential_file_nanos = other.env_new_sequential_file_nanos;
291   env_new_random_access_file_nanos = other.env_new_random_access_file_nanos;
292   env_new_writable_file_nanos = other.env_new_writable_file_nanos;
293   env_reuse_writable_file_nanos = other.env_reuse_writable_file_nanos;
294   env_new_random_rw_file_nanos = other.env_new_random_rw_file_nanos;
295   env_new_directory_nanos = other.env_new_directory_nanos;
296   env_file_exists_nanos = other.env_file_exists_nanos;
297   env_get_children_nanos = other.env_get_children_nanos;
298   env_get_children_file_attributes_nanos =
299       other.env_get_children_file_attributes_nanos;
300   env_delete_file_nanos = other.env_delete_file_nanos;
301   env_create_dir_nanos = other.env_create_dir_nanos;
302   env_create_dir_if_missing_nanos = other.env_create_dir_if_missing_nanos;
303   env_delete_dir_nanos = other.env_delete_dir_nanos;
304   env_get_file_size_nanos = other.env_get_file_size_nanos;
305   env_get_file_modification_time_nanos =
306       other.env_get_file_modification_time_nanos;
307   env_rename_file_nanos = other.env_rename_file_nanos;
308   env_link_file_nanos = other.env_link_file_nanos;
309   env_lock_file_nanos = other.env_lock_file_nanos;
310   env_unlock_file_nanos = other.env_unlock_file_nanos;
311   env_new_logger_nanos = other.env_new_logger_nanos;
312   get_cpu_nanos = other.get_cpu_nanos;
313   iter_next_cpu_nanos = other.iter_next_cpu_nanos;
314   iter_prev_cpu_nanos = other.iter_prev_cpu_nanos;
315   iter_seek_cpu_nanos = other.iter_seek_cpu_nanos;
316   if (per_level_perf_context_enabled && level_to_perf_context != nullptr) {
317     ClearPerLevelPerfContext();
318   }
319   if (other.level_to_perf_context != nullptr) {
320     level_to_perf_context = new std::map<uint32_t, PerfContextByLevel>();
321     *level_to_perf_context = *other.level_to_perf_context;
322   }
323   per_level_perf_context_enabled = other.per_level_perf_context_enabled;
324 #endif
325   return *this;
326 }
327 
Reset()328 void PerfContext::Reset() {
329 #ifndef NPERF_CONTEXT
330   user_key_comparison_count = 0;
331   block_cache_hit_count = 0;
332   block_read_count = 0;
333   block_read_byte = 0;
334   block_read_time = 0;
335   block_cache_index_hit_count = 0;
336   index_block_read_count = 0;
337   block_cache_filter_hit_count = 0;
338   filter_block_read_count = 0;
339   compression_dict_block_read_count = 0;
340   block_checksum_time = 0;
341   block_decompress_time = 0;
342   get_read_bytes = 0;
343   multiget_read_bytes = 0;
344   iter_read_bytes = 0;
345   internal_key_skipped_count = 0;
346   internal_delete_skipped_count = 0;
347   internal_recent_skipped_count = 0;
348   internal_merge_count = 0;
349   write_wal_time = 0;
350 
351   get_snapshot_time = 0;
352   get_from_memtable_time = 0;
353   get_from_memtable_count = 0;
354   get_post_process_time = 0;
355   get_from_output_files_time = 0;
356   seek_on_memtable_time = 0;
357   seek_on_memtable_count = 0;
358   next_on_memtable_count = 0;
359   prev_on_memtable_count = 0;
360   seek_child_seek_time = 0;
361   seek_child_seek_count = 0;
362   seek_min_heap_time = 0;
363   seek_internal_seek_time = 0;
364   find_next_user_entry_time = 0;
365   write_pre_and_post_process_time = 0;
366   write_memtable_time = 0;
367   write_delay_time = 0;
368   write_thread_wait_nanos = 0;
369   write_scheduling_flushes_compactions_time = 0;
370   db_mutex_lock_nanos = 0;
371   db_condition_wait_nanos = 0;
372   merge_operator_time_nanos = 0;
373   read_index_block_nanos = 0;
374   read_filter_block_nanos = 0;
375   new_table_block_iter_nanos = 0;
376   new_table_iterator_nanos = 0;
377   block_seek_nanos = 0;
378   find_table_nanos = 0;
379   bloom_memtable_hit_count = 0;
380   bloom_memtable_miss_count = 0;
381   bloom_sst_hit_count = 0;
382   bloom_sst_miss_count = 0;
383   key_lock_wait_time = 0;
384   key_lock_wait_count = 0;
385 
386   env_new_sequential_file_nanos = 0;
387   env_new_random_access_file_nanos = 0;
388   env_new_writable_file_nanos = 0;
389   env_reuse_writable_file_nanos = 0;
390   env_new_random_rw_file_nanos = 0;
391   env_new_directory_nanos = 0;
392   env_file_exists_nanos = 0;
393   env_get_children_nanos = 0;
394   env_get_children_file_attributes_nanos = 0;
395   env_delete_file_nanos = 0;
396   env_create_dir_nanos = 0;
397   env_create_dir_if_missing_nanos = 0;
398   env_delete_dir_nanos = 0;
399   env_get_file_size_nanos = 0;
400   env_get_file_modification_time_nanos = 0;
401   env_rename_file_nanos = 0;
402   env_link_file_nanos = 0;
403   env_lock_file_nanos = 0;
404   env_unlock_file_nanos = 0;
405   env_new_logger_nanos = 0;
406   get_cpu_nanos = 0;
407   iter_next_cpu_nanos = 0;
408   iter_prev_cpu_nanos = 0;
409   iter_seek_cpu_nanos = 0;
410   if (per_level_perf_context_enabled && level_to_perf_context) {
411     for (auto& kv : *level_to_perf_context) {
412       kv.second.Reset();
413     }
414   }
415 #endif
416 }
417 
418 #define PERF_CONTEXT_OUTPUT(counter)             \
419   if (!exclude_zero_counters || (counter > 0)) { \
420     ss << #counter << " = " << counter << ", ";  \
421   }
422 
423 #define PERF_CONTEXT_BY_LEVEL_OUTPUT_ONE_COUNTER(counter)         \
424   if (per_level_perf_context_enabled && \
425       level_to_perf_context) {                                    \
426     ss << #counter << " = ";                                      \
427     for (auto& kv : *level_to_perf_context) {                     \
428       if (!exclude_zero_counters || (kv.second.counter > 0)) {    \
429         ss << kv.second.counter << "@level" << kv.first << ", ";  \
430       }                                                           \
431     }                                                             \
432   }
433 
Reset()434 void PerfContextByLevel::Reset() {
435 #ifndef NPERF_CONTEXT
436   bloom_filter_useful = 0;
437   bloom_filter_full_positive = 0;
438   bloom_filter_full_true_positive = 0;
439   block_cache_hit_count = 0;
440   block_cache_miss_count = 0;
441 #endif
442 }
443 
ToString(bool exclude_zero_counters) const444 std::string PerfContext::ToString(bool exclude_zero_counters) const {
445 #ifdef NPERF_CONTEXT
446   return "";
447 #else
448   std::ostringstream ss;
449   PERF_CONTEXT_OUTPUT(user_key_comparison_count);
450   PERF_CONTEXT_OUTPUT(block_cache_hit_count);
451   PERF_CONTEXT_OUTPUT(block_read_count);
452   PERF_CONTEXT_OUTPUT(block_read_byte);
453   PERF_CONTEXT_OUTPUT(block_read_time);
454   PERF_CONTEXT_OUTPUT(block_cache_index_hit_count);
455   PERF_CONTEXT_OUTPUT(index_block_read_count);
456   PERF_CONTEXT_OUTPUT(block_cache_filter_hit_count);
457   PERF_CONTEXT_OUTPUT(filter_block_read_count);
458   PERF_CONTEXT_OUTPUT(compression_dict_block_read_count);
459   PERF_CONTEXT_OUTPUT(block_checksum_time);
460   PERF_CONTEXT_OUTPUT(block_decompress_time);
461   PERF_CONTEXT_OUTPUT(get_read_bytes);
462   PERF_CONTEXT_OUTPUT(multiget_read_bytes);
463   PERF_CONTEXT_OUTPUT(iter_read_bytes);
464   PERF_CONTEXT_OUTPUT(internal_key_skipped_count);
465   PERF_CONTEXT_OUTPUT(internal_delete_skipped_count);
466   PERF_CONTEXT_OUTPUT(internal_recent_skipped_count);
467   PERF_CONTEXT_OUTPUT(internal_merge_count);
468   PERF_CONTEXT_OUTPUT(write_wal_time);
469   PERF_CONTEXT_OUTPUT(get_snapshot_time);
470   PERF_CONTEXT_OUTPUT(get_from_memtable_time);
471   PERF_CONTEXT_OUTPUT(get_from_memtable_count);
472   PERF_CONTEXT_OUTPUT(get_post_process_time);
473   PERF_CONTEXT_OUTPUT(get_from_output_files_time);
474   PERF_CONTEXT_OUTPUT(seek_on_memtable_time);
475   PERF_CONTEXT_OUTPUT(seek_on_memtable_count);
476   PERF_CONTEXT_OUTPUT(next_on_memtable_count);
477   PERF_CONTEXT_OUTPUT(prev_on_memtable_count);
478   PERF_CONTEXT_OUTPUT(seek_child_seek_time);
479   PERF_CONTEXT_OUTPUT(seek_child_seek_count);
480   PERF_CONTEXT_OUTPUT(seek_min_heap_time);
481   PERF_CONTEXT_OUTPUT(seek_internal_seek_time);
482   PERF_CONTEXT_OUTPUT(find_next_user_entry_time);
483   PERF_CONTEXT_OUTPUT(write_pre_and_post_process_time);
484   PERF_CONTEXT_OUTPUT(write_memtable_time);
485   PERF_CONTEXT_OUTPUT(write_thread_wait_nanos);
486   PERF_CONTEXT_OUTPUT(write_scheduling_flushes_compactions_time);
487   PERF_CONTEXT_OUTPUT(db_mutex_lock_nanos);
488   PERF_CONTEXT_OUTPUT(db_condition_wait_nanos);
489   PERF_CONTEXT_OUTPUT(merge_operator_time_nanos);
490   PERF_CONTEXT_OUTPUT(write_delay_time);
491   PERF_CONTEXT_OUTPUT(read_index_block_nanos);
492   PERF_CONTEXT_OUTPUT(read_filter_block_nanos);
493   PERF_CONTEXT_OUTPUT(new_table_block_iter_nanos);
494   PERF_CONTEXT_OUTPUT(new_table_iterator_nanos);
495   PERF_CONTEXT_OUTPUT(block_seek_nanos);
496   PERF_CONTEXT_OUTPUT(find_table_nanos);
497   PERF_CONTEXT_OUTPUT(bloom_memtable_hit_count);
498   PERF_CONTEXT_OUTPUT(bloom_memtable_miss_count);
499   PERF_CONTEXT_OUTPUT(bloom_sst_hit_count);
500   PERF_CONTEXT_OUTPUT(bloom_sst_miss_count);
501   PERF_CONTEXT_OUTPUT(key_lock_wait_time);
502   PERF_CONTEXT_OUTPUT(key_lock_wait_count);
503   PERF_CONTEXT_OUTPUT(env_new_sequential_file_nanos);
504   PERF_CONTEXT_OUTPUT(env_new_random_access_file_nanos);
505   PERF_CONTEXT_OUTPUT(env_new_writable_file_nanos);
506   PERF_CONTEXT_OUTPUT(env_reuse_writable_file_nanos);
507   PERF_CONTEXT_OUTPUT(env_new_random_rw_file_nanos);
508   PERF_CONTEXT_OUTPUT(env_new_directory_nanos);
509   PERF_CONTEXT_OUTPUT(env_file_exists_nanos);
510   PERF_CONTEXT_OUTPUT(env_get_children_nanos);
511   PERF_CONTEXT_OUTPUT(env_get_children_file_attributes_nanos);
512   PERF_CONTEXT_OUTPUT(env_delete_file_nanos);
513   PERF_CONTEXT_OUTPUT(env_create_dir_nanos);
514   PERF_CONTEXT_OUTPUT(env_create_dir_if_missing_nanos);
515   PERF_CONTEXT_OUTPUT(env_delete_dir_nanos);
516   PERF_CONTEXT_OUTPUT(env_get_file_size_nanos);
517   PERF_CONTEXT_OUTPUT(env_get_file_modification_time_nanos);
518   PERF_CONTEXT_OUTPUT(env_rename_file_nanos);
519   PERF_CONTEXT_OUTPUT(env_link_file_nanos);
520   PERF_CONTEXT_OUTPUT(env_lock_file_nanos);
521   PERF_CONTEXT_OUTPUT(env_unlock_file_nanos);
522   PERF_CONTEXT_OUTPUT(env_new_logger_nanos);
523   PERF_CONTEXT_OUTPUT(get_cpu_nanos);
524   PERF_CONTEXT_OUTPUT(iter_next_cpu_nanos);
525   PERF_CONTEXT_OUTPUT(iter_prev_cpu_nanos);
526   PERF_CONTEXT_OUTPUT(iter_seek_cpu_nanos);
527   PERF_CONTEXT_BY_LEVEL_OUTPUT_ONE_COUNTER(bloom_filter_useful);
528   PERF_CONTEXT_BY_LEVEL_OUTPUT_ONE_COUNTER(bloom_filter_full_positive);
529   PERF_CONTEXT_BY_LEVEL_OUTPUT_ONE_COUNTER(bloom_filter_full_true_positive);
530   PERF_CONTEXT_BY_LEVEL_OUTPUT_ONE_COUNTER(block_cache_hit_count);
531   PERF_CONTEXT_BY_LEVEL_OUTPUT_ONE_COUNTER(block_cache_miss_count);
532 
533   std::string str = ss.str();
534   str.erase(str.find_last_not_of(", ") + 1);
535   return str;
536 #endif
537 }
538 
EnablePerLevelPerfContext()539 void PerfContext::EnablePerLevelPerfContext() {
540   if (level_to_perf_context == nullptr) {
541     level_to_perf_context = new std::map<uint32_t, PerfContextByLevel>();
542   }
543   per_level_perf_context_enabled = true;
544 }
545 
DisablePerLevelPerfContext()546 void PerfContext::DisablePerLevelPerfContext(){
547   per_level_perf_context_enabled = false;
548 }
549 
ClearPerLevelPerfContext()550 void PerfContext::ClearPerLevelPerfContext(){
551   if (level_to_perf_context != nullptr) {
552     level_to_perf_context->clear();
553     delete level_to_perf_context;
554     level_to_perf_context = nullptr;
555   }
556   per_level_perf_context_enabled = false;
557 }
558 
559 }  // namespace ROCKSDB_NAMESPACE
560