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 
148  Status& operator=(const Status& s);
149 
150 #if __cplusplus >= 201103L
151  Status(Status&& s);
156 
162  Status& operator=(Status&& s);
163 #endif
164 
166  static Status OK() { return Status(); }
167 
168 
180  static Status NotFound(const Slice& msg, const Slice& msg2 = Slice(),
181  int16_t posix_code = -1) {
182  return Status(kNotFound, msg, msg2, posix_code);
183  }
184  static Status Corruption(const Slice& msg, const Slice& msg2 = Slice(),
185  int16_t posix_code = -1) {
186  return Status(kCorruption, msg, msg2, posix_code);
187  }
188  static Status NotSupported(const Slice& msg, const Slice& msg2 = Slice(),
189  int16_t posix_code = -1) {
190  return Status(kNotSupported, msg, msg2, posix_code);
191  }
192  static Status InvalidArgument(const Slice& msg, const Slice& msg2 = Slice(),
193  int16_t posix_code = -1) {
194  return Status(kInvalidArgument, msg, msg2, posix_code);
195  }
196  static Status IOError(const Slice& msg, const Slice& msg2 = Slice(),
197  int16_t posix_code = -1) {
198  return Status(kIOError, msg, msg2, posix_code);
199  }
200  static Status AlreadyPresent(const Slice& msg, const Slice& msg2 = Slice(),
201  int16_t posix_code = -1) {
202  return Status(kAlreadyPresent, msg, msg2, posix_code);
203  }
204  static Status RuntimeError(const Slice& msg, const Slice& msg2 = Slice(),
205  int16_t posix_code = -1) {
206  return Status(kRuntimeError, msg, msg2, posix_code);
207  }
208  static Status NetworkError(const Slice& msg, const Slice& msg2 = Slice(),
209  int16_t posix_code = -1) {
210  return Status(kNetworkError, msg, msg2, posix_code);
211  }
212  static Status IllegalState(const Slice& msg, const Slice& msg2 = Slice(),
213  int16_t posix_code = -1) {
214  return Status(kIllegalState, msg, msg2, posix_code);
215  }
216  static Status NotAuthorized(const Slice& msg, const Slice& msg2 = Slice(),
217  int16_t posix_code = -1) {
218  return Status(kNotAuthorized, msg, msg2, posix_code);
219  }
220  static Status Aborted(const Slice& msg, const Slice& msg2 = Slice(),
221  int16_t posix_code = -1) {
222  return Status(kAborted, msg, msg2, posix_code);
223  }
224  static Status RemoteError(const Slice& msg, const Slice& msg2 = Slice(),
225  int16_t posix_code = -1) {
226  return Status(kRemoteError, msg, msg2, posix_code);
227  }
228  static Status ServiceUnavailable(const Slice& msg, const Slice& msg2 = Slice(),
229  int16_t posix_code = -1) {
230  return Status(kServiceUnavailable, msg, msg2, posix_code);
231  }
232  static Status TimedOut(const Slice& msg, const Slice& msg2 = Slice(),
233  int16_t posix_code = -1) {
234  return Status(kTimedOut, msg, msg2, posix_code);
235  }
236  static Status Uninitialized(const Slice& msg, const Slice& msg2 = Slice(),
237  int16_t posix_code = -1) {
238  return Status(kUninitialized, msg, msg2, posix_code);
239  }
240  static Status ConfigurationError(const Slice& msg, const Slice& msg2 = Slice(),
241  int16_t posix_code = -1) {
242  return Status(kConfigurationError, msg, msg2, posix_code);
243  }
244  static Status Incomplete(const Slice& msg, const Slice& msg2 = Slice(),
245  int64_t posix_code = -1) {
246  return Status(kIncomplete, msg, msg2, posix_code);
247  }
248  static Status EndOfFile(const Slice& msg, const Slice& msg2 = Slice(),
249  int64_t posix_code = -1) {
250  return Status(kEndOfFile, msg, msg2, posix_code);
251  }
253 
255  bool ok() const { return (state_ == NULL); }
256 
258  bool IsNotFound() const { return code() == kNotFound; }
259 
261  bool IsCorruption() const { return code() == kCorruption; }
262 
264  bool IsNotSupported() const { return code() == kNotSupported; }
265 
267  bool IsIOError() const { return code() == kIOError; }
268 
270  bool IsInvalidArgument() const { return code() == kInvalidArgument; }
271 
273  bool IsAlreadyPresent() const { return code() == kAlreadyPresent; }
274 
276  bool IsRuntimeError() const { return code() == kRuntimeError; }
277 
279  bool IsNetworkError() const { return code() == kNetworkError; }
280 
282  bool IsIllegalState() const { return code() == kIllegalState; }
283 
285  bool IsNotAuthorized() const { return code() == kNotAuthorized; }
286 
288  bool IsAborted() const { return code() == kAborted; }
289 
291  bool IsRemoteError() const { return code() == kRemoteError; }
292 
294  bool IsServiceUnavailable() const { return code() == kServiceUnavailable; }
295 
297  bool IsTimedOut() const { return code() == kTimedOut; }
298 
300  bool IsUninitialized() const { return code() == kUninitialized; }
301 
303  bool IsConfigurationError() const { return code() == kConfigurationError; }
304 
306  bool IsIncomplete() const { return code() == kIncomplete; }
307 
309  bool IsEndOfFile() const { return code() == kEndOfFile; }
310 
313  std::string ToString() const;
314 
317  std::string CodeAsString() const;
318 
327  Slice message() const;
328 
331  int16_t posix_code() const;
332 
339  Status CloneAndPrepend(const Slice& msg) const;
340 
347  Status CloneAndAppend(const Slice& msg) const;
348 
351  size_t memory_footprint_excluding_this() const;
352 
355  size_t memory_footprint_including_this() const;
356 
357  private:
358  // OK status has a NULL state_. Otherwise, state_ is a new[] array
359  // of the following form:
360  // state_[0..3] == length of message
361  // state_[4] == code
362  // state_[5..6] == posix_code
363  // state_[7..] == message
364  const char* state_;
365 
366  enum Code {
367  kOk = 0,
368  kNotFound = 1,
369  kCorruption = 2,
370  kNotSupported = 3,
371  kInvalidArgument = 4,
372  kIOError = 5,
373  kAlreadyPresent = 6,
374  kRuntimeError = 7,
375  kNetworkError = 8,
376  kIllegalState = 9,
377  kNotAuthorized = 10,
378  kAborted = 11,
379  kRemoteError = 12,
380  kServiceUnavailable = 13,
381  kTimedOut = 14,
382  kUninitialized = 15,
383  kConfigurationError = 16,
384  kIncomplete = 17,
385  kEndOfFile = 18,
386  // NOTE: Remember to duplicate these constants into wire_protocol.proto and
387  // and to add StatusTo/FromPB ser/deser cases in wire_protocol.cc !
388  // Also remember to make the same changes to the java client in Status.java.
389  //
390  // TODO: Move error codes into an error_code.proto or something similar.
391  };
392  COMPILE_ASSERT(sizeof(Code) == 4, code_enum_size_is_part_of_abi);
393 
394  Code code() const {
395  return (state_ == NULL) ? kOk : static_cast<Code>(state_[4]);
396  }
397 
398  Status(Code code, const Slice& msg, const Slice& msg2, int16_t posix_code);
399  static const char* CopyState(const char* s);
400 };
401 
402 inline Status::Status(const Status& s) {
403  state_ = (s.state_ == NULL) ? NULL : CopyState(s.state_);
404 }
405 
406 inline Status& Status::operator=(const Status& s) {
407  // The following condition catches both aliasing (when this == &s),
408  // and the common case where both s and *this are OK.
409  if (state_ != s.state_) {
410  delete[] state_;
411  state_ = (s.state_ == NULL) ? NULL : CopyState(s.state_);
412  }
413  return *this;
414 }
415 
416 #if __cplusplus >= 201103L
417 inline Status::Status(Status&& s) : state_(s.state_) {
418  s.state_ = nullptr;
419 }
420 
421 inline Status& Status::operator=(Status&& s) {
422  if (state_ != s.state_) {
423  delete[] state_;
424  state_ = s.state_;
425  s.state_ = nullptr;
426  }
427  return *this;
428 }
429 #endif
430 
431 } // namespace kudu
432 
433 #endif // KUDU_UTIL_STATUS_H_
Status()
Create an object representing success status.
Definition: status.h:133
bool IsNotAuthorized() const
Definition: status.h:285
A representation of an operation&#39;s outcome.
Definition: status.h:130
bool IsIllegalState() const
Definition: status.h:282
Definition: callbacks.h:28
bool ok() const
Definition: status.h:255
bool IsTimedOut() const
Definition: status.h:297
bool IsRemoteError() const
Definition: status.h:291
bool IsServiceUnavailable() const
Definition: status.h:294
bool IsAborted() const
Definition: status.h:288
bool IsUninitialized() const
Definition: status.h:300
bool IsRuntimeError() const
Definition: status.h:276
bool IsAlreadyPresent() const
Definition: status.h:273
bool IsIOError() const
Definition: status.h:267
static Status OK()
Definition: status.h:166
A wrapper around externally allocated data.
Definition: slice.h:43
Status & operator=(const Status &s)
Definition: status.h:406
bool IsConfigurationError() const
Definition: status.h:303
bool IsInvalidArgument() const
Definition: status.h:270
bool IsCorruption() const
Definition: status.h:261
bool IsEndOfFile() const
Definition: status.h:309
bool IsNotSupported() const
Definition: status.h:264
bool IsNetworkError() const
Definition: status.h:279
bool IsIncomplete() const
Definition: status.h:306
bool IsNotFound() const
Definition: status.h:258