频道栏目
首页 > 资讯 > 其他综合 > 正文

关于leveldb源码整理

17-07-24        来源:[db:作者]  
收藏   我要投稿

正文

工欲善其事必先利其器,我们这里因为需要添加一些测试代码,所以编译机会比较多,我们在我们的makefile中加入一句:

.PHONY: test
test: $(STATIC_OUTDIR)/dbformat_test

以后每次阅读关于dbformatetest的代码时候,就可以直接make test了。
我们进入昨天一小段代码继续看

ASSERT_EQ(IKey("g", kMaxSequenceNumber, kValueTypeForSeek),
            ShortSuccessor(IKey("foo", 100, kTypeValue)));

这里我们知道这个ASSERT_TEST就是判断传入的参数是不是一样。我们可以进入本篇博客的问题空间了。这里我们可以了解到kMaxSequenceNumber是56个1,打小在这里毫无意义,就反正很大很大,kTypeValue 为1.
看下IKey函数到底干了啥,这里我们一一追踪。首先

static std::string IKey(const std::string& user_key,
                        uint64_t seq,
                        ValueType vt) {
  std::string encoded;
  AppendInternalKey(&encoded, ParsedInternalKey(user_key, seq, vt));
  return encoded;
}

这里我们先解决下ParsedInternalKey这个函数干了啥。这个函数其实干的事情很少,这是一个结构体的构造函数:

ParsedInternalKey(const Slice& u, const SequenceNumber& seq, ValueType t)
      : user_key(u), sequence(seq), type(t) {
            fprintf(stderr, "==== Test %s\n", "ParsedInternalKey");       }

这里有个问题,我们传入的是个std::string数据,但是最后变成Slice,因为我们会发现Slice有个string为参数的构造函数,这里很容易想到是编译器直接改变传入参数的。这里这个特性,大概就是这个道理,关于Slice的功能,这里就不详细介绍,很简单。这个构造函数,其实就是把传入的三个参数,都保存在三个变量中:

  Slice user_key;
  SequenceNumber sequence;
  ValueType type;

这里我们很容易的知道这里是干啥的,可以暂时记住,这里要作为参数传入关键的函数,进行编码,我们开始我们本次博客的正餐。

  void AppendInternalKey(std::string* result, const ParsedInternalKey& key) {
  result->append(key.user_key.data(), key.user_key.size()); //result = g 
  PutFixed64(result, PackSequenceAndType(key.sequence, key.type));  //result = g +上 (key.sequence << 8) | 1 转换成16进制数。编码格式是ASSIC.
}

这里就是函数的追踪,其实没啥特殊的,这里也许你们会骂娘,可是事实上,只有这么多东西,
这里只是进行了一种编码方式,我们继续第二种:

static std::string ShortSuccessor(const std::string& s) {
  std::string result = s;
  InternalKeyComparator(BytewiseComparator()).FindShortSuccessor(&result);
  return result;
}

ShortSuccessor(IKey("foo", 100, kTypeValue)));

IKey("foo", 100, kTypeValue) 这个东西最后生成了“foo+后面的数字的特殊编码”,为11位。我们开始看我们的ShortSuccessor
BytewiseComparator()这个函数是个单例模式,线程安全,具体什么单利模式我也忘记了,反正就是线程安全的单例模式。最终生成了一个BytewiseComparatorImpl这个类,
InternalKeyComparator这个类的构造函数

  explicit InternalKeyComparator(const Comparator* c) : user_comparator_(c) { }

是不是超级简单,那就不要多说了,总之就是持有一个BytewiseComparatorImpl,关键是最后的这个内部函数我们继续看

void InternalKeyComparator::FindShortSuccessor(std::string* key) const {
  Slice user_key = ExtractUserKey(*key);

  std::string tmp(user_key.data(), user_key.size());
   std::cout<<><>FindShortSuccessor(&tmp);
   std::cout<<><>Compare(user_key, tmp) < 0) {
    // User key has become shorter physically, but larger logically.
    // Tack on the earliest possible number to the shortened user key.
    PutFixed64(&tmp, PackSequenceAndType(kMaxSequenceNumber,kValueTypeForSeek));
    assert(this->Compare(*key, tmp) < 0);
    key->swap(tmp);
  }
}<><>

其实这里用了代理者模式,吧关键人物交给刚才我们的那个IMPL类,具体处理的代码如下:

virtual void FindShortSuccessor(std::string* key) const {
    // Find first character that can be incremented
    size_t n = key->size();
    for (size_t i = 0; i < n; i++) {
      const uint8_t byte = (*key)[i];
      if (byte != static_cast(0xff)) {
        (*key)[i] = byte + 1;
        key->resize(i+1);
        return;
      }
    }
    // *key is a run of 0xffs.  Leave it alone.
  }

这里处理比较奇怪,吧key作为一个数组,每个字符加1,然后去掉结尾,这里这种用法,很奇怪我暂时不能解释清楚,反正,就是这个指针的指向了一个g(f+1),
至此这个测试函数完全就通了,g==g为真。

相关TAG标签
上一篇:MySQLCluster7.3.7+CentOS7集群配置入门MySQL双管理节点配置入门
下一篇:oracle中出现:ORA-00911:invalidcharacter的问题
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站