ssdb源码初探之libnet库

关于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: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;}nice();// 扩大缓冲区int grow();std::string stats() const;int read_record(Bytes *s);int append(char c);int append(const char *p);int append(const void *p, int size);int append(const Bytes &s);int append_record(const Bytes &s);};

Link类表示一个TCP连接,它封装好了常用的操作:建立连接、数据收发等。

class Link{private:error_;/* 是否出错 */std::vector<Bytes> recv_data;/* 接收数据 */RedisLink *redis;/* redis连接 */public:auth;min_recv_buf;min_send_buf;/* useless? */Buffer *input;/* 输入缓冲 */Buffer *output;active_time;/* 活跃时间(秒) */Link(bool is_server=false);~Link();void close();void nodelay(bool enable=true);noblock(bool enable=true);void keepalive(bool enable=true);int fd() const{return sock;}bool error() const{return error_;}void mark_error(){error_ = true;}static Link* connect(const char *ip, int port);static Link* listen(const char *ip, int port);Link* accept();// read network data info bufferint read();int write();flush();/*** parse received data, and return -* NULL: error* empty vector: recv not ready* vector<Bytes>: recv ready*/const std::vector<Bytes>* recv();::vector<Bytes>* response();::vector<std::string> &packet);int send(const std::vector<Bytes> &packet);int send(const Bytes &s1);int send(const Bytes &s1, const Bytes &s2);int send(const Bytes &s1, const Bytes &s2, const Bytes &s3);int send(const Bytes &s1, const Bytes &s2, const Bytes &s3, const Bytes &s4);int send(const Bytes &s1, const Bytes &s2, const Bytes &s3, const Bytes &s4, const Bytes &s5);const std::vector<Bytes>* last_recv(){return &recv_data;}/** these methods will send a request to the server, and wait until a response received.* @return* NULL: error* vector<Bytes>: response ready*/const std::vector<Bytes>* request(const Bytes &s1);const std::vector<Bytes>* request(const Bytes &s1, const Bytes &s2);const std::vector<Bytes>* request(const Bytes &s1, const Bytes &s2, const Bytes &s3);const std::vector<Bytes>* request(const Bytes &s1, const Bytes &s2, const Bytes &s3, const Bytes &s4);const std::vector<Bytes>* request(const Bytes &s1, const Bytes &s2, const Bytes &s3, const Bytes &s4, const Bytes &s5);};fd事件相关文件:fde.h、fde.cpp、fde_select.cpp和fde_epoll.cpp看着你手中的戒指,你说,你可以把它取下来吗?

ssdb源码初探之libnet库

相关文章:

你感兴趣的文章:

标签云: