status.cc 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
  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).
  5. //
  6. // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
  7. // Use of this source code is governed by a BSD-style license that can be
  8. // found in the LICENSE file. See the AUTHORS file for names of contributors.
  9. #include "rocksdb/status.h"
  10. #include <cstdio>
  11. #ifdef OS_WIN
  12. #include <string.h>
  13. #endif
  14. #include <cstring>
  15. #include "port/port.h"
  16. namespace ROCKSDB_NAMESPACE {
  17. std::unique_ptr<const char[]> Status::CopyState(const char* s) {
  18. const size_t cch = std::strlen(s) + 1; // +1 for the null terminator
  19. char* rv = new char[cch];
  20. std::strncpy(rv, s, cch);
  21. return std::unique_ptr<const char[]>(rv);
  22. }
  23. static const char* msgs[static_cast<int>(Status::kMaxSubCode)] = {
  24. "", // kNone
  25. "Timeout Acquiring Mutex", // kMutexTimeout
  26. "Timeout waiting to lock key", // kLockTimeout
  27. "Failed to acquire lock due to max_num_locks limit", // kLockLimit
  28. "No space left on device", // kNoSpace
  29. "Deadlock", // kDeadlock
  30. "Stale file handle", // kStaleFile
  31. "Memory limit reached", // kMemoryLimit
  32. "Space limit reached", // kSpaceLimit
  33. "No such file or directory", // kPathNotFound
  34. // KMergeOperandsInsufficientCapacity
  35. "Insufficient capacity for merge operands",
  36. // kManualCompactionPaused
  37. "Manual compaction paused",
  38. " (overwritten)", // kOverwritten, subcode of OK
  39. "Txn not prepared", // kTxnNotPrepared
  40. "IO fenced off", // kIOFenced
  41. "Merge operator failed", // kMergeOperatorFailed
  42. "Number of operands merged exceeded threshold", // kMergeOperandThresholdExceeded
  43. "MultiScan reached file prefetch limit", // kMultiScanPrefetchLimit
  44. };
  45. Status::Status(Code _code, SubCode _subcode, const Slice& msg,
  46. const Slice& msg2, Severity sev)
  47. : code_(_code),
  48. subcode_(_subcode),
  49. sev_(sev),
  50. retryable_(false),
  51. data_loss_(false),
  52. scope_(0) {
  53. assert(subcode_ != kMaxSubCode);
  54. const size_t len1 = msg.size();
  55. const size_t len2 = msg2.size();
  56. const size_t size = len1 + (len2 ? (2 + len2) : 0);
  57. char* const result = new char[size + 1]; // +1 for null terminator
  58. memcpy(result, msg.data(), len1);
  59. if (len2) {
  60. result[len1] = ':';
  61. result[len1 + 1] = ' ';
  62. memcpy(result + len1 + 2, msg2.data(), len2);
  63. }
  64. result[size] = '\0'; // null terminator for C style string
  65. state_.reset(result);
  66. }
  67. Status Status::CopyAppendMessage(const Status& s, const Slice& delim,
  68. const Slice& msg) {
  69. // (No attempt at efficiency)
  70. return Status(s.code(), s.subcode(), s.severity(),
  71. std::string(s.getState()) + delim.ToString() + msg.ToString());
  72. }
  73. std::string Status::ToString() const {
  74. #ifdef ROCKSDB_ASSERT_STATUS_CHECKED
  75. checked_ = true;
  76. #endif // ROCKSDB_ASSERT_STATUS_CHECKED
  77. const char* type = nullptr;
  78. switch (code_) {
  79. case kOk:
  80. return "OK";
  81. case kNotFound:
  82. type = "NotFound: ";
  83. break;
  84. case kCorruption:
  85. type = "Corruption: ";
  86. break;
  87. case kNotSupported:
  88. type = "Not implemented: ";
  89. break;
  90. case kInvalidArgument:
  91. type = "Invalid argument: ";
  92. break;
  93. case kIOError:
  94. type = "IO error: ";
  95. break;
  96. case kMergeInProgress:
  97. type = "Merge in progress: ";
  98. break;
  99. case kIncomplete:
  100. type = "Result incomplete: ";
  101. break;
  102. case kShutdownInProgress:
  103. type = "Shutdown in progress: ";
  104. break;
  105. case kTimedOut:
  106. type = "Operation timed out: ";
  107. break;
  108. case kAborted:
  109. type = "Operation aborted: ";
  110. break;
  111. case kBusy:
  112. type = "Resource busy: ";
  113. break;
  114. case kExpired:
  115. type = "Operation expired: ";
  116. break;
  117. case kTryAgain:
  118. type = "Operation failed. Try again.: ";
  119. break;
  120. case kCompactionTooLarge:
  121. type = "Compaction too large: ";
  122. break;
  123. case kColumnFamilyDropped:
  124. type = "Column family dropped: ";
  125. break;
  126. case kMaxCode:
  127. assert(false);
  128. break;
  129. }
  130. char tmp[30];
  131. if (type == nullptr) {
  132. // This should not happen since `code_` should be a valid non-`kMaxCode`
  133. // member of the `Code` enum. The above switch-statement should have had a
  134. // case assigning `type` to a corresponding string.
  135. assert(false);
  136. snprintf(tmp, sizeof(tmp), "Unknown code(%d): ", static_cast<int>(code()));
  137. type = tmp;
  138. }
  139. std::string result(type);
  140. if (subcode_ != kNone) {
  141. uint32_t index = static_cast<int32_t>(subcode_);
  142. assert(sizeof(msgs) / sizeof(msgs[0]) > index);
  143. result.append(msgs[index]);
  144. }
  145. if (state_ != nullptr) {
  146. if (subcode_ != kNone) {
  147. result.append(": ");
  148. }
  149. result.append(state_.get());
  150. }
  151. return result;
  152. }
  153. } // namespace ROCKSDB_NAMESPACE