学习了levelDB源码分析-Skiplist
1. 在levelDB里Skiplist是个模板类。 它的声明和定义全部都放在了.h文件中。 普通class一般是把声明和定义分别放到.h和.cpp文件里的,而模板类必须把声明和定义都放到.h文件中。具体原因,参考学习博客 c++ 模板类 声明和定义都放在.h文件的原因.
2. 首先声明了 struct Node,这是前置声明,因为Node类是在后面的位置声明和定义的。
3. 接着public声明了explict的构造函数和其他两个普通接口:Insert 和 Contains。 注意它们的传参都是const 引用类型,这样可以避免copy构造和析构的成本。对于自定义class和template类,在effective C++书中作者都是推荐的这种 “pass by const reference”。
// Insert key into the list.
// REQUIRES: nothing that compares equal to key is currently in the list.
void Insert(const Key& key);
// Returns true iff an entry that compares equal to key is in the list.
bool Contains(const Key& key) const;
4. 以内部类的方式,实现了一个Iterator。
5. enum { kMaxHeight = 12 }; 这是用enum hack来替代传统C里面的宏了。 这个enum hack技巧在effective c++ item2有提到。
6. 跟着声明了private 的成员变量,可以看到作者使用了很多const来修饰。 这个是和effective C++里item 3提倡的是一致的。
// Immutable after construction
Comparator const compare_;
Arena* const arena_; // Arena used for allocations of nodes
Node* const head_;
7. GetMaxHeight函数在class的声明里写出了定义,普通类应该不用inline修饰本身也是隐式inline的。 这里作者显式写出inline。应该是template类中确实需要inline的就明确写出inline关键字。 这里可以参考博客C++ inline函数和template函数
inline int GetMaxHeight() const {
return static_cast<int>(
reinterpret_cast<intptr_t>(max_height_.NoBarrier_Load()));
}
8. 成员函数,很多都加了const修饰。表示该成员函数不会修改成员变量的值。
// Return the last node in the list.
// Return head_ if list is empty.
Node* FindLast() const;
9. 禁止复制的方式和effective C++提倡的方式是一致。
// No copying allowed
SkipList(const SkipList&);
void operator=(const SkipList&);
10. new (mem) Node(key);使用了placement new, 是在mem中创建了Node对象。 placement new效率更高。 参考博客 【原创】LevelDB中的placement new
template<typename Key, class Comparator>
typename SkipList<Key,Comparator>::Node*
SkipList<Key,Comparator>::NewNode(const Key& key, int height) {
char* mem = arena_->AllocateAligned(
sizeof(Node) + sizeof(port::AtomicPointer) * (height - 1));
return new (mem) Node(key);
}