leveldb status学习

来源:互联网 发布:淘宝怎么设置淘宝客 编辑:程序博客网 时间:2024/06/05 03:52

学习了 巴山独钓 的levelDB源码分析-Status
1. 主要的声明和inline定义(隐式inline和显式inline关键字定义)都放在了status.h文件中。 只有CopyState,Status和ToString这3个代码比较多和复杂一些的函数放在了status.cc文件中去定义。
2. 发现leveldb中的显式inline都是采用如下形式定义在.h文件中。 我自己的话一般会在声明的同时显式inline定义,以后要学习leveldb中的用法,毕竟把声明和定义分离开更加清晰。 至于隐式inline的,那是因为定义式的代码本来就1-2行,声明式和定义式放一起也不影响清晰性。
3. status类主要是封装了一个数组const char* state_; 至于这个变长数组的定义格式,源码注释写的很清楚,前4字节是长度,第5字节是错误code,第6字节以后是message。 错误code使用了enum进行了声明。总计是6种,名字都是k打头,这是谷歌规范里面的规定的,静态常量以k打头。

// 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  };
  1. 由于state_的格式是固定的,所以像code()函数,也就是获取status对象的code码,可以直接取state_ 的第5个元素。
  Code code() const {    return (state_ == NULL) ? kOk : static_cast<Code>(state_[4]);  }
  1. 分析下 函数CopyState,也是利用state_的格式是已知的固定格式,来取得数据长度,进行mycpy的。
const char* Status::CopyState(const char* state) {  uint32_t size;  //message的长度  memcpy(&size, state, sizeof(size)); //state的前4字节正好是表示message长度的。  char* result = new char[size + 5]; //state的长度是前面5个固定字节,再加上message的长度。 用此长度new出来数组。  memcpy(result, state, size + 5); //将state的内容取size+5产固定,copy到新new出来的数组result里  return result;}
  1. 分析下构造函数Status,也是利用固定格式的state_
Status::Status(Code code, const Slice& msg, const Slice& msg2) {  assert(code != kOk);  //如果是kOk,直接就是个空对象嘛。  const uint32_t len1 = msg.size(); //用到的第一个msg的长度  const uint32_t len2 = msg2.size();//用到的第一个msg的长度  const uint32_t size = len1 + (len2 ? (2 + len2) : 0);//总长度是len1+len2+2,原因是msg和msg2之间要用:加上空格符号隔开  char* result = new char[size + 5];// size是新message的长度,还要加上5个字节的固定长度。  其中前4个字节是表示新message有多长的,第5个字节表示code码是啥的。  memcpy(result, &size, sizeof(size)); //前4个字节是表示新message多长的,直接用memcpy效率高啊。  result[4] = static_cast<char>(code);//第5个字节放置表示code嘛是啥的,这里把enum转换成了char类型。  memcpy(result + 5, msg.data(), len1); //先copy第一个msg到新message的内存里  if (len2) {    result[5 + len1] = ':';  //第一个msg后加:符号    result[6 + len1] = ' ';  //然后再加空格符号    memcpy(result + 7 + len1, msg2.data(), len2); //最后把msg2整个copy到新message里。 注意这里的指针已经是result+7+len1了, 7是:符号加上空格符号,加上新messag的前5个固定字节。  }  state_ = result;}