关于leveldb源码整理之二
2017-07-22 01:56
190 查看
前言
上一节介绍了makefile的问题,可是那个仅仅是编译出一个动态库,函数的流程根本毫无办法了解,这里只能找test,这里我们先找几个慢慢分析。正文
我们基本上都是挨个看,找一些简单的test,慢慢进行。这里我们选取了dbformat_test这个作为我们的第一个文件,这个相对来说比较简单,可是有些东西还是比较复杂,我们一一道来。
找到
main()函数
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); }
是不是觉得挺崩溃的,我也是,我们来看看最终的函数调用,
int RunAllTests() { const char* matcher = getenv("LEVELDB_TESTS"); int num = 0; if (tests != NULL) { for (size_t i = 0; i < tests->size(); i++) { const Test& t = (*tests)[i]; if (matcher != NULL) { std::string name = t.base; name.push_back('.'); name.append(t.name); if (strstr(name.c_str(), matcher) == NULL) { continue; } } fprintf(stderr, "==== Test %s.%s\n", t.base, t.name); (*t.func)(); ++num; } } fprintf(stderr, "==== PASSED %d tests\n", num); return 0; }
更蒙了,这里我们大概看下,大概就是输出tests中的一些东西,那么我们就记住这个变量,看下在哪里初始化,添加值,这里我们就暂时不管了。
继续看我们的
dbformat_test.cc这里代码很短,除了定义几个函数,都不会被调用,立马我们就会感觉是这俩TEST搞出了问题,我们就追踪这个,
//这俩是字符串的拼接,在预处理阶段进行 #define TCONCAT(a,b) TCONCAT1(a,b) #define TCONCAT1(a,b) a##b #define TEST(base,name) \ class TCONCAT(_Test_,name) : public base { \ public: \ void _Run(); \ static void _RunIt() { \ TCONCAT(_Test_,name) t; \ t._Run(); \ } \ }; \ bool TCONCAT(_Test_ignored_,name) = \ ::leveldb::test::RegisterTest(#base, #name, &TCONCAT(_Test_,name)::_RunIt); \ void TCONCAT(_Test_,name)::_Run()
作为java出身的我,看到这些代码,我是崩溃的,不过好在,我还是看懂了,咱们可以吧这些东西转化成预处理后的东西,这里只拿第二个函数来转化:
TEST(FormatTest, InternalKeyShortestSuccessor) { ASSERT_EQ(IKey("g", kMaxSequenceNumber, kValueTypeForSeek), ShortSuccessor(IKey("foo", 100, kTypeValue))); ASSERT_EQ(IKey("\xff\xff", 100, kTypeValue), ShortSuccessor(IKey("\xff\xff", 100, kTypeValue))); } //转化后 class _FormatTest_InternalKeyShortestSuccessor : public FormatTest{ public: void _Run(); static void _RunIt() { _FormatTest_InternalKeyShortestSuccessor t; t.run(); } }; bool _FormatTest_ignored_InternalKeyShortestSuccessor = ::leveldb::test::RegisterTest("FormatTest", "InternalKeyShortestSuccessor", &_FormatTest_InternalKeyShortestSuccessor::_RunIt); void _FormatTest_ignored_InternalKeyShortestSuccessor::_Run() { ASSERT_EQ(IKey("g", kMaxSequenceNumber, kValueTypeForSeek), ShortSuccessor(IKey("foo", 100, kTypeValue))); ASSERT_EQ(IKey("\xff\xff", 100, kTypeValue), ShortSuccessor(IKey("\xff\xff", 100, kTypeValue))); }
是不是发现就是定义了一个类,然后,调用了一个函数,这个函数做了什么,我们来好好观察,
bool RegisterTest(const char* base, const char* name, void (*func)()) { if (tests == NULL) { tests = new std::vector<Test>; } Test t; t.base = base; t.name = name; t.func = func; tests->push_back(t); return true; }
很简单对吧,就是加入tests队列中,和我们开始想的一模一样。我们在回到开始看看到底干了啥:
for (size_t i = 0; i < tests->size(); i++) { const Test& t = (*tests)[i]; if (matcher != NULL) { std::string name = t.base; name.push_back('.'); name.append(t.name); if (strstr(name.c_str(), matcher) == NULL) { continue; } } fprintf(stderr, "==== Test %s.%s\n", t.base, t.name); (*t.func)(); ++num; }
开始的东西基本可以漠视了,这里我们看看到输出名字,然后,调用传进来的函数指针,这些函数内容就是在源文件中的东西,如下
ASSERT_EQ(IKey("g", kMaxSequenceNumber, kValueTypeForSeek), ShortSuccessor(IKey("foo", 100, kTypeValue))); ASSERT_EQ(IKey("\xff\xff", 100, kTypeValue), ShortSuccessor(IKey("\xff\xff", 100, kTypeValue)));
搞了这么多事情,就为了这个,有没有好气的感觉,那么我们还是进入这些真实的测试,看看真实的leveldb的内容吧。
::leveldb::test::Tester(__FILE__, __LINE__).IsEq((a),(b)) //其实是调用了一个Tester的一个名字叫IsEq的方法,这个又是宏生成的,继续阅读,最后是调用了: template <class X, class Y> Tester& IsEq(const X& x, const Y& y) { if (! (x == y)) { bc72 ss_ << " failed: " << x << (" " #op " ") << y; ok_ = false; } return *this; }
我们暂时没看传入的a、b到底是啥,我们可以确定是一个string类型的东西,然后判断他们俩是不是一样,这样的话,不一样,输出failed,
那么我们就看真正的a、b到底是啥。这才是这个测试的重头戏,我们准备好开启真的征程了吗?
后记
本来想一篇文章写完,可是发现内容偏多,还是下一篇继续。下一篇继续看下关于数据库键值的编码部分相关文章推荐
- 关于leveldb源码整理之三
- 以下是computer vision:algorithm and application计算机视觉算法与应用这本书中附录里关于计算机视觉的一些测试数据集和源码站点,我整理了下,加了点中文注解
- [Leveldb]源码分析之二 Cache模块的实现
- 关于网狐棋牌6603源码的整理、编译和搭建
- 关于网狐棋牌6603源码的整理、编译和搭建
- 整理的关于Java对mongodb进行的CURD操作工具类及源码
- LevelDB源码分析之二:comparator
- 以下是computer vision:algorithm and application计算机视觉算法与应用这本书中附录里关于计算机视觉的一些测试数据集和源码站点,我整理了下,加了点中文注解
- 关于网狐棋牌6603源码的整理、编译和搭建
- 关于网狐棋牌6603源码的整理、编译和搭建
- 关于网狐棋牌6603源码的整理、编译和搭建
- 关于网狐棋牌6603源码的整理、编译和搭建
- 以下是computer vision:algorithm and application计算机视觉算法与应用这本书中附录里关于计算机视觉的一些测试数据集和源码站点,我整理了下,加了点中文注解
- 关于网狐棋牌6603源码的整理、编译和搭建
- 自己收集整理的关于 判断 网页是否加载完毕的方法(特别是多框架Frame),然后获取网页源码
- 关于网狐棋牌6603源码的整理、编译和搭建
- 以下是computer vision:algorithm and application计算机视觉算法与应用这本书中附录里关于计算机视觉的一些测试数据集和源码站点,我整理了下,加了点中文注解
- Android源码分析系列-整理篇 ------ 关于Vold 自动挂载部分
- 关于网狐棋牌6603源码的整理、编译和搭建
- 发福利,整理了一份关于“资源汇总”的汇总