Memcached源码分析之memcached.h

Memcached 2238℃

作者:Calix

 //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"

转载请注明:Calix » Memcached源码分析之memcached.h

喜欢 (1)or分享 (0)
发表我的评论
取消评论
表情

亲~ 写下昵称哦~

  • 昵称 (必填)
  • 网址