#include "rocksdb/status.h"
#include <cstdio>
#ifdef OS_WIN
#include <string.h>
#endif
#include <cstring>
#include "port/port.h"
namespace ROCKSDB_NAMESPACE {
std::unique_ptr<const char[]> Status::CopyState(const char* s) {
const size_t cch = std::strlen(s) + 1; char* rv = new char[cch];
std::strncpy(rv, s, cch);
return std::unique_ptr<const char[]>(rv);
}
static const char* msgs[static_cast<int>(Status::kMaxSubCode)] = {
"", "Timeout Acquiring Mutex", "Timeout waiting to lock key", "Failed to acquire lock due to max_num_locks limit", "No space left on device", "Deadlock", "Stale file handle", "Memory limit reached", "Space limit reached", "No such file or directory", "Insufficient capacity for merge operands",
"Manual compaction paused",
" (overwritten)", "Txn not prepared", "IO fenced off", "Merge operator failed", "Number of operands merged exceeded threshold", "MultiScan reached file prefetch limit", "Not expected code path", "All compactions aborted", };
Status::Status(Code _code, SubCode _subcode, const Slice& msg,
const Slice& msg2, Severity sev)
: code_(_code),
subcode_(_subcode),
sev_(sev),
retryable_(false),
data_loss_(false),
scope_(0) {
assert(subcode_ != kMaxSubCode);
const size_t len1 = msg.size();
const size_t len2 = msg2.size();
const size_t size = len1 + (len2 ? (2 + len2) : 0);
char* const result = new char[size + 1]; memcpy(result, msg.data(), len1);
if (len2) {
result[len1] = ':';
result[len1 + 1] = ' ';
memcpy(result + len1 + 2, msg2.data(), len2);
}
result[size] = '\0'; state_.reset(result);
}
Status Status::CopyAppendMessage(const Status& s, const Slice& delim,
const Slice& msg) {
return Status(s.code(), s.subcode(), s.severity(),
std::string(s.getState()) + delim.ToString() + msg.ToString());
}
std::string Status::ToString() const {
#ifdef ROCKSDB_ASSERT_STATUS_CHECKED
checked_ = true;
#endif const char* type = nullptr;
switch (code_) {
case kOk:
return "OK";
case kNotFound:
type = "NotFound: ";
break;
case kCorruption:
type = "Corruption: ";
break;
case kNotSupported:
type = "Not implemented: ";
break;
case kInvalidArgument:
type = "Invalid argument: ";
break;
case kIOError:
type = "IO error: ";
break;
case kMergeInProgress:
type = "Merge in progress: ";
break;
case kIncomplete:
type = "Result incomplete: ";
break;
case kShutdownInProgress:
type = "Shutdown in progress: ";
break;
case kTimedOut:
type = "Operation timed out: ";
break;
case kAborted:
type = "Operation aborted: ";
break;
case kBusy:
type = "Resource busy: ";
break;
case kExpired:
type = "Operation expired: ";
break;
case kTryAgain:
type = "Operation failed. Try again.: ";
break;
case kCompactionTooLarge:
type = "Compaction too large: ";
break;
case kColumnFamilyDropped:
type = "Column family dropped: ";
break;
case kMaxCode:
assert(false);
break;
}
char tmp[30];
if (type == nullptr) {
assert(false);
snprintf(tmp, sizeof(tmp), "Unknown code(%d): ", static_cast<int>(code()));
type = tmp;
}
std::string result(type);
if (subcode_ != kNone) {
uint32_t index = static_cast<int32_t>(subcode_);
assert(sizeof(msgs) / sizeof(msgs[0]) > index);
result.append(msgs[index]);
}
if (state_ != nullptr) {
if (subcode_ != kNone) {
result.append(": ");
}
result.append(state_.get());
}
return result;
}
}