Kudu C++ client API
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
status.h
Go to the documentation of this file.
1 // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. See the AUTHORS file for names of contributors.
4 //
5 // A Status encapsulates the result of an operation. It may indicate success,
6 // or it may indicate an error with an associated error message.
7 //
8 // Multiple threads can invoke const methods on a Status without
9 // external synchronization, but if any of the threads may call a
10 // non-const method, all threads accessing the same Status must use
11 // external synchronization.
12 
13 #ifndef KUDU_UTIL_STATUS_H_
14 #define KUDU_UTIL_STATUS_H_
15 
16 #include <stdint.h>
17 #include <string>
18 
19 #ifdef KUDU_HEADERS_NO_STUBS
20 #include "kudu/gutil/macros.h"
21 #include "kudu/gutil/port.h"
22 #else
23 #include "kudu/client/stubs.h"
24 #endif
25 
26 #include "kudu/util/kudu_export.h"
27 #include "kudu/util/slice.h"
28 
30 #define KUDU_RETURN_NOT_OK(s) do { \
31  const ::kudu::Status& _s = (s); \
32  if (PREDICT_FALSE(!_s.ok())) return _s; \
33  } while (0);
34 
37 #define KUDU_RETURN_NOT_OK_PREPEND(s, msg) do { \
38  const ::kudu::Status& _s = (s); \
39  if (PREDICT_FALSE(!_s.ok())) return _s.CloneAndPrepend(msg); \
40  } while (0);
41 
45 #define KUDU_RETURN_NOT_OK_RET(to_call, to_return) do { \
46  const ::kudu::Status& s = (to_call); \
47  if (PREDICT_FALSE(!s.ok())) return (to_return); \
48  } while (0);
49 
51 #define KUDU_WARN_NOT_OK(to_call, warning_prefix) do { \
52  const ::kudu::Status& _s = (to_call); \
53  if (PREDICT_FALSE(!_s.ok())) { \
54  KUDU_LOG(WARNING) << (warning_prefix) << ": " << _s.ToString(); \
55  } \
56  } while (0);
57 
59 #define KUDU_LOG_AND_RETURN(level, status) do { \
60  const ::kudu::Status& _s = (status); \
61  KUDU_LOG(level) << _s.ToString(); \
62  return _s; \
63  } while (0);
64 
67 #define KUDU_CHECK_OK_PREPEND(to_call, msg) do { \
68  const ::kudu::Status& _s = (to_call); \
69  KUDU_CHECK(_s.ok()) << (msg) << ": " << _s.ToString(); \
70  } while (0);
71 
74 #define KUDU_CHECK_OK(s) KUDU_CHECK_OK_PREPEND(s, "Bad status")
75 
89 #ifdef KUDU_HEADERS_USE_SHORT_STATUS_MACROS
90 #define RETURN_NOT_OK KUDU_RETURN_NOT_OK
91 #define RETURN_NOT_OK_PREPEND KUDU_RETURN_NOT_OK_PREPEND
92 #define RETURN_NOT_OK_RET KUDU_RETURN_NOT_OK_RET
93 #define WARN_NOT_OK KUDU_WARN_NOT_OK
94 #define LOG_AND_RETURN KUDU_LOG_AND_RETURN
95 #define CHECK_OK_PREPEND KUDU_CHECK_OK_PREPEND
96 #define CHECK_OK KUDU_CHECK_OK
97 
98 // These are standard glog macros.
99 #define KUDU_LOG LOG
100 #define KUDU_CHECK CHECK
101 #endif
102 
103 namespace kudu {
104 
106 class KUDU_EXPORT Status {
107  public:
109  Status() : state_(NULL) { }
110 
111  ~Status() { delete[] state_; }
112 
117  Status(const Status& s);
118 
123  void operator=(const Status& s);
124 
125 #if __cplusplus >= 201103L
126  Status(Status&& s);
131 
136  void operator=(Status&& s);
137 #endif
138 
140  static Status OK() { return Status(); }
141 
142 
154  static Status NotFound(const Slice& msg, const Slice& msg2 = Slice(),
155  int16_t posix_code = -1) {
156  return Status(kNotFound, msg, msg2, posix_code);
157  }
158  static Status Corruption(const Slice& msg, const Slice& msg2 = Slice(),
159  int16_t posix_code = -1) {
160  return Status(kCorruption, msg, msg2, posix_code);
161  }
162  static Status NotSupported(const Slice& msg, const Slice& msg2 = Slice(),
163  int16_t posix_code = -1) {
164  return Status(kNotSupported, msg, msg2, posix_code);
165  }
166  static Status InvalidArgument(const Slice& msg, const Slice& msg2 = Slice(),
167  int16_t posix_code = -1) {
168  return Status(kInvalidArgument, msg, msg2, posix_code);
169  }
170  static Status IOError(const Slice& msg, const Slice& msg2 = Slice(),
171  int16_t posix_code = -1) {
172  return Status(kIOError, msg, msg2, posix_code);
173  }
174  static Status AlreadyPresent(const Slice& msg, const Slice& msg2 = Slice(),
175  int16_t posix_code = -1) {
176  return Status(kAlreadyPresent, msg, msg2, posix_code);
177  }
178  static Status RuntimeError(const Slice& msg, const Slice& msg2 = Slice(),
179  int16_t posix_code = -1) {
180  return Status(kRuntimeError, msg, msg2, posix_code);
181  }
182  static Status NetworkError(const Slice& msg, const Slice& msg2 = Slice(),
183  int16_t posix_code = -1) {
184  return Status(kNetworkError, msg, msg2, posix_code);
185  }
186  static Status IllegalState(const Slice& msg, const Slice& msg2 = Slice(),
187  int16_t posix_code = -1) {
188  return Status(kIllegalState, msg, msg2, posix_code);
189  }
190  static Status NotAuthorized(const Slice& msg, const Slice& msg2 = Slice(),
191  int16_t posix_code = -1) {
192  return Status(kNotAuthorized, msg, msg2, posix_code);
193  }
194  static Status Aborted(const Slice& msg, const Slice& msg2 = Slice(),
195  int16_t posix_code = -1) {
196  return Status(kAborted, msg, msg2, posix_code);
197  }
198  static Status RemoteError(const Slice& msg, const Slice& msg2 = Slice(),
199  int16_t posix_code = -1) {
200  return Status(kRemoteError, msg, msg2, posix_code);
201  }
202  static Status ServiceUnavailable(const Slice& msg, const Slice& msg2 = Slice(),
203  int16_t posix_code = -1) {
204  return Status(kServiceUnavailable, msg, msg2, posix_code);
205  }
206  static Status TimedOut(const Slice& msg, const Slice& msg2 = Slice(),
207  int16_t posix_code = -1) {
208  return Status(kTimedOut, msg, msg2, posix_code);
209  }
210  static Status Uninitialized(const Slice& msg, const Slice& msg2 = Slice(),
211  int16_t posix_code = -1) {
212  return Status(kUninitialized, msg, msg2, posix_code);
213  }
214  static Status ConfigurationError(const Slice& msg, const Slice& msg2 = Slice(),
215  int16_t posix_code = -1) {
216  return Status(kConfigurationError, msg, msg2, posix_code);
217  }
218  static Status Incomplete(const Slice& msg, const Slice& msg2 = Slice(),
219  int64_t posix_code = -1) {
220  return Status(kIncomplete, msg, msg2, posix_code);
221  }
222  static Status EndOfFile(const Slice& msg, const Slice& msg2 = Slice(),
223  int64_t posix_code = -1) {
224  return Status(kEndOfFile, msg, msg2, posix_code);
225  }
227 
229  bool ok() const { return (state_ == NULL); }
230 
232  bool IsNotFound() const { return code() == kNotFound; }
233 
235  bool IsCorruption() const { return code() == kCorruption; }
236 
238  bool IsNotSupported() const { return code() == kNotSupported; }
239 
241  bool IsIOError() const { return code() == kIOError; }
242 
244  bool IsInvalidArgument() const { return code() == kInvalidArgument; }
245 
247  bool IsAlreadyPresent() const { return code() == kAlreadyPresent; }
248 
250  bool IsRuntimeError() const { return code() == kRuntimeError; }
251 
253  bool IsNetworkError() const { return code() == kNetworkError; }
254 
256  bool IsIllegalState() const { return code() == kIllegalState; }
257 
259  bool IsNotAuthorized() const { return code() == kNotAuthorized; }
260 
262  bool IsAborted() const { return code() == kAborted; }
263 
265  bool IsRemoteError() const { return code() == kRemoteError; }
266 
268  bool IsServiceUnavailable() const { return code() == kServiceUnavailable; }
269 
271  bool IsTimedOut() const { return code() == kTimedOut; }
272 
274  bool IsUninitialized() const { return code() == kUninitialized; }
275 
277  bool IsConfigurationError() const { return code() == kConfigurationError; }
278 
280  bool IsIncomplete() const { return code() == kIncomplete; }
281 
283  bool IsEndOfFile() const { return code() == kEndOfFile; }
284 
287  std::string ToString() const;
288 
291  std::string CodeAsString() const;
292 
301  Slice message() const;
302 
305  int16_t posix_code() const;
306 
313  Status CloneAndPrepend(const Slice& msg) const;
314 
321  Status CloneAndAppend(const Slice& msg) const;
322 
325  size_t memory_footprint_excluding_this() const;
326 
329  size_t memory_footprint_including_this() const;
330 
331  private:
332  // OK status has a NULL state_. Otherwise, state_ is a new[] array
333  // of the following form:
334  // state_[0..3] == length of message
335  // state_[4] == code
336  // state_[5..6] == posix_code
337  // state_[7..] == message
338  const char* state_;
339 
340  enum Code {
341  kOk = 0,
342  kNotFound = 1,
343  kCorruption = 2,
344  kNotSupported = 3,
345  kInvalidArgument = 4,
346  kIOError = 5,
347  kAlreadyPresent = 6,
348  kRuntimeError = 7,
349  kNetworkError = 8,
350  kIllegalState = 9,
351  kNotAuthorized = 10,
352  kAborted = 11,
353  kRemoteError = 12,
354  kServiceUnavailable = 13,
355  kTimedOut = 14,
356  kUninitialized = 15,
357  kConfigurationError = 16,
358  kIncomplete = 17,
359  kEndOfFile = 18,
360  // NOTE: Remember to duplicate these constants into wire_protocol.proto and
361  // and to add StatusTo/FromPB ser/deser cases in wire_protocol.cc !
362  // Also remember to make the same changes to the java client in Status.java.
363  //
364  // TODO: Move error codes into an error_code.proto or something similar.
365  };
366  COMPILE_ASSERT(sizeof(Code) == 4, code_enum_size_is_part_of_abi);
367 
368  Code code() const {
369  return (state_ == NULL) ? kOk : static_cast<Code>(state_[4]);
370  }
371 
372  Status(Code code, const Slice& msg, const Slice& msg2, int16_t posix_code);
373  static const char* CopyState(const char* s);
374 };
375 
376 inline Status::Status(const Status& s) {
377  state_ = (s.state_ == NULL) ? NULL : CopyState(s.state_);
378 }
379 inline void Status::operator=(const Status& s) {
380  // The following condition catches both aliasing (when this == &s),
381  // and the common case where both s and *this are ok.
382  if (state_ != s.state_) {
383  delete[] state_;
384  state_ = (s.state_ == NULL) ? NULL : CopyState(s.state_);
385  }
386 }
387 
388 #if __cplusplus >= 201103L
389 inline Status::Status(Status&& s) : state_(s.state_) {
390  s.state_ = nullptr;
391 }
392 
393 inline void Status::operator=(Status&& s) {
394  if (state_ != s.state_) {
395  delete[] state_;
396  state_ = s.state_;
397  s.state_ = nullptr;
398  }
399 }
400 #endif
401 
402 } // namespace kudu
403 
404 #endif // KUDU_UTIL_STATUS_H_
Status()
Create an object representing success status.
Definition: status.h:109
bool IsNotAuthorized() const
Definition: status.h:259
A representation of an operation's outcome.
Definition: status.h:106
bool IsIllegalState() const
Definition: status.h:256
bool ok() const
Definition: status.h:229
bool IsTimedOut() const
Definition: status.h:271
bool IsRemoteError() const
Definition: status.h:265
bool IsServiceUnavailable() const
Definition: status.h:268
bool IsAborted() const
Definition: status.h:262
bool IsUninitialized() const
Definition: status.h:274
bool IsRuntimeError() const
Definition: status.h:250
bool IsAlreadyPresent() const
Definition: status.h:247
bool IsIOError() const
Definition: status.h:241
static Status OK()
Definition: status.h:140
A wrapper around externally allocated data.
Definition: slice.h:43
bool IsConfigurationError() const
Definition: status.h:277
bool IsInvalidArgument() const
Definition: status.h:244
bool IsCorruption() const
Definition: status.h:235
void operator=(const Status &s)
Definition: status.h:379
bool IsEndOfFile() const
Definition: status.h:283
bool IsNotSupported() const
Definition: status.h:238
bool IsNetworkError() const
Definition: status.h:253
bool IsIncomplete() const
Definition: status.h:280
bool IsNotFound() const
Definition: status.h:232