Kudu C++ client API
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 
87 #define KUDU_DCHECK_OK_PREPEND(to_call, msg) do { \
88  const ::kudu::Status& _s = (to_call); \
89  KUDU_DCHECK(_s.ok()) << (msg) << ": " << _s.ToString(); \
90  } while (0);
91 
94 #define KUDU_DCHECK_OK(s) KUDU_DCHECK_OK_PREPEND(s, "Bad status")
95 
109 #ifdef KUDU_HEADERS_USE_SHORT_STATUS_MACROS
110 #define RETURN_NOT_OK KUDU_RETURN_NOT_OK
111 #define RETURN_NOT_OK_PREPEND KUDU_RETURN_NOT_OK_PREPEND
112 #define RETURN_NOT_OK_RET KUDU_RETURN_NOT_OK_RET
113 #define WARN_NOT_OK KUDU_WARN_NOT_OK
114 #define LOG_AND_RETURN KUDU_LOG_AND_RETURN
115 #define RETURN_NOT_OK_LOG KUDU_RETURN_NOT_OK_LOG
116 #define CHECK_OK_PREPEND KUDU_CHECK_OK_PREPEND
117 #define CHECK_OK KUDU_CHECK_OK
118 #define DCHECK_OK_PREPEND KUDU_DCHECK_OK_PREPEND
119 #define DCHECK_OK KUDU_DCHECK_OK
120 
121 // These are standard glog macros.
122 #define KUDU_LOG LOG
123 #define KUDU_CHECK CHECK
124 #define KUDU_DCHECK DCHECK
125 #endif
126 
127 namespace kudu {
128 
130 class KUDU_EXPORT Status {
131  public:
133  Status() : state_(NULL) { }
134 
135  ~Status() { delete[] state_; }
136 
141  Status(const Status& s);
142 
147  void operator=(const Status& s);
148 
149 #if __cplusplus >= 201103L
150  Status(Status&& s);
155 
160  void operator=(Status&& s);
161 #endif
162 
164  static Status OK() { return Status(); }
165 
166 
178  static Status NotFound(const Slice& msg, const Slice& msg2 = Slice(),
179  int16_t posix_code = -1) {
180  return Status(kNotFound, msg, msg2, posix_code);
181  }
182  static Status Corruption(const Slice& msg, const Slice& msg2 = Slice(),
183  int16_t posix_code = -1) {
184  return Status(kCorruption, msg, msg2, posix_code);
185  }
186  static Status NotSupported(const Slice& msg, const Slice& msg2 = Slice(),
187  int16_t posix_code = -1) {
188  return Status(kNotSupported, msg, msg2, posix_code);
189  }
190  static Status InvalidArgument(const Slice& msg, const Slice& msg2 = Slice(),
191  int16_t posix_code = -1) {
192  return Status(kInvalidArgument, msg, msg2, posix_code);
193  }
194  static Status IOError(const Slice& msg, const Slice& msg2 = Slice(),
195  int16_t posix_code = -1) {
196  return Status(kIOError, msg, msg2, posix_code);
197  }
198  static Status AlreadyPresent(const Slice& msg, const Slice& msg2 = Slice(),
199  int16_t posix_code = -1) {
200  return Status(kAlreadyPresent, msg, msg2, posix_code);
201  }
202  static Status RuntimeError(const Slice& msg, const Slice& msg2 = Slice(),
203  int16_t posix_code = -1) {
204  return Status(kRuntimeError, msg, msg2, posix_code);
205  }
206  static Status NetworkError(const Slice& msg, const Slice& msg2 = Slice(),
207  int16_t posix_code = -1) {
208  return Status(kNetworkError, msg, msg2, posix_code);
209  }
210  static Status IllegalState(const Slice& msg, const Slice& msg2 = Slice(),
211  int16_t posix_code = -1) {
212  return Status(kIllegalState, msg, msg2, posix_code);
213  }
214  static Status NotAuthorized(const Slice& msg, const Slice& msg2 = Slice(),
215  int16_t posix_code = -1) {
216  return Status(kNotAuthorized, msg, msg2, posix_code);
217  }
218  static Status Aborted(const Slice& msg, const Slice& msg2 = Slice(),
219  int16_t posix_code = -1) {
220  return Status(kAborted, msg, msg2, posix_code);
221  }
222  static Status RemoteError(const Slice& msg, const Slice& msg2 = Slice(),
223  int16_t posix_code = -1) {
224  return Status(kRemoteError, msg, msg2, posix_code);
225  }
226  static Status ServiceUnavailable(const Slice& msg, const Slice& msg2 = Slice(),
227  int16_t posix_code = -1) {
228  return Status(kServiceUnavailable, msg, msg2, posix_code);
229  }
230  static Status TimedOut(const Slice& msg, const Slice& msg2 = Slice(),
231  int16_t posix_code = -1) {
232  return Status(kTimedOut, msg, msg2, posix_code);
233  }
234  static Status Uninitialized(const Slice& msg, const Slice& msg2 = Slice(),
235  int16_t posix_code = -1) {
236  return Status(kUninitialized, msg, msg2, posix_code);
237  }
238  static Status ConfigurationError(const Slice& msg, const Slice& msg2 = Slice(),
239  int16_t posix_code = -1) {
240  return Status(kConfigurationError, msg, msg2, posix_code);
241  }
242  static Status Incomplete(const Slice& msg, const Slice& msg2 = Slice(),
243  int64_t posix_code = -1) {
244  return Status(kIncomplete, msg, msg2, posix_code);
245  }
246  static Status EndOfFile(const Slice& msg, const Slice& msg2 = Slice(),
247  int64_t posix_code = -1) {
248  return Status(kEndOfFile, msg, msg2, posix_code);
249  }
251 
253  bool ok() const { return (state_ == NULL); }
254 
256  bool IsNotFound() const { return code() == kNotFound; }
257 
259  bool IsCorruption() const { return code() == kCorruption; }
260 
262  bool IsNotSupported() const { return code() == kNotSupported; }
263 
265  bool IsIOError() const { return code() == kIOError; }
266 
268  bool IsInvalidArgument() const { return code() == kInvalidArgument; }
269 
271  bool IsAlreadyPresent() const { return code() == kAlreadyPresent; }
272 
274  bool IsRuntimeError() const { return code() == kRuntimeError; }
275 
277  bool IsNetworkError() const { return code() == kNetworkError; }
278 
280  bool IsIllegalState() const { return code() == kIllegalState; }
281 
283  bool IsNotAuthorized() const { return code() == kNotAuthorized; }
284 
286  bool IsAborted() const { return code() == kAborted; }
287 
289  bool IsRemoteError() const { return code() == kRemoteError; }
290 
292  bool IsServiceUnavailable() const { return code() == kServiceUnavailable; }
293 
295  bool IsTimedOut() const { return code() == kTimedOut; }
296 
298  bool IsUninitialized() const { return code() == kUninitialized; }
299 
301  bool IsConfigurationError() const { return code() == kConfigurationError; }
302 
304  bool IsIncomplete() const { return code() == kIncomplete; }
305 
307  bool IsEndOfFile() const { return code() == kEndOfFile; }
308 
311  std::string ToString() const;
312 
315  std::string CodeAsString() const;
316 
325  Slice message() const;
326 
329  int16_t posix_code() const;
330 
337  Status CloneAndPrepend(const Slice& msg) const;
338 
345  Status CloneAndAppend(const Slice& msg) const;
346 
349  size_t memory_footprint_excluding_this() const;
350 
353  size_t memory_footprint_including_this() const;
354 
355  private:
356  // OK status has a NULL state_. Otherwise, state_ is a new[] array
357  // of the following form:
358  // state_[0..3] == length of message
359  // state_[4] == code
360  // state_[5..6] == posix_code
361  // state_[7..] == message
362  const char* state_;
363 
364  enum Code {
365  kOk = 0,
366  kNotFound = 1,
367  kCorruption = 2,
368  kNotSupported = 3,
369  kInvalidArgument = 4,
370  kIOError = 5,
371  kAlreadyPresent = 6,
372  kRuntimeError = 7,
373  kNetworkError = 8,
374  kIllegalState = 9,
375  kNotAuthorized = 10,
376  kAborted = 11,
377  kRemoteError = 12,
378  kServiceUnavailable = 13,
379  kTimedOut = 14,
380  kUninitialized = 15,
381  kConfigurationError = 16,
382  kIncomplete = 17,
383  kEndOfFile = 18,
384  // NOTE: Remember to duplicate these constants into wire_protocol.proto and
385  // and to add StatusTo/FromPB ser/deser cases in wire_protocol.cc !
386  // Also remember to make the same changes to the java client in Status.java.
387  //
388  // TODO: Move error codes into an error_code.proto or something similar.
389  };
390  COMPILE_ASSERT(sizeof(Code) == 4, code_enum_size_is_part_of_abi);
391 
392  Code code() const {
393  return (state_ == NULL) ? kOk : static_cast<Code>(state_[4]);
394  }
395 
396  Status(Code code, const Slice& msg, const Slice& msg2, int16_t posix_code);
397  static const char* CopyState(const char* s);
398 };
399 
400 inline Status::Status(const Status& s) {
401  state_ = (s.state_ == NULL) ? NULL : CopyState(s.state_);
402 }
403 inline void Status::operator=(const Status& s) {
404  // The following condition catches both aliasing (when this == &s),
405  // and the common case where both s and *this are OK.
406  if (state_ != s.state_) {
407  delete[] state_;
408  state_ = (s.state_ == NULL) ? NULL : CopyState(s.state_);
409  }
410 }
411 
412 #if __cplusplus >= 201103L
413 inline Status::Status(Status&& s) : state_(s.state_) {
414  s.state_ = nullptr;
415 }
416 
417 inline void Status::operator=(Status&& s) {
418  if (state_ != s.state_) {
419  delete[] state_;
420  state_ = s.state_;
421  s.state_ = nullptr;
422  }
423 }
424 #endif
425 
426 } // namespace kudu
427 
428 #endif // KUDU_UTIL_STATUS_H_
Status()
Create an object representing success status.
Definition: status.h:133
bool IsNotAuthorized() const
Definition: status.h:283
A representation of an operation&#39;s outcome.
Definition: status.h:130
bool IsIllegalState() const
Definition: status.h:280
Definition: callbacks.h:28
bool ok() const
Definition: status.h:253
bool IsTimedOut() const
Definition: status.h:295
bool IsRemoteError() const
Definition: status.h:289
bool IsServiceUnavailable() const
Definition: status.h:292
bool IsAborted() const
Definition: status.h:286
bool IsUninitialized() const
Definition: status.h:298
bool IsRuntimeError() const
Definition: status.h:274
bool IsAlreadyPresent() const
Definition: status.h:271
bool IsIOError() const
Definition: status.h:265
static Status OK()
Definition: status.h:164
A wrapper around externally allocated data.
Definition: slice.h:43
bool IsConfigurationError() const
Definition: status.h:301
bool IsInvalidArgument() const
Definition: status.h:268
bool IsCorruption() const
Definition: status.h:259
void operator=(const Status &s)
Definition: status.h:403
bool IsEndOfFile() const
Definition: status.h:307
bool IsNotSupported() const
Definition: status.h:262
bool IsNetworkError() const
Definition: status.h:277
bool IsIncomplete() const
Definition: status.h:304
bool IsNotFound() const
Definition: status.h:256