/src/rocksdb/util/status.cc
Line | Count | Source (jump to first uncovered line) |
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 | | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. |
7 | | // Use of this source code is governed by a BSD-style license that can be |
8 | | // found in the LICENSE file. See the AUTHORS file for names of contributors. |
9 | | |
10 | | #include "rocksdb/status.h" |
11 | | |
12 | | #include <cstdio> |
13 | | #ifdef OS_WIN |
14 | | #include <string.h> |
15 | | #endif |
16 | | #include <cstring> |
17 | | |
18 | | #include "port/port.h" |
19 | | |
20 | | namespace ROCKSDB_NAMESPACE { |
21 | | |
22 | 17.7k | std::unique_ptr<const char[]> Status::CopyState(const char* s) { |
23 | 17.7k | const size_t cch = std::strlen(s) + 1; // +1 for the null terminator |
24 | 17.7k | char* rv = new char[cch]; |
25 | 17.7k | std::strncpy(rv, s, cch); |
26 | 17.7k | return std::unique_ptr<const char[]>(rv); |
27 | 17.7k | } |
28 | | |
29 | | static const char* msgs[static_cast<int>(Status::kMaxSubCode)] = { |
30 | | "", // kNone |
31 | | "Timeout Acquiring Mutex", // kMutexTimeout |
32 | | "Timeout waiting to lock key", // kLockTimeout |
33 | | "Failed to acquire lock due to max_num_locks limit", // kLockLimit |
34 | | "No space left on device", // kNoSpace |
35 | | "Deadlock", // kDeadlock |
36 | | "Stale file handle", // kStaleFile |
37 | | "Memory limit reached", // kMemoryLimit |
38 | | "Space limit reached", // kSpaceLimit |
39 | | "No such file or directory", // kPathNotFound |
40 | | // KMergeOperandsInsufficientCapacity |
41 | | "Insufficient capacity for merge operands", |
42 | | // kManualCompactionPaused |
43 | | "Manual compaction paused", |
44 | | " (overwritten)", // kOverwritten, subcode of OK |
45 | | "Txn not prepared", // kTxnNotPrepared |
46 | | "IO fenced off", // kIOFenced |
47 | | "Merge operator failed", // kMergeOperatorFailed |
48 | | "Number of operands merged exceeded threshold", // kMergeOperandThresholdExceeded |
49 | | }; |
50 | | |
51 | | Status::Status(Code _code, SubCode _subcode, const Slice& msg, |
52 | | const Slice& msg2, Severity sev) |
53 | 567k | : code_(_code), |
54 | 567k | subcode_(_subcode), |
55 | 567k | sev_(sev), |
56 | 567k | retryable_(false), |
57 | 567k | data_loss_(false), |
58 | 567k | scope_(0) { |
59 | 567k | assert(subcode_ != kMaxSubCode); |
60 | 567k | const size_t len1 = msg.size(); |
61 | 567k | const size_t len2 = msg2.size(); |
62 | 567k | const size_t size = len1 + (len2 ? (2 + len2) : 0); |
63 | 567k | char* const result = new char[size + 1]; // +1 for null terminator |
64 | 567k | memcpy(result, msg.data(), len1); |
65 | 567k | if (len2) { |
66 | 0 | result[len1] = ':'; |
67 | 0 | result[len1 + 1] = ' '; |
68 | 0 | memcpy(result + len1 + 2, msg2.data(), len2); |
69 | 0 | } |
70 | 567k | result[size] = '\0'; // null terminator for C style string |
71 | 567k | state_.reset(result); |
72 | 567k | } |
73 | | |
74 | | Status Status::CopyAppendMessage(const Status& s, const Slice& delim, |
75 | 0 | const Slice& msg) { |
76 | | // (No attempt at efficiency) |
77 | 0 | return Status(s.code(), s.subcode(), s.severity(), |
78 | 0 | std::string(s.getState()) + delim.ToString() + msg.ToString()); |
79 | 0 | } |
80 | | |
81 | 229k | std::string Status::ToString() const { |
82 | | #ifdef ROCKSDB_ASSERT_STATUS_CHECKED |
83 | | checked_ = true; |
84 | | #endif // ROCKSDB_ASSERT_STATUS_CHECKED |
85 | 229k | const char* type = nullptr; |
86 | 229k | switch (code_) { |
87 | 226k | case kOk: |
88 | 226k | return "OK"; |
89 | 0 | case kNotFound: |
90 | 0 | type = "NotFound: "; |
91 | 0 | break; |
92 | 0 | case kCorruption: |
93 | 0 | type = "Corruption: "; |
94 | 0 | break; |
95 | 0 | case kNotSupported: |
96 | 0 | type = "Not implemented: "; |
97 | 0 | break; |
98 | 0 | case kInvalidArgument: |
99 | 0 | type = "Invalid argument: "; |
100 | 0 | break; |
101 | 0 | case kIOError: |
102 | 0 | type = "IO error: "; |
103 | 0 | break; |
104 | 0 | case kMergeInProgress: |
105 | 0 | type = "Merge in progress: "; |
106 | 0 | break; |
107 | 0 | case kIncomplete: |
108 | 0 | type = "Result incomplete: "; |
109 | 0 | break; |
110 | 3.28k | case kShutdownInProgress: |
111 | 3.28k | type = "Shutdown in progress: "; |
112 | 3.28k | break; |
113 | 0 | case kTimedOut: |
114 | 0 | type = "Operation timed out: "; |
115 | 0 | break; |
116 | 0 | case kAborted: |
117 | 0 | type = "Operation aborted: "; |
118 | 0 | break; |
119 | 0 | case kBusy: |
120 | 0 | type = "Resource busy: "; |
121 | 0 | break; |
122 | 0 | case kExpired: |
123 | 0 | type = "Operation expired: "; |
124 | 0 | break; |
125 | 0 | case kTryAgain: |
126 | 0 | type = "Operation failed. Try again.: "; |
127 | 0 | break; |
128 | 0 | case kCompactionTooLarge: |
129 | 0 | type = "Compaction too large: "; |
130 | 0 | break; |
131 | 0 | case kColumnFamilyDropped: |
132 | 0 | type = "Column family dropped: "; |
133 | 0 | break; |
134 | 0 | case kMaxCode: |
135 | 0 | assert(false); |
136 | 0 | break; |
137 | 229k | } |
138 | 3.28k | char tmp[30]; |
139 | 3.28k | if (type == nullptr) { |
140 | | // This should not happen since `code_` should be a valid non-`kMaxCode` |
141 | | // member of the `Code` enum. The above switch-statement should have had a |
142 | | // case assigning `type` to a corresponding string. |
143 | 0 | assert(false); |
144 | 0 | snprintf(tmp, sizeof(tmp), "Unknown code(%d): ", static_cast<int>(code())); |
145 | 0 | type = tmp; |
146 | 0 | } |
147 | 3.28k | std::string result(type); |
148 | 3.28k | if (subcode_ != kNone) { |
149 | 0 | uint32_t index = static_cast<int32_t>(subcode_); |
150 | 0 | assert(sizeof(msgs) / sizeof(msgs[0]) > index); |
151 | 0 | result.append(msgs[index]); |
152 | 0 | } |
153 | | |
154 | 3.28k | if (state_ != nullptr) { |
155 | 3.28k | if (subcode_ != kNone) { |
156 | 0 | result.append(": "); |
157 | 0 | } |
158 | 3.28k | result.append(state_.get()); |
159 | 3.28k | } |
160 | 3.28k | return result; |
161 | 229k | } |
162 | | |
163 | | } // namespace ROCKSDB_NAMESPACE |