mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Summary: If ReadOptions.non_blocking_io is set to true, then KeyMayExists and Iterators will return data that is cached in RAM. If the Iterator needs to do IO from storage to serve the data, then the Iterator.status() will return Status::IsRetry(). Test Plan: Enhanced unit test DBTest.KeyMayExist to detect if there were are IOs issues from storage. Added DBTest.NonBlockingIteration to verify nonblocking Iterations. Reviewers: emayanke, haobo Reviewed By: haobo CC: leveldb Maniphest Tasks: T63 Differential Revision: https://reviews.facebook.net/D12531
127 lines
4.1 KiB
C++
127 lines
4.1 KiB
C++
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
|
//
|
|
// A Status encapsulates the result of an operation. It may indicate success,
|
|
// or it may indicate an error with an associated error message.
|
|
//
|
|
// Multiple threads can invoke const methods on a Status without
|
|
// external synchronization, but if any of the threads may call a
|
|
// non-const method, all threads accessing the same Status must use
|
|
// external synchronization.
|
|
|
|
#ifndef STORAGE_ROCKSDB_INCLUDE_STATUS_H_
|
|
#define STORAGE_ROCKSDB_INCLUDE_STATUS_H_
|
|
|
|
#include <string>
|
|
#include "rocksdb/slice.h"
|
|
|
|
namespace leveldb {
|
|
|
|
class Status {
|
|
public:
|
|
// Create a success status.
|
|
Status() : state_(nullptr) { }
|
|
~Status() { delete[] state_; }
|
|
|
|
// Copy the specified status.
|
|
Status(const Status& s);
|
|
void operator=(const Status& s);
|
|
|
|
// Return a success status.
|
|
static Status OK() { return Status(); }
|
|
|
|
// Return error status of an appropriate type.
|
|
static Status NotFound(const Slice& msg, const Slice& msg2 = Slice()) {
|
|
return Status(kNotFound, msg, msg2);
|
|
}
|
|
static Status Corruption(const Slice& msg, const Slice& msg2 = Slice()) {
|
|
return Status(kCorruption, msg, msg2);
|
|
}
|
|
static Status NotSupported(const Slice& msg, const Slice& msg2 = Slice()) {
|
|
return Status(kNotSupported, msg, msg2);
|
|
}
|
|
static Status InvalidArgument(const Slice& msg, const Slice& msg2 = Slice()) {
|
|
return Status(kInvalidArgument, msg, msg2);
|
|
}
|
|
static Status IOError(const Slice& msg, const Slice& msg2 = Slice()) {
|
|
return Status(kIOError, msg, msg2);
|
|
}
|
|
static Status MergeInProgress(const Slice& msg, const Slice& msg2 = Slice()) {
|
|
return Status(kMergeInProgress, msg, msg2);
|
|
}
|
|
static Status Incomplete(const Slice& msg, const Slice& msg2 = Slice()) {
|
|
return Status(kIncomplete, msg, msg2);
|
|
}
|
|
|
|
// Returns true iff the status indicates success.
|
|
bool ok() const { return (state_ == nullptr); }
|
|
|
|
// Returns true iff the status indicates a NotFound error.
|
|
bool IsNotFound() const { return code() == kNotFound; }
|
|
|
|
// Returns true iff the status indicates a Corruption error.
|
|
bool IsCorruption() const { return code() == kCorruption; }
|
|
|
|
// Returns true iff the status indicates a NotSupported error.
|
|
bool IsNotSupported() const { return code() == kNotSupported; }
|
|
|
|
// Returns true iff the status indicates an InvalidArgument error.
|
|
bool IsInvalidArgument() const { return code() == kInvalidArgument; }
|
|
|
|
// Returns true iff the status indicates an IOError.
|
|
bool IsIOError() const { return code() == kIOError; }
|
|
|
|
// Returns true iff the status indicates an MergeInProgress.
|
|
bool IsMergeInProgress() const { return code() == kMergeInProgress; }
|
|
|
|
// Returns true iff the status indicates Incomplete
|
|
bool IsIncomplete() const { return code() == kIncomplete; }
|
|
|
|
// Return a string representation of this status suitable for printing.
|
|
// Returns the string "OK" for success.
|
|
std::string ToString() const;
|
|
|
|
private:
|
|
// OK status has a nullptr state_. Otherwise, state_ is a new[] array
|
|
// of the following form:
|
|
// state_[0..3] == length of message
|
|
// state_[4] == code
|
|
// state_[5..] == message
|
|
const char* state_;
|
|
|
|
enum Code {
|
|
kOk = 0,
|
|
kNotFound = 1,
|
|
kCorruption = 2,
|
|
kNotSupported = 3,
|
|
kInvalidArgument = 4,
|
|
kIOError = 5,
|
|
kMergeInProgress = 6,
|
|
kIncomplete = 7
|
|
};
|
|
|
|
Code code() const {
|
|
return (state_ == nullptr) ? kOk : static_cast<Code>(state_[4]);
|
|
}
|
|
|
|
Status(Code code, const Slice& msg, const Slice& msg2);
|
|
static const char* CopyState(const char* s);
|
|
};
|
|
|
|
inline Status::Status(const Status& s) {
|
|
state_ = (s.state_ == nullptr) ? nullptr : CopyState(s.state_);
|
|
}
|
|
inline void Status::operator=(const Status& s) {
|
|
// The following condition catches both aliasing (when this == &s),
|
|
// and the common case where both s and *this are ok.
|
|
if (state_ != s.state_) {
|
|
delete[] state_;
|
|
state_ = (s.state_ == nullptr) ? nullptr : CopyState(s.state_);
|
|
}
|
|
}
|
|
|
|
} // namespace leveldb
|
|
|
|
#endif // STORAGE_ROCKSDB_INCLUDE_STATUS_H_
|