levelDB源码分析-Status
2012-06-14 15:54
330 查看
leveldb::Status表示levelDB的一个返回状态,通常的错误处理(如:errno)是返回一个错误号,然后根据错误号可以获得出错的描述信息。
leveldb将错误号和错误信息封装成Status类,来统一进行处理。
声明如下:
实现如下:
使用方法:
leveldb将错误号和错误信息封装成Status类,来统一进行处理。
声明如下:
class Status { public: // Create a success status. Status() : state_(NULL) { } // 构造函数,默认状态为success ~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(); } // 返回一个success的状态 // 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); } // Returns true iff the status indicates success. bool ok() const { return (state_ == NULL); } // Returns true iff the status indicates a NotFound error. bool IsNotFound() const { return code() == kNotFound; } // Return a string representation of this status suitable for printing. // Returns the string "OK" for success. std::string ToString() const; private: // 为了节省空间Status并没有用std::string来存储错误信息, // 而是将返回码(Code), 错误信息msg及长度打包存储于一个字符串数组中。 // OK status has a NULL 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 }; Code code() const { // 返回状态码 return (state_ == NULL) ? 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_ == NULL) ? NULL : 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_ == NULL) ? NULL : CopyState(s.state_); } } const char* Status::CopyState(const char* state) { // 复制状态字符串 uint32_t size; memcpy(&size, state, sizeof(size)); uint32_t len = size + sizeof(size) + 1 ; char* result = new char[len]; memcpy(result, state, len); return result; } Status::Status(Code code, const Slice& msg, const Slice& msg2) { // 内部构造函数 assert(code != kOk); const uint32_t len1 = msg.size(); const uint32_t len2 = msg2.size(); const uint32_t size = len1 + (len2 ? (2 + len2) : 0); char* result = new char[size + 6]; // 没有结束符? --- 由于保留了size字段,采用memcpy指定size操作,可以没有结束符 memcpy(result, &size, sizeof(size)); result[4] = static_cast<char>(code); // 第5个字节存放code //memcpy(result + 5, msg.data(), len1); memcpy(result + sizeof(size) + 1, msg.data(), len1); if (len2) { result[5 + len1] = ':'; result[6 + len1] = ' '; memcpy(result + 7 + len1, msg2.data(), len2); } state_ = result; } std::string Status::ToString() const { // 返回状态字符串 if (state_ == NULL) { return "OK"; } else { char tmp[30]; const char* type; switch (code()) { case kOk: type = "OK"; break; 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; default: snprintf(tmp, sizeof(tmp), "Unknown code(%d): ", static_cast<int>(code())); type = tmp; break; } std::string result(type); uint32_t length; memcpy(&length, state_, sizeof(length)); result.append(state_ + 5, length); // 状态字符串 return result; } }
使用方法:
Status status_ = Status::Corruption("bad entry in block"); Status::Corruption("bad block contents") ; Status::InvalidArgument((string)dbname_, "does not exist (create_if_missing is false)"); Status::Corruption("log record too small"); Status s = Status::IOError("Deleting DB during memtable compaction"); Status::OK() ; status.ToString() ;
相关文章推荐
- 二,leveldb源码分析(status)
- LevelDB源码分析4-Status
- leveldb源码分析入手
- leveldb源码分析--BloomFilter
- goleveldb源码分析-key的存储和构成
- Leveldb源码分析--17
- Leveldb源码分析
- Leveldb源码分析--22
- leveldb源码分析四
- [Leveldb]源码分析之三 BloomFilter模块的实现
- leveldb源码分析--SSTable之Compaction 详解
- LevelDB源码分析1-基础
- Leveldb源码分析--4
- LevelDB源码分析之八:memtable
- levelDB源码分析-SSTable
- Leveldb源码分析--8
- Leveldb源码分析--21
- LevelDB源码分析之四:AtomicPointer
- leveldb源码分析--SSTable之逻辑结构
- Leveldb源码分析--8