关于ssdb的介绍就不多说了,自行百度去了解下。因为工作上用到了ssdb,正好看看源码也可以学习下作者的设计思路。ssdb的作者在自己的博客上也写了不少关于它的文章,但说的很浅不够深入,借这个机会看看它的内在究竟是怎样的。我下的版本是1.8.0,直接从github上clone过来的。由于本人道行很浅,说的不对的地方还请大家不吝指正。
下载完后可以看到两个比较关键的目录src和deps。deps下包含了ssdb所依赖的一些项目(cpy、jemalloc、leveldb和snappy),cpy是作者造的一个编程语言,jemalloc是一个内存管理库,leveldb是一个kv数据库,ssdb底部的数据库引擎采用的是leveldb,snappy用来压缩和解压缩的开发包。src目录包含了ssdb核心的代码,这是我要分析的主要区域。src目录下有三个子目录:net、ssdb和util,编译这三个子目录会生成三个.a文件:libnet.a、libssdb.a和libutil.a,ssdb-server会依赖这三个静态链接库,不妨先从它们三个入手。本节先看看libnet库~
网络连接
相关文件:link.h、link.cpp
不妨先看看libutil库中的Buffer类,一个简单的缓冲区类,对SSDB协议格式有兴趣的可以看这篇博文,这对于看懂read_record和append_record方法有很大帮助:
class Buffer{
private:
char *buf; /* Buffer起始地址 */
char *data_; /* 数据区起始地址 */
int size_; /* 数据区大小 *
int total_; /* 缓冲区大小 */
int origin_total; /* 首次申请大小 */
public:
Buffer(int total);
~Buffer();
int total() const{ // 缓冲区大小
return total_;
}
bool empty() const{
return size_ == 0;
}
// 数据
char* data() const{
return data_;
}
int size() const{
return size_;
}
char* slot() const{
return data_ + size_;
}
// 剩余空间大小
int space() const{
// 注:(data_ - buf)表示无效数据空间大小
return total_ - (data_ - buf) - size_;
}
// 数据区扩大
void incr(int num){
size_ += num;
}
// 数据区缩小
void decr(int num){
size_ -= num;
data_ += num;
}
// 保证不改变后半段的数据, 以便使已生成的 Bytes 不失效.
// 注:当前段无效数据空间超过缓冲区一半时,把数据区拷贝到缓冲区起始地址
void nice();
// 扩大缓冲区
int grow();
std::string stats() const;
int read_record(Bytes *s);
int append(char c);
int append(const char *p);
int append(const