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 
9 #include "rocksdb/env.h"
10 #include "rocksdb/thread_status.h"
11 #include "util/string_util.h"
12 #include "util/thread_operation.h"
13 
14 namespace ROCKSDB_NAMESPACE {
15 
16 #ifdef ROCKSDB_USING_THREAD_STATUS
GetThreadTypeName(ThreadStatus::ThreadType thread_type)17 std::string ThreadStatus::GetThreadTypeName(
18     ThreadStatus::ThreadType thread_type) {
19   switch (thread_type) {
20     case ThreadStatus::ThreadType::HIGH_PRIORITY:
21       return "High Pri";
22     case ThreadStatus::ThreadType::LOW_PRIORITY:
23       return "Low Pri";
24     case ThreadStatus::ThreadType::USER:
25       return "User";
26     case ThreadStatus::ThreadType::BOTTOM_PRIORITY:
27       return "Bottom Pri";
28     case ThreadStatus::ThreadType::NUM_THREAD_TYPES:
29       assert(false);
30   }
31   return "Unknown";
32 }
33 
GetOperationName(ThreadStatus::OperationType op_type)34 const std::string& ThreadStatus::GetOperationName(
35     ThreadStatus::OperationType op_type) {
36   if (op_type < 0 || op_type >= NUM_OP_TYPES) {
37     return global_operation_table[OP_UNKNOWN].name;
38   }
39   return global_operation_table[op_type].name;
40 }
41 
GetOperationStageName(ThreadStatus::OperationStage stage)42 const std::string& ThreadStatus::GetOperationStageName(
43     ThreadStatus::OperationStage stage) {
44   if (stage < 0 || stage >= NUM_OP_STAGES) {
45     return global_op_stage_table[STAGE_UNKNOWN].name;
46   }
47   return global_op_stage_table[stage].name;
48 }
49 
GetStateName(ThreadStatus::StateType state_type)50 const std::string& ThreadStatus::GetStateName(
51     ThreadStatus::StateType state_type) {
52   if (state_type < 0 || state_type >= NUM_STATE_TYPES) {
53     return global_state_table[STATE_UNKNOWN].name;
54   }
55   return global_state_table[state_type].name;
56 }
57 
MicrosToString(uint64_t micros)58 const std::string ThreadStatus::MicrosToString(uint64_t micros) {
59   if (micros == 0) {
60     return "";
61   }
62   const int kBufferLen = 100;
63   char buffer[kBufferLen];
64   AppendHumanMicros(micros, buffer, kBufferLen, false);
65   return std::string(buffer);
66 }
67 
GetOperationPropertyName(ThreadStatus::OperationType op_type,int i)68 const std::string& ThreadStatus::GetOperationPropertyName(
69     ThreadStatus::OperationType op_type, int i) {
70   static const std::string empty_str = "";
71   switch (op_type) {
72     case ThreadStatus::OP_COMPACTION:
73       if (i >= NUM_COMPACTION_PROPERTIES) {
74         return empty_str;
75       }
76       return compaction_operation_properties[i].name;
77     case ThreadStatus::OP_FLUSH:
78       if (i >= NUM_FLUSH_PROPERTIES) {
79         return empty_str;
80       }
81       return flush_operation_properties[i].name;
82     default:
83       return empty_str;
84   }
85 }
86 
InterpretOperationProperties(ThreadStatus::OperationType op_type,const uint64_t * op_properties)87 std::map<std::string, uint64_t> ThreadStatus::InterpretOperationProperties(
88     ThreadStatus::OperationType op_type, const uint64_t* op_properties) {
89   int num_properties;
90   switch (op_type) {
91     case OP_COMPACTION:
92       num_properties = NUM_COMPACTION_PROPERTIES;
93       break;
94     case OP_FLUSH:
95       num_properties = NUM_FLUSH_PROPERTIES;
96       break;
97     default:
98       num_properties = 0;
99   }
100 
101   std::map<std::string, uint64_t> property_map;
102   for (int i = 0; i < num_properties; ++i) {
103     if (op_type == OP_COMPACTION && i == COMPACTION_INPUT_OUTPUT_LEVEL) {
104       property_map.insert({"BaseInputLevel", op_properties[i] >> 32});
105       property_map.insert(
106           {"OutputLevel", op_properties[i] % (uint64_t(1) << 32U)});
107     } else if (op_type == OP_COMPACTION && i == COMPACTION_PROP_FLAGS) {
108       property_map.insert({"IsManual", ((op_properties[i] & 2) >> 1)});
109       property_map.insert({"IsDeletion", ((op_properties[i] & 4) >> 2)});
110       property_map.insert({"IsTrivialMove", ((op_properties[i] & 8) >> 3)});
111     } else {
112       property_map.insert(
113           {GetOperationPropertyName(op_type, i), op_properties[i]});
114     }
115   }
116   return property_map;
117 }
118 
119 #else
120 
121 std::string ThreadStatus::GetThreadTypeName(
122     ThreadStatus::ThreadType /*thread_type*/) {
123   static std::string dummy_str = "";
124   return dummy_str;
125 }
126 
127 const std::string& ThreadStatus::GetOperationName(
128     ThreadStatus::OperationType /*op_type*/) {
129   static std::string dummy_str = "";
130   return dummy_str;
131 }
132 
133 const std::string& ThreadStatus::GetOperationStageName(
134     ThreadStatus::OperationStage /*stage*/) {
135   static std::string dummy_str = "";
136   return dummy_str;
137 }
138 
139 const std::string& ThreadStatus::GetStateName(
140     ThreadStatus::StateType /*state_type*/) {
141   static std::string dummy_str = "";
142   return dummy_str;
143 }
144 
145 const std::string ThreadStatus::MicrosToString(uint64_t /*op_elapsed_time*/) {
146   static std::string dummy_str = "";
147   return dummy_str;
148 }
149 
150 const std::string& ThreadStatus::GetOperationPropertyName(
151     ThreadStatus::OperationType /*op_type*/, int /*i*/) {
152   static std::string dummy_str = "";
153   return dummy_str;
154 }
155 
156 std::map<std::string, uint64_t> ThreadStatus::InterpretOperationProperties(
157     ThreadStatus::OperationType /*op_type*/,
158     const uint64_t* /*op_properties*/) {
159   return std::map<std::string, uint64_t>();
160 }
161 
162 #endif  // ROCKSDB_USING_THREAD_STATUS
163 }  // namespace ROCKSDB_NAMESPACE
164