Memcached源码分析之memcached.h
- //memcached.h
- //返回在item中data字段key的地址,即把指针指向key
- #define ITEM_key(item) (((char*)&((item)->data)) \
- + (((item)->it_flags & ITEM_CAS) ? sizeof(uint64_t) : 0))
- //返回在item中data字段suffix的地址,即把指针指向suffix
- #define ITEM_suffix(item) ((char*) &((item)->data) + (item)->nkey + 1 \
- + (((item)->it_flags & ITEM_CAS) ? sizeof(uint64_t) : 0))
- //返回在item中data字段value的地址,即把指针指向value
- #define ITEM_data(item) ((char*) &((item)->data) + (item)->nkey + 1 \
- + (item)->nsuffix \
- + (((item)->it_flags & ITEM_CAS) ? sizeof(uint64_t) : 0))
- //item总字节数
- #define ITEM_ntotal(item) (sizeof(struct _stritem) + (item)->nkey + 1 \
- + (item)->nsuffix + (item)->nbytes \
- + (((item)->it_flags & ITEM_CAS) ? sizeof(uint64_t) : 0))
- //conn结构体中state字段的枚举,代表连接状态
- enum conn_states {
- conn_listening, /**< the socket which listens for connections */
- conn_new_cmd, /**< Prepare connection for next command */
- conn_waiting, /**< waiting for a readable socket */
- conn_read, /**< reading in a command line */
- conn_parse_cmd, /**< try to parse a command from the input buffer */
- conn_write, /**< writing out a simple response */
- conn_nread, /**< reading in a fixed number of bytes */
- conn_swallow, /**< swallowing unnecessary bytes w/o storing */
- conn_closing, /**< closing this connection */
- conn_mwrite, /**< writing out many items sequentially */
- conn_closed, /**< connection is closed */
- conn_max_state /**< Max state value (used for assertion) */
- };
- //item保存结果枚举
- enum store_item_type {
- NOT_STORED=0, STORED, EXISTS, NOT_FOUND
- };
- //item结构体
- typedef struct _stritem {
- struct _stritem *next; //链表中下一个,这个链表有可能是slots链表,也有可能是LRU链表,但一个item不可能同时这两个链表中,所以复用一个指针。
- struct _stritem *prev; //链表中上一个。
- struct _stritem *h_next; //相同hash值中链表的下一个。
- rel_time_t time; //最近访问时间
- rel_time_t exptime; //过期时间
- int nbytes; //value的字节数
- unsigned short refcount; //引用计数
- uint8_t nsuffix; //后缀长度
- uint8_t it_flags; //标记
- uint8_t slabs_clsid; //item所在的slabclass的id值
- uint8_t nkey; //键长
- /* this odd type prevents type-punning issues when we do
- * the little shuffle to save space when not using CAS. */
- union {
- uint64_t cas;
- char end;
- } data[]; //数据,这个数据不仅仅包括key对应的value,还有key、CAS、后缀等等数据也存在此,所以它有4部分“拼”成:CAS(可选),KEY,后缀,VALUE。
- /* if it_flags & ITEM_CAS we have 8 bytes CAS */
- /* then null-terminated key */
- /* then " flags length\r\n" (no terminating null) */
- /* then data with terminating \r\n (no terminating null; it's binary!) */
- } item;
- /**
- worker线程结构体
- */
- typedef struct {
- pthread_t thread_id; //线程id
- struct event_base *base; //每个线程自己独立的event_base,监听的就是下面的notify_event事件对象
- struct event notify_event; //事件对象,fd即为下面的notify_receive_fd
- int notify_receive_fd; //管道接收fd
- int notify_send_fd; //管道写入fd
- struct thread_stats stats; //线程的一些统计
- struct conn_queue *new_conn_queue; //连接参数对象CQ_ITEM队列
- cache_t *suffix_cache;
- uint8_t item_lock_type; //控制线程锁的粒度
- } LIBEVENT_THREAD;
- /**
- 主线程结构体
- */
- typedef struct {
- pthread_t thread_id; //线程id
- struct event_base *base; //event_base
- } LIBEVENT_DISPATCHER_THREAD;
- typedef struct conn conn;
- struct conn {
- int sfd; //连接的socket fd
- sasl_conn_t *sasl_conn;
- bool authenticated;
- enum conn_states state; //当前的连接状态
- enum bin_substates substate;
- rel_time_t last_cmd_time;
- struct event event; // 监听的事件
- short ev_flags; //监听的事件 类型
- short which; /** which events were just triggered */ //刚触发的事件
- /**
- 读buffer会涉及两个方向上的“读”:
- 一个是从socket读进来到rbuf里面
- 一个是从rbuf里面把数据读出去解析,读buffer相当于一个中介,从socket读进来最终还是得被别人读出去解析,而
- rcurr工作指针与rbytes就是在rbuf数据被读出去解析的时候用到,用来控制可以读出去被解析的数据还剩余多少。
- */
- char *rbuf; /** buffer to read commands into */ //读buffer
- char *rcurr; /** but if we parsed some already, this is where we stopped */ //读buffer的当前指针
- int rsize; /** total allocated size of rbuf */ //读buffer大小
- int rbytes; /** how much data, starting from rcur, do we have unparsed */ //剩余buffer字节数
- //下面4个属性和上面4个类似
- char *wbuf;
- char *wcurr;
- int wsize;
- int wbytes;
- /** which state to go into after finishing current write */
- enum conn_states write_and_go; //完成当前写操作后,连接状态将会置为此状态
- void *write_and_free; /** free this memory after finishing writing */
- char *ritem; /** when we read in an item's value, it goes here */ //这个指针指向item结构体中data中的value地址
- int rlbytes; //尚未读完item的data的value的字节数
- void *item; /* for commands set/add/replace */ //当执行set/add/replace 命令时,此指针用于指向分配的item空间
- /* data for the swallow state */
- int sbytes; /* how many bytes to swallow */
- //下面是往socket写出数据时用的字段
- struct iovec *iov; //iovec结构体数组
- int iovsize; //*iov数组大小
- int iovused; //*iov数组已被使用的元素个数
- struct msghdr *msglist; //msghdr结构体数组,表示sendmsg要发送的消息列表
- int msgsize; //*msglist数组大小
- int msgused; //*msglist数组已使用的元素个数
- int msgcurr; //当前要发送的msghdr
- int msgbytes; //当前msghdr的字节数
- item **ilist; //get key1 key2命令时,要发送给客户端的item列表
- int isize; //列表大小
- item **icurr; //当前要发送的item
- int ileft; //剩余数目
- char **suffixlist;
- int suffixsize;
- char **suffixcurr;
- int suffixleft;
- enum protocol protocol; /* which protocol this connection speaks */
- enum network_transport transport; /* what transport is used by this connection */
- //UDP相关的字段
- int request_id; /* Incoming UDP request ID, if this is a UDP "connection" */
- struct sockaddr_in6 request_addr; /* udp: Who sent the most recent request */
- socklen_t request_addr_size;
- unsigned char *hdrbuf; /* udp packet headers */
- int hdrsize; /* number of headers' worth of space is allocated */
- bool noreply; /* True if the reply should not be sent. */
- /* current stats command */
- struct {
- char *buffer;
- size_t size;
- size_t offset;
- } stats;
- // 二进制相关的字段
- protocol_binary_request_header binary_header;
- uint64_t cas; /* the cas to return */
- short cmd; /* current command being processed */
- int opaque;
- int keylen;
- conn *next; /* Used for generating a list of conn structures */
- LIBEVENT_THREAD *thread; /* Pointer to the thread object serving this connection */
- };
- //非阻塞方式获取互斥锁
- static inline int mutex_lock(pthread_mutex_t *mutex)
- {
- while (pthread_mutex_trylock(mutex));
- return 0;
- }
- //释放锁
- #define mutex_unlock(x) pthread_mutex_unlock(x)
- #include "stats.h"
- #include "slabs.h"
- #include "assoc.h"
- #include "items.h"
- #include "trace.h"
- #include "hash.h"
- #include "util.h"
Memcached源码分析之memcached.h的更多相关文章
- Memcached源码分析之memcached.c
memcached.c 由于代码太多,在此省略了部分代码,例如UPD连接,二进制协议,某些错误输出和调试输出等,建议从main函数开始看起. #include "memcached.h&qu ...
- Memcached源码分析
作者:Calix,转载请注明出处:http://calixwu.com 最近研究了一下memcached的源码,在这里系统总结了一下笔记和理解,写了几 篇源码分析和大家分享,整个系列分为“结构篇”和“ ...
- Memcached源码分析之请求处理(状态机)
作者:Calix 一)上文 在上一篇线程模型的分析中,我们知道,worker线程和主线程都调用了同一个函数,conn_new进行事件监听,并返回conn结构体对象.最终有事件到达时,调用同一个函数ev ...
- Memcached源码分析之线程模型
作者:Calix 一)模型分析 memcached到底是如何处理我们的网络连接的? memcached通过epoll(使用libevent,下面具体再讲)实现异步的服务器,但仍然使用多线程,主要有两种 ...
- Memcached源码分析之从SET命令开始说起
作者:Calix 如果直接把memcached的源码从main函数开始说,恐怕会有点头大,所以这里以一句经典的“SET”命令简单地开个头,算是回忆一下memcached的作用,后面的结构篇中关于命令解 ...
- Memcached源码分析之内存管理
先再说明一下,我本次分析的memcached版本是1.4.20,有些旧的版本关于内存管理的机制和数据结构与1.4.20有一定的差异(本文中会提到). 一)模型分析在开始解剖memcached关于内存管 ...
- memcached源码分析-----item过期失效处理以及LRU爬虫
memcached源码分析-----item过期失效处理以及LRU爬虫,memcached-----item 转载请注明出处:http://blog.csdn.net/luotuo44/article ...
- RobHess的SIFT源码分析:imgfeatures.h和imgfeatures.c文件
SIFT源码分析系列文章的索引在这里:RobHess的SIFT源码分析:综述 imgfeatures.h中有SIFT特征点结构struct feature的定义,除此之外还有一些特征点的导入导出以及特 ...
- Memcached源码分析——内存管理
注:这篇内容极其混乱 推荐学习这篇博客.博客的地址:http://kenby.iteye.com/blog/1423989 基本元素item item是Memcached中记录存储的基本单元,用户向m ...
随机推荐
- javascript语句语义大全(3)
1. for(var i=0;i<10;i++){ } for循环,括号里面是循环条件,翻译过来是,初始设定1=0:没循环一次i会+1,直到i<10 2. var i=0: while(i ...
- 破解SharpPlus Sqlite Develope[转]
1.运行里输入regedit,打开注册表 2.编辑->查找,输入sqlite 查找结果如下 3.直接删除SqliteDev节点就可以了,重新打开Sqlite Developer就可以用了,当然还 ...
- POJ 2084 Game of Connections(卡特兰数)
卡特兰数源于组合数学,ACM中比较具体的使用例子有,1括号匹配的种数.2在栈中的自然数出栈的种数.3求多边形内三角形的个数.4,n个数围城圆圈,找不相交线段的个数.5给定n个数,求组成二叉树的种数…… ...
- 利用eclipse新建一个maven项目步骤:
1.打开eclipse,左键点击左上角File,选中New,左键点击选中Maven Project,出现下面界面: 2.把打钩的去掉,选择自己项目所在的工作空间,如下图,我建在我的工作空间worksp ...
- 解决:无法将“Add-Migration”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次
1.输入的中划线“-”格式不对,检查是否为全角状态下输入,误输入了下划线“_",或是前后有空格: 2.没有引用EntityFramework命令,请执行如下名称(Import-Module ...
- 单片AT89C2051 + SD卡 + 3310LCD = 音乐播放器
http://www.amobbs.com/thread-4503884-1-1.html 这个小玩意,采用 ATMEL 的传统51MCU作主控制芯片,加上SD卡和显示屏,就可以作简单的音乐播放器了, ...
- 转 :Vim文件编码识别与乱码处理
Vim文件编码识别与乱码处理 在 Vim 中,有四个与编码有关的选项,它们是:fileencodings.fileencoding.encoding 和 termencoding.在实际使用中,任 ...
- FusionChart实现柱状图、饼状图的动态数据显示 附Demo
最近做的项目中需要用饼状图显示——'问卷调查'的统计结果(之前用过FusionChart做过柱状图的数据展示,那还是两年前的事了),在网上查了下FusionChart实现饼状图显示方面的资料,却发现资 ...
- Android----ListView入门知识--各种Adapter配合使用
引自:http://www.cnblogs.com/playing/archive/2011/03/21/1990555.html 在android开发中ListView是比较常用的组件,它以列表的形 ...
- int main(int argc,char *argv[])参数的应用
#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/sta ...