]> git.proxmox.com Git - ceph.git/blame - ceph/src/rocksdb/include/rocksdb/status.h
import 14.2.4 nautilus point release
[ceph.git] / ceph / src / rocksdb / include / rocksdb / status.h
CommitLineData
7c673cae 1// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
11fdf7f2
TL
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).
7c673cae
FG
5// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
6// Use of this source code is governed by a BSD-style license that can be
7// found in the LICENSE file. See the AUTHORS file for names of contributors.
8//
9// A Status encapsulates the result of an operation. It may indicate success,
10// or it may indicate an error with an associated error message.
11//
12// Multiple threads can invoke const methods on a Status without
13// external synchronization, but if any of the threads may call a
14// non-const method, all threads accessing the same Status must use
15// external synchronization.
16
11fdf7f2 17#pragma once
7c673cae
FG
18
19#include <string>
20#include "rocksdb/slice.h"
21
22namespace rocksdb {
23
24class Status {
25 public:
26 // Create a success status.
11fdf7f2 27 Status() : code_(kOk), subcode_(kNone), sev_(kNoError), state_(nullptr) {}
7c673cae
FG
28 ~Status() { delete[] state_; }
29
30 // Copy the specified status.
31 Status(const Status& s);
32 Status& operator=(const Status& s);
33 Status(Status&& s)
34#if !(defined _MSC_VER) || ((defined _MSC_VER) && (_MSC_VER >= 1900))
35 noexcept
36#endif
37 ;
38 Status& operator=(Status&& s)
39#if !(defined _MSC_VER) || ((defined _MSC_VER) && (_MSC_VER >= 1900))
40 noexcept
41#endif
42 ;
43 bool operator==(const Status& rhs) const;
44 bool operator!=(const Status& rhs) const;
45
11fdf7f2 46 enum Code : unsigned char {
7c673cae
FG
47 kOk = 0,
48 kNotFound = 1,
49 kCorruption = 2,
50 kNotSupported = 3,
51 kInvalidArgument = 4,
52 kIOError = 5,
53 kMergeInProgress = 6,
54 kIncomplete = 7,
55 kShutdownInProgress = 8,
56 kTimedOut = 9,
57 kAborted = 10,
58 kBusy = 11,
59 kExpired = 12,
11fdf7f2
TL
60 kTryAgain = 13,
61 kCompactionTooLarge = 14
7c673cae
FG
62 };
63
64 Code code() const { return code_; }
65
11fdf7f2 66 enum SubCode : unsigned char {
7c673cae
FG
67 kNone = 0,
68 kMutexTimeout = 1,
69 kLockTimeout = 2,
70 kLockLimit = 3,
71 kNoSpace = 4,
72 kDeadlock = 5,
73 kStaleFile = 6,
74 kMemoryLimit = 7,
11fdf7f2 75 kSpaceLimit = 8,
494da23a 76 kPathNotFound = 9,
7c673cae
FG
77 kMaxSubCode
78 };
79
80 SubCode subcode() const { return subcode_; }
81
11fdf7f2
TL
82 enum Severity : unsigned char {
83 kNoError = 0,
84 kSoftError = 1,
85 kHardError = 2,
86 kFatalError = 3,
87 kUnrecoverableError = 4,
88 kMaxSeverity
89 };
90
91 Status(const Status& s, Severity sev);
92 Severity severity() const { return sev_; }
93
7c673cae
FG
94 // Returns a C style string indicating the message of the Status
95 const char* getState() const { return state_; }
96
97 // Return a success status.
98 static Status OK() { return Status(); }
99
100 // Return error status of an appropriate type.
101 static Status NotFound(const Slice& msg, const Slice& msg2 = Slice()) {
102 return Status(kNotFound, msg, msg2);
103 }
104 // Fast path for not found without malloc;
105 static Status NotFound(SubCode msg = kNone) { return Status(kNotFound, msg); }
106
107 static Status Corruption(const Slice& msg, const Slice& msg2 = Slice()) {
108 return Status(kCorruption, msg, msg2);
109 }
110 static Status Corruption(SubCode msg = kNone) {
111 return Status(kCorruption, msg);
112 }
113
114 static Status NotSupported(const Slice& msg, const Slice& msg2 = Slice()) {
115 return Status(kNotSupported, msg, msg2);
116 }
117 static Status NotSupported(SubCode msg = kNone) {
118 return Status(kNotSupported, msg);
119 }
120
121 static Status InvalidArgument(const Slice& msg, const Slice& msg2 = Slice()) {
122 return Status(kInvalidArgument, msg, msg2);
123 }
124 static Status InvalidArgument(SubCode msg = kNone) {
125 return Status(kInvalidArgument, msg);
126 }
127
128 static Status IOError(const Slice& msg, const Slice& msg2 = Slice()) {
129 return Status(kIOError, msg, msg2);
130 }
131 static Status IOError(SubCode msg = kNone) { return Status(kIOError, msg); }
132
133 static Status MergeInProgress(const Slice& msg, const Slice& msg2 = Slice()) {
134 return Status(kMergeInProgress, msg, msg2);
135 }
136 static Status MergeInProgress(SubCode msg = kNone) {
137 return Status(kMergeInProgress, msg);
138 }
139
140 static Status Incomplete(const Slice& msg, const Slice& msg2 = Slice()) {
141 return Status(kIncomplete, msg, msg2);
142 }
143 static Status Incomplete(SubCode msg = kNone) {
144 return Status(kIncomplete, msg);
145 }
146
147 static Status ShutdownInProgress(SubCode msg = kNone) {
148 return Status(kShutdownInProgress, msg);
149 }
150 static Status ShutdownInProgress(const Slice& msg,
151 const Slice& msg2 = Slice()) {
152 return Status(kShutdownInProgress, msg, msg2);
153 }
154 static Status Aborted(SubCode msg = kNone) { return Status(kAborted, msg); }
155 static Status Aborted(const Slice& msg, const Slice& msg2 = Slice()) {
156 return Status(kAborted, msg, msg2);
157 }
158
159 static Status Busy(SubCode msg = kNone) { return Status(kBusy, msg); }
160 static Status Busy(const Slice& msg, const Slice& msg2 = Slice()) {
161 return Status(kBusy, msg, msg2);
162 }
163
164 static Status TimedOut(SubCode msg = kNone) { return Status(kTimedOut, msg); }
165 static Status TimedOut(const Slice& msg, const Slice& msg2 = Slice()) {
166 return Status(kTimedOut, msg, msg2);
167 }
168
169 static Status Expired(SubCode msg = kNone) { return Status(kExpired, msg); }
170 static Status Expired(const Slice& msg, const Slice& msg2 = Slice()) {
171 return Status(kExpired, msg, msg2);
172 }
173
174 static Status TryAgain(SubCode msg = kNone) { return Status(kTryAgain, msg); }
175 static Status TryAgain(const Slice& msg, const Slice& msg2 = Slice()) {
176 return Status(kTryAgain, msg, msg2);
177 }
178
11fdf7f2
TL
179 static Status CompactionTooLarge(SubCode msg = kNone) {
180 return Status(kCompactionTooLarge, msg);
181 }
182 static Status CompactionTooLarge(const Slice& msg,
183 const Slice& msg2 = Slice()) {
184 return Status(kCompactionTooLarge, msg, msg2);
185 }
186
7c673cae
FG
187 static Status NoSpace() { return Status(kIOError, kNoSpace); }
188 static Status NoSpace(const Slice& msg, const Slice& msg2 = Slice()) {
189 return Status(kIOError, kNoSpace, msg, msg2);
190 }
191
192 static Status MemoryLimit() { return Status(kAborted, kMemoryLimit); }
193 static Status MemoryLimit(const Slice& msg, const Slice& msg2 = Slice()) {
194 return Status(kAborted, kMemoryLimit, msg, msg2);
195 }
196
11fdf7f2
TL
197 static Status SpaceLimit() { return Status(kIOError, kSpaceLimit); }
198 static Status SpaceLimit(const Slice& msg, const Slice& msg2 = Slice()) {
199 return Status(kIOError, kSpaceLimit, msg, msg2);
200 }
201
494da23a
TL
202 static Status PathNotFound() { return Status(kIOError, kPathNotFound); }
203 static Status PathNotFound(const Slice& msg, const Slice& msg2 = Slice()) {
204 return Status(kIOError, kPathNotFound, msg, msg2);
205 }
206
7c673cae
FG
207 // Returns true iff the status indicates success.
208 bool ok() const { return code() == kOk; }
209
210 // Returns true iff the status indicates a NotFound error.
211 bool IsNotFound() const { return code() == kNotFound; }
212
213 // Returns true iff the status indicates a Corruption error.
214 bool IsCorruption() const { return code() == kCorruption; }
215
216 // Returns true iff the status indicates a NotSupported error.
217 bool IsNotSupported() const { return code() == kNotSupported; }
218
219 // Returns true iff the status indicates an InvalidArgument error.
220 bool IsInvalidArgument() const { return code() == kInvalidArgument; }
221
222 // Returns true iff the status indicates an IOError.
223 bool IsIOError() const { return code() == kIOError; }
224
225 // Returns true iff the status indicates an MergeInProgress.
226 bool IsMergeInProgress() const { return code() == kMergeInProgress; }
227
228 // Returns true iff the status indicates Incomplete
229 bool IsIncomplete() const { return code() == kIncomplete; }
230
231 // Returns true iff the status indicates Shutdown In progress
232 bool IsShutdownInProgress() const { return code() == kShutdownInProgress; }
233
234 bool IsTimedOut() const { return code() == kTimedOut; }
235
236 bool IsAborted() const { return code() == kAborted; }
237
238 bool IsLockLimit() const {
239 return code() == kAborted && subcode() == kLockLimit;
240 }
241
242 // Returns true iff the status indicates that a resource is Busy and
243 // temporarily could not be acquired.
244 bool IsBusy() const { return code() == kBusy; }
245
246 bool IsDeadlock() const { return code() == kBusy && subcode() == kDeadlock; }
247
248 // Returns true iff the status indicated that the operation has Expired.
249 bool IsExpired() const { return code() == kExpired; }
250
251 // Returns true iff the status indicates a TryAgain error.
252 // This usually means that the operation failed, but may succeed if
253 // re-attempted.
254 bool IsTryAgain() const { return code() == kTryAgain; }
255
11fdf7f2
TL
256 // Returns true iff the status indicates the proposed compaction is too large
257 bool IsCompactionTooLarge() const { return code() == kCompactionTooLarge; }
258
7c673cae
FG
259 // Returns true iff the status indicates a NoSpace error
260 // This is caused by an I/O error returning the specific "out of space"
261 // error condition. Stricto sensu, an NoSpace error is an I/O error
262 // with a specific subcode, enabling users to take the appropriate action
263 // if needed
264 bool IsNoSpace() const {
265 return (code() == kIOError) && (subcode() == kNoSpace);
266 }
267
268 // Returns true iff the status indicates a memory limit error. There may be
269 // cases where we limit the memory used in certain operations (eg. the size
270 // of a write batch) in order to avoid out of memory exceptions.
271 bool IsMemoryLimit() const {
272 return (code() == kAborted) && (subcode() == kMemoryLimit);
273 }
274
494da23a
TL
275 // Returns true iff the status indicates a PathNotFound error
276 // This is caused by an I/O error returning the specific "no such file or
277 // directory" error condition. A PathNotFound error is an I/O error with
278 // a specific subcode, enabling users to take appropriate action if necessary
279 bool IsPathNotFound() const {
280 return (code() == kIOError) && (subcode() == kPathNotFound);
281 }
282
7c673cae
FG
283 // Return a string representation of this status suitable for printing.
284 // Returns the string "OK" for success.
285 std::string ToString() const;
286
287 private:
288 // A nullptr state_ (which is always the case for OK) means the message
289 // is empty.
290 // of the following form:
291 // state_[0..3] == length of message
292 // state_[4..] == message
293 Code code_;
294 SubCode subcode_;
11fdf7f2 295 Severity sev_;
7c673cae
FG
296 const char* state_;
297
7c673cae 298 explicit Status(Code _code, SubCode _subcode = kNone)
11fdf7f2 299 : code_(_code), subcode_(_subcode), sev_(kNoError), state_(nullptr) {}
7c673cae
FG
300
301 Status(Code _code, SubCode _subcode, const Slice& msg, const Slice& msg2);
302 Status(Code _code, const Slice& msg, const Slice& msg2)
303 : Status(_code, kNone, msg, msg2) {}
304
305 static const char* CopyState(const char* s);
306};
307
494da23a
TL
308inline Status::Status(const Status& s)
309 : code_(s.code_), subcode_(s.subcode_), sev_(s.sev_) {
11fdf7f2
TL
310 state_ = (s.state_ == nullptr) ? nullptr : CopyState(s.state_);
311}
312inline Status::Status(const Status& s, Severity sev)
494da23a 313 : code_(s.code_), subcode_(s.subcode_), sev_(sev) {
7c673cae
FG
314 state_ = (s.state_ == nullptr) ? nullptr : CopyState(s.state_);
315}
316inline Status& Status::operator=(const Status& s) {
317 // The following condition catches both aliasing (when this == &s),
318 // and the common case where both s and *this are ok.
319 if (this != &s) {
320 code_ = s.code_;
321 subcode_ = s.subcode_;
11fdf7f2 322 sev_ = s.sev_;
7c673cae
FG
323 delete[] state_;
324 state_ = (s.state_ == nullptr) ? nullptr : CopyState(s.state_);
325 }
326 return *this;
327}
328
329inline Status::Status(Status&& s)
330#if !(defined _MSC_VER) || ((defined _MSC_VER) && (_MSC_VER >= 1900))
331 noexcept
332#endif
333 : Status() {
334 *this = std::move(s);
335}
336
337inline Status& Status::operator=(Status&& s)
338#if !(defined _MSC_VER) || ((defined _MSC_VER) && (_MSC_VER >= 1900))
339 noexcept
340#endif
341{
342 if (this != &s) {
343 code_ = std::move(s.code_);
344 s.code_ = kOk;
345 subcode_ = std::move(s.subcode_);
346 s.subcode_ = kNone;
11fdf7f2
TL
347 sev_ = std::move(s.sev_);
348 s.sev_ = kNoError;
7c673cae
FG
349 delete[] state_;
350 state_ = nullptr;
351 std::swap(state_, s.state_);
352 }
353 return *this;
354}
355
356inline bool Status::operator==(const Status& rhs) const {
357 return (code_ == rhs.code_);
358}
359
360inline bool Status::operator!=(const Status& rhs) const {
361 return !(*this == rhs);
362}
363
364} // namespace rocksdb