Twemproxy内部定义了若干种数据结构,如概述中所述,包括自定义的数据结构和关键数据结构,本章将讲述两种数据结构,为后面的复杂的逻辑分析扫清障碍。
- 自定义的数据类型: nc_array.c、nc_array.h、nc_string.c、nc_string.h
- 关键数据结构和算法: nc_rbtree.h、nc_rbtree.c、nc_queue.h、nc_request.c、nc_response.c、nc_mbuf.c、 nc_mbuf.h、nc_message.c、nc_message.h、nc_server.c、nc_server.h
(1) 数组(nc_array)
数组是一个很常见的数据存储方式,其特点比如连续存储、随机访问等在此就不累述,这里只讲解在NC中的实现。
NC的array实现需要熟练操作指针,基本所有的数组操作都是内存指针的操作。根据元素个数和元素大小申请一块连续的内存,像array_idx获取元素index、array_get获取指定index处的元素、array_top等操作比较简单,array_push需要考虑数组已经满了的情况,如果出现这种情况,为了减少内存分配和释放的次数,NC会重新申请当前数组长度两倍的内存,然后才能将新元素放入数组。
还有一点,nc_array实际上是一个栈的操作,只能在array的尾部执行添加(push)和删除(pop)操作,但是查看元素不限位置,只需知道元素的index就可查看该index上的元素。
(2) 字符串(nc_string)
NC字符串string是一个结构体,包含长度和值,如下:
针对string的操作是对glibc库中字符串操作的一系列的封装。
(3) 红黑树(nc_rbtree)
Nc源码里实现了红黑树的初始化,查找最小值,插入和删除操作
对红黑树的讲解下面的这篇博客讲解的比较清晰,可以参考:
http://blog.csdn.net/chenhuajie123/article/details/11951777
(4) 队列(nc_queue)
NC的列表没有自己实现,而是采用了“拿来主义”,借用了系统内核代码sys/queue.h。该头文件中共定义了5种数据结构,全部采用宏定义的方式实现:
l singly-linked lists
l singly-linked tail queues
l lists
l tail queues
l circular queues
在NC中只使用了其中的单向尾队列(STAILQ,用于内存池)和尾队列(TAILQ,用于管理client或server的连接队列)。
网络上讲解这五种数据结构的文章比较多,在此不再累述。
(5) 内存池(nc_mbuf)
内存池(mbuf)内部采用单向尾队列(STAILQ)作为存储结构。
mbuf定义了一个struct mhdr类型的STAILQ单向尾队列,队列通过两个mbuf类型的指针stqh_first和stqh_last将若干个mbuf类型的元素串连起来,形成一个链表队列。