[leveldb] 学习leveldb第一个类Status

[TOC]

回顾上一篇文章《[leveldb] 初步探索 leveldb》的样例代码,是不是发现有个类比例简单:leveldb::Status,你发现它有status.ok()status.ToString()方法。那怎么找到Status类的定义和成员方法的实现呢?

1、 第一步:把相关代码找出来

1-1 用grep 大法过滤内容

我们知道C++的类一般是这样定义的:class Status {...},我们grep在当前目前递归-r .全词匹配-w和半词匹配都搜不到,最后grep "Status {"出来了,并显示代码所在行数-n

wu_being@UbuntuKylin1704:~/Github/leveldb$ grep "class Status" -rnw .
wu_being@UbuntuKylin1704:~/Github/leveldb$ grep "class Status" -rn .
wu_being@UbuntuKylin1704:~/Github/leveldb$ grep "Status{" -rn .
wu_being@UbuntuKylin1704:~/Github/leveldb$ grep "Status {" -rn .
./include/leveldb/status.h:22:class LEVELDB_EXPORT Status {
wu_being@UbuntuKylin1704:~/Github/leveldb$ 

这个就是Status类定义的头文件:

./include/leveldb/status.h:22:class LEVELDB_EXPORT Status {

1-2 用find 大法找到文件

我们发现上面grep大法连文件名都过滤出来,下面用find大法通过文件名匹配到相关文件,找到一个Status类方法实现的文件./util/status.cc

wu_being@UbuntuKylin1704:~/Github/leveldb$
wu_being@UbuntuKylin1704:~/Github/leveldb$ find . -name status.
./util/status.cc
./util/status.o
./out-static/util/status.o
./include/leveldb/status.h
./out-shared/util/status.o
wu_being@UbuntuKylin1704:~/Github/leveldb$ 

2、 第二步:RTFSC (Read the fucking source code )

wu_being@UbuntuKylin1704:~/Github/leveldb$
wu_being@UbuntuKylin1704:~/Github/leveldb$ gedit include/leveldb/status.h &
[2] 3936
wu_being@UbuntuKylin1704:~/Github/leveldb$ gedit util/status.cc
[2]+  已完成               gedit include/leveldb/status.h
wu_being@UbuntuKylin1704:~/Github/leveldb$ 

2-1 include/leveldb/status.h

#ifndef STORAGE_LEVELDB_INCLUDE_STATUS_H_
#define STORAGE_LEVELDB_INCLUDE_STATUS_H_

#include <string>
#include "leveldb/export.h"
#include "leveldb/slice.h"

namespace leveldb {

class LEVELDB_EXPORT Status {
 public:
  // Create a success status.
  Status() : state_(NULL) { }
  ~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);
  }
...

  // 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.
  // status.cc
  std::string ToString() const;

 private:
  // 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.cc
  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_);
  }
}

}  // namespace leveldb

#endif  // STORAGE_LEVELDB_INCLUDE_STATUS_H_

2-1-1 类Status公有成员变量和方法

构造函数

 public:
  // Create a success status.
  Status() : state_(NULL) { }

  // Copy the specified status.
  Status(const Status& s);
  void operator=(const Status& 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_);
  }
}

析构函数

  ~Status() { delete[] state_; }

2-1-2 类Status私有成员变量和方法

私有成员变量

下面这个state_设计很不好调试,在后面的CopyState方法就是了,没有手工调试配制state_。

 // 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.cc
  Status(Code code, const Slice& msg, const Slice& msg2);
  static const char CopyState(const char s);

2-2 util/status.cc


#include <stdio.h>
#include "port/port.h"
#include "leveldb/status.h"

namespace leveldb {

const char Status::CopyState(const char state) {
  uint32_t size;
  memcpy(&size, state, sizeof(size));

  char* result = new char[size + 5];
  memcpy(result, state, size + 5);

  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 + 5];
  memcpy(result, &size, sizeof(size));
  result[4] = static_cast<char>(code);
  memcpy(result + 5, 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;
...
      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;
  }
}

}  // namespace leveldb

Status::CopyState

 // 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 Status::CopyState(const char state) {
  uint32_t size; //sizeof(size)为4
  memcpy(&size, state, sizeof(size));//把state前面4个length of message字符给size

  char* result = new char[size + 5];
  memcpy(result, state, size + 5);

  return result;
}

Status::ToString() const


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;
...
      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::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 + 5];
  memcpy(result, &size, sizeof(size));
  result[4] = static_cast<char>(code);
  memcpy(result + 5, msg.data(), len1);
  if (len2) {
    result[5 + len1] = ':';
    result[6 + len1] = ' ';
    memcpy(result + 7 + len1, msg2.data(), len2);
  }
  state_ = result;
}

Wu_Being博客声明:本人博客欢迎转载,请标明博客原文和原链接!谢谢!
《[leveldb] 学习leveldb第一个类Status》: /

如果你看完这篇博文,觉得对你有帮助,并且愿意付赞助费,那么我会更有动力写下去。

时间: 2024-12-29 10:52:29

[leveldb] 学习leveldb第一个类Status的相关文章

[leveldb] 初探 leveldb

[TOC] 1. leveldb 简介 leveldb 是 Google 用 C++ 开发的一个快速的 键值对存储数据库(持久化KV单机数据库),提供从字符串键到字符串值的有序映射,具有很高的随机写,顺序读/写性能,但是随机读的性能很一般,也就是说,LevelDB很适合应用在查询较少,而写很多的场景. LevelDB应用了 LSM (Log Structured Merge) 策略,lsm_tree对索引变更进行延迟及批量处理,并通过一种类似于归并排序的方式高效地将更新迁移到磁盘,降低索引插入开

C#学习之结构与类的区别

区别 最近有看到网上面试题提到结构鱼类的区别,遂查看了msdn以及一些网上的资料总结了一下,一做学习之用 C#学习之结构与类的区别数据结构和类实际上都是创建对象的模版,每个对象都包含数据,并提供了处理和访问数据的方法.在语法上,非常相似,主要是使用关键字的区别.对于类和结构,都是使用关键字new来声明实例:这个关键字对象创建对象,并对其进行初始化. 1.值类型和引用类型结构是指类型,指类型在堆栈(栈)上分配地址,C#中的所有基类型都是结构类型(例如:int对应System.Int32结构):类是

初学者求教,C++中在类内声明一个struct和另一个类,在类外怎么定义

问题描述 初学者求教,C++中在类内声明一个struct和另一个类,在类外怎么定义 template class List{ struct Node{}; ... class const_iterator{}; class iterator:public const_iterator{}; ... }; struct Node{ Object data; ... }; 这样定义出现了错误,但不知如何解决.并且模板Object在struct Node为何无法使用? 解决方案 类中定义一个stati

java-声明一个类,可使用的权限修饰符为什么不能用protected和privatr

问题描述 声明一个类,可使用的权限修饰符为什么不能用protected和privatr 声明一个类,可使用的权限修饰符为什么不能用protected和privatr 解决方案 私有的类,不能用,有何意义? 解决方案二: 这是java语法的规定,类的修饰符号有:public 公共类:default 默认包内访问权限(即class前什么都不假):abstract 抽象类: fanal 不能被继承的类: static 静态类: private 只能修饰内部类,一般不推荐使用. 解决方案三: 公开的可以

java-对一个list中一个类的困扰

问题描述 对一个list中一个类的困扰 我参考的这个文档学习的livewallpaper.这里我有一些地方不太明白. 教程中的示例代码中有个MyPoint类 public class MyPoint { String text; private int x; private int y; public MyPoint(String text, int x, int y) { this.text = text; this.x = x; this.y = y; } } 然后又创建了一个MyWallp

在线等!一个类的设计问题,咋这么个问题就难倒我了,悲哀啊!

问题描述 各位大侠好,现在有一个关于建立实体的难题:业务逻辑如下:炼钢厂连铸机有3个段:5段.6段.7段,每个段有如下数据(压力.位移.电流)需要表示:压力:压力又分为A口压力.B口压力位移:位移又分为缸1位移.缸2位移.缸3位移.缸4位移电流:电流又分为上辊电流.下辊电流那么5段需要表示的数据就有:5段上辊电流.5段下辊电流.5段1缸位移.5段2缸位移.5段3缸位移.5段4缸位移.5段A口压力.5段B口压力请问这些个实体类怎么建立啊,头痛死我了! 解决方案 解决方案二:sf解决方案三:枚举吧解

apache utils工具类-怎么学习Apache commons utils类

问题描述 怎么学习Apache commons utils类 本人菜鸟一个,最近在看apache commons源码,发现里面有好多好多的工具类啊, 真心佩服大牛们的默默付出,但是太多了,看不过来啊,怎么办?难道全部都要记住么 解决方案 学好英语就可以了,java函数的命名都是英文单词,如果你能理解字面上的意思,不用记忆,你就自动知道了90%的函数的作用.剩下10%,看看文档源码或者google下,也就分分钟搞定. 解决方案二: Apache官网 这个里面有如何使用和快速入门和API 解决方案三

自己定义的一个类,为什么不能将它实例化成对象数组?

问题描述 如题,我自己定义了一个类,里面封装了一些属性,但是在实例化此类时,却总是出现NonePointException异常.有高人能指点一下原因吗?这是我定义的类:publicclassEmailMessage{privateStringfrom=null;privateStringto=null;privateStringreceive=null;privateStringsubject=null;privateStringcontent=null;privateStringfileNam

一个类应该要么声称,“你不能破坏我,我对你来说是个黑盒”,要么“我已经被破坏了;先修复我然后再使用我”(转)

  英文原文:Seven Virtues of a Good Object Marin Folwer 说过: "库本质上是一组可以调用的函数,这些函数现在经常被组织到类中." 函数组织到类中?恕我冒昧,这个观点是错误的.而且这是对面向对象编程中类的非常普遍的误解.类不是函数的组织者,对象也不是数据结构. 那么什么是"合理的"对象呢?哪些不合理呢?区别又是什么?虽然这是个争论比较激烈的主题,但同时也是非常重要的.如果我们不了解对象到底是什么,我们怎么才能编写出面向对象