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 
66 #define KUDU_RETURN_NOT_OK_LOG(s, level, msg) do { \
67  const ::kudu::Status& _s = (s); \
68  if (PREDICT_FALSE(!_s.ok())) { \
69  KUDU_LOG(level) << "Status: " << _s.ToString() << " " << (msg); \
70  return _s; \
71  } \
72  } while (0);
73 
76 #define KUDU_CHECK_OK_PREPEND(to_call, msg) do { \
77  const ::kudu::Status& _s = (to_call); \
78  KUDU_CHECK(_s.ok()) << (msg) << ": " << _s.ToString(); \
79  } while (0);
80 
83 #define KUDU_CHECK_OK(s) KUDU_CHECK_OK_PREPEND(s, "Bad status")
84 
98 #ifdef KUDU_HEADERS_USE_SHORT_STATUS_MACROS
99 #define RETURN_NOT_OK KUDU_RETURN_NOT_OK
100 #define RETURN_NOT_OK_PREPEND KUDU_RETURN_NOT_OK_PREPEND
101 #define RETURN_NOT_OK_RET KUDU_RETURN_NOT_OK_RET
102 #define WARN_NOT_OK KUDU_WARN_NOT_OK
103 #define LOG_AND_RETURN KUDU_LOG_AND_RETURN
104 #define RETURN_NOT_OK_LOG KUDU_RETURN_NOT_OK_LOG
105 #define CHECK_OK_PREPEND KUDU_CHECK_OK_PREPEND
106 #define CHECK_OK KUDU_CHECK_OK
107 
108 // These are standard glog macros.
109 #define KUDU_LOG LOG
110 #define KUDU_CHECK CHECK
111 #endif
112 
113 namespace kudu {
114 
116 class KUDU_EXPORT Status {
117  public:
119  Status() : state_(NULL) { }
120 
121  ~Status() { delete[] state_; }
122 
127  Status(const Status& s);
128 
133  void operator=(const Status& s);
134 
135 #if __cplusplus >= 201103L
136  Status(Status&& s);
141 
146  void operator=(Status&& s);
147 #endif
148 
150  static Status OK() { return Status(); }
151 
152 
164  static Status NotFound(const Slice& msg, const Slice& msg2 = Slice(),
165  int16_t posix_code = -1) {
166  return Status(kNotFound, msg, msg2, posix_code);
167  }
168  static Status Corruption(const Slice& msg, const Slice& msg2 = Slice(),
169  int16_t posix_code = -1) {
170  return Status(kCorruption, msg, msg2, posix_code);
171  }
172  static Status NotSupported(const Slice& msg, const Slice& msg2 = Slice(),
173  int16_t posix_code = -1) {
174  return Status(kNotSupported, msg, msg2, posix_code);
175  }
176  static Status InvalidArgument(const Slice& msg, const Slice& msg2 = Slice(),
177  int16_t posix_code = -1) {
178  return Status(kInvalidArgument, msg, msg2, posix_code);
179  }
180  static Status IOError(const Slice& msg, const Slice& msg2 = Slice(),
181  int16_t posix_code = -1) {
182  return Status(kIOError, msg, msg2, posix_code);
183  }
184  static Status AlreadyPresent(const Slice& msg, const Slice& msg2 = Slice(),
185  int16_t posix_code = -1) {
186  return Status(kAlreadyPresent, msg, msg2, posix_code);
187  }
188  static Status RuntimeError(const Slice& msg, const Slice& msg2 = Slice(),
189  int16_t posix_code = -1) {
190  return Status(kRuntimeError, msg, msg2, posix_code);
191  }
192  static Status NetworkError(const Slice& msg, const Slice& msg2 = Slice(),
193  int16_t posix_code = -1) {
194  return Status(kNetworkError, msg, msg2, posix_code);
195  }
196  static Status IllegalState(const Slice& msg, const Slice& msg2 = Slice(),
197  int16_t posix_code = -1) {
198  return Status(kIllegalState, msg, msg2, posix_code);
199  }
200  static Status NotAuthorized(const Slice& msg, const Slice& msg2 = Slice(),
201  int16_t posix_code = -1) {
202  return Status(kNotAuthorized, msg, msg2, posix_code);
203  }
204  static Status Aborted(const Slice& msg, const Slice& msg2 = Slice(),
205  int16_t posix_code = -1) {
206  return Status(kAborted, msg, msg2, posix_code);
207  }
208  static Status RemoteError(const Slice& msg, const Slice& msg2 = Slice(),
209  int16_t posix_code = -1) {
210  return Status(kRemoteError, msg, msg2, posix_code);
211  }
212  static Status ServiceUnavailable(const Slice& msg, const Slice& msg2 = Slice(),
213  int16_t posix_code = -1) {
214  return Status(kServiceUnavailable, msg, msg2, posix_code);
215  }
216  static Status TimedOut(const Slice& msg, const Slice& msg2 = Slice(),
217  int16_t posix_code = -1) {
218  return Status(kTimedOut, msg, msg2, posix_code);
219  }
220  static Status Uninitialized(const Slice& msg, const Slice& msg2 = Slice(),
221  int16_t posix_code = -1) {
222  return Status(kUninitialized, msg, msg2, posix_code);
223  }
224  static Status ConfigurationError(const Slice& msg, const Slice& msg2 = Slice(),
225  int16_t posix_code = -1) {
226  return Status(kConfigurationError, msg, msg2, posix_code);
227  }
228  static Status Incomplete(const Slice& msg, const Slice& msg2 = Slice(),
229  int64_t posix_code = -1) {
230  return Status(kIncomplete, msg, msg2, posix_code);
231  }
232  static Status EndOfFile(const Slice& msg, const Slice& msg2 = Slice(),
233  int64_t posix_code = -1) {
234  return Status(kEndOfFile, msg, msg2, posix_code);
235  }
237 
239  bool ok() const { return (state_ == NULL); }
240 
242  bool IsNotFound() const { return code() == kNotFound; }
243 
245  bool IsCorruption() const { return code() == kCorruption; }
246 
248  bool IsNotSupported() const { return code() == kNotSupported; }
249 
251  bool IsIOError() const { return code() == kIOError; }
252 
254  bool IsInvalidArgument() const { return code() == kInvalidArgument; }
255 
257  bool IsAlreadyPresent() const { return code() == kAlreadyPresent; }
258 
260  bool IsRuntimeError() const { return code() == kRuntimeError; }
261 
263  bool IsNetworkError() const { return code() == kNetworkError; }
264 
266  bool IsIllegalState() const { return code() == kIllegalState; }
267 
269  bool IsNotAuthorized() const { return code() == kNotAuthorized; }
270 
272  bool IsAborted() const { return code() == kAborted; }
273 
275  bool IsRemoteError() const { return code() == kRemoteError; }
276 
278  bool IsServiceUnavailable() const { return code() == kServiceUnavailable; }
279 
281  bool IsTimedOut() const { return code() == kTimedOut; }
282 
284  bool IsUninitialized() const { return code() == kUninitialized; }
285 
287  bool IsConfigurationError() const { return code() == kConfigurationError; }
288 
290  bool IsIncomplete() const { return code() == kIncomplete; }
291 
293  bool IsEndOfFile() const { return code() == kEndOfFile; }
294 
297  std::string ToString() const;
298 
301  std::string CodeAsString() const;
302 
311  Slice message() const;
312 
315  int16_t posix_code() const;
316 
323  Status CloneAndPrepend(const Slice& msg) const;
324 
331  Status CloneAndAppend(const Slice& msg) const;
332 
335  size_t memory_footprint_excluding_this() const;
336 
339  size_t memory_footprint_including_this() const;
340 
341  private:
342  // OK status has a NULL state_. Otherwise, state_ is a new[] array
343  // of the following form:
344  // state_[0..3] == length of message
345  // state_[4] == code
346  // state_[5..6] == posix_code
347  // state_[7..] == message
348  const char* state_;
349 
350  enum Code {
351  kOk = 0,
352  kNotFound = 1,
353  kCorruption = 2,
354  kNotSupported = 3,
355  kInvalidArgument = 4,
356  kIOError = 5,
357  kAlreadyPresent = 6,
358  kRuntimeError = 7,
359  kNetworkError = 8,
360  kIllegalState = 9,
361  kNotAuthorized = 10,
362  kAborted = 11,
363  kRemoteError = 12,
364  kServiceUnavailable = 13,
365  kTimedOut = 14,
366  kUninitialized = 15,
367  kConfigurationError = 16,
368  kIncomplete = 17,
369  kEndOfFile = 18,
370  // NOTE: Remember to duplicate these constants into wire_protocol.proto and
371  // and to add StatusTo/FromPB ser/deser cases in wire_protocol.cc !
372  // Also remember to make the same changes to the java client in Status.java.
373  //
374  // TODO: Move error codes into an error_code.proto or something similar.
375  };
376  COMPILE_ASSERT(sizeof(Code) == 4, code_enum_size_is_part_of_abi);
377 
378  Code code() const {
379  return (state_ == NULL) ? kOk : static_cast<Code>(state_[4]);
380  }
381 
382  Status(Code code, const Slice& msg, const Slice& msg2, int16_t posix_code);
383  static const char* CopyState(const char* s);
384 };
385 
386 inline Status::Status(const Status& s) {
387  state_ = (s.state_ == NULL) ? NULL : CopyState(s.state_);
388 }
389 inline void Status::operator=(const Status& s) {
390  // The following condition catches both aliasing (when this == &s),
391  // and the common case where both s and *this are ok.
392  if (state_ != s.state_) {
393  delete[] state_;
394  state_ = (s.state_ == NULL) ? NULL : CopyState(s.state_);
395  }
396 }
397 
398 #if __cplusplus >= 201103L
399 inline Status::Status(Status&& s) : state_(s.state_) {
400  s.state_ = nullptr;
401 }
402 
403 inline void Status::operator=(Status&& s) {
404  if (state_ != s.state_) {
405  delete[] state_;
406  state_ = s.state_;
407  s.state_ = nullptr;
408  }
409 }
410 #endif
411 
412 } // namespace kudu
413 
414 #endif // KUDU_UTIL_STATUS_H_
Status()
Create an object representing success status.
Definition: status.h:119
bool IsNotAuthorized() const
Definition: status.h:269
A representation of an operation's outcome.
Definition: status.h:116
bool IsIllegalState() const
Definition: status.h:266
bool ok() const
Definition: status.h:239
bool IsTimedOut() const
Definition: status.h:281
bool IsRemoteError() const
Definition: status.h:275
bool IsServiceUnavailable() const
Definition: status.h:278
bool IsAborted() const
Definition: status.h:272
bool IsUninitialized() const
Definition: status.h:284
bool IsRuntimeError() const
Definition: status.h:260
bool IsAlreadyPresent() const
Definition: status.h:257
bool IsIOError() const
Definition: status.h:251
static Status OK()
Definition: status.h:150
A wrapper around externally allocated data.
Definition: slice.h:43
bool IsConfigurationError() const
Definition: status.h:287
bool IsInvalidArgument() const
Definition: status.h:254
bool IsCorruption() const
Definition: status.h:245
void operator=(const Status &s)
Definition: status.h:389
bool IsEndOfFile() const
Definition: status.h:293
bool IsNotSupported() const
Definition: status.h:248
bool IsNetworkError() const
Definition: status.h:263
bool IsIncomplete() const
Definition: status.h:290
bool IsNotFound() const
Definition: status.h:242