zoukankan      html  css  js  c++  java
  • Memcached源码分析之memcached.h

    1.  //memcached.h
    2.  
    3. //返回在item中data字段key的地址,即把指针指向key
    4. #define ITEM_key(item) (((char*)&((item)->data))
    5.          + (((item)->it_flags & ITEM_CAS) ? sizeof(uint64_t) : 0))
    6. //返回在item中data字段suffix的地址,即把指针指向suffix
    7. #define ITEM_suffix(item) ((char*) &((item)->data) + (item)->nkey + 1
    8.          + (((item)->it_flags & ITEM_CAS) ? sizeof(uint64_t) : 0))
    9.  //返回在item中data字段value的地址,即把指针指向value
    10. #define ITEM_data(item) ((char*) &((item)->data) + (item)->nkey + 1
    11.          + (item)->nsuffix
    12.          + (((item)->it_flags & ITEM_CAS) ? sizeof(uint64_t) : 0))
    13. //item总字节数
    14. #define ITEM_ntotal(item) (sizeof(struct _stritem) + (item)->nkey + 1
    15.          + (item)->nsuffix + (item)->nbytes
    16.          + (((item)->it_flags & ITEM_CAS) ? sizeof(uint64_t) : 0))
    17. //conn结构体中state字段的枚举,代表连接状态
    18. enum conn_states {
    19.     conn_listening, /**< the socket which listens for connections */
    20.     conn_new_cmd, /**< Prepare connection for next command */
    21.     conn_waiting, /**< waiting for a readable socket */
    22.     conn_read, /**< reading in a command line */
    23.     conn_parse_cmd, /**< try to parse a command from the input buffer */
    24.     conn_write, /**< writing out a simple response */
    25.     conn_nread, /**< reading in a fixed number of bytes */
    26.     conn_swallow, /**< swallowing unnecessary bytes w/o storing */
    27.     conn_closing, /**< closing this connection */
    28.     conn_mwrite, /**< writing out many items sequentially */
    29.     conn_closed, /**< connection is closed */
    30.     conn_max_state /**< Max state value (used for assertion) */
    31. };
    32. //item保存结果枚举
    33. enum store_item_type {
    34.     NOT_STORED=0, STORED, EXISTS, NOT_FOUND
    35. };
    36. //item结构体
    37. typedef struct _stritem {
    38.     struct _stritem *next; //链表中下一个,这个链表有可能是slots链表,也有可能是LRU链表,但一个item不可能同时这两个链表中,所以复用一个指针。
    39.     struct _stritem *prev; //链表中上一个。
    40.     struct _stritem *h_next;  //相同hash值中链表的下一个。
    41.     rel_time_t time;   //最近访问时间
    42.     rel_time_t exptime;  //过期时间
    43.     int nbytes;  //value的字节数
    44.     unsigned short refcount; //引用计数
    45.     uint8_t nsuffix;  //后缀长度
    46.     uint8_t it_flags;  //标记
    47.     uint8_t slabs_clsid;  //item所在的slabclass的id值
    48.     uint8_t nkey; //键长
    49.     /* this odd type prevents type-punning issues when we do
    50.      * the little shuffle to save space when not using CAS. */
    51.     union {
    52.         uint64_t cas;
    53.         char end;
    54.     } data[]; //数据,这个数据不仅仅包括key对应的value,还有key、CAS、后缀等等数据也存在此,所以它有4部分“拼”成:CAS(可选),KEY,后缀,VALUE。
    55.     /* if it_flags & ITEM_CAS we have 8 bytes CAS */
    56.     /* then null-terminated key */
    57.     /* then " flags length " (no terminating null) */
    58.     /* then data with terminating (no terminating null; it's binary!) */
    59. } item;
    60. /**
    61. worker线程结构体
    62. */
    63. typedef struct {
    64.     pthread_t thread_id; //线程id
    65.     struct event_base *base; //每个线程自己独立的event_base,监听的就是下面的notify_event事件对象
    66.     struct event notify_event; //事件对象,fd即为下面的notify_receive_fd
    67.     int notify_receive_fd; //管道接收fd
    68.     int notify_send_fd; //管道写入fd
    69.     struct thread_stats stats; //线程的一些统计
    70.     struct conn_queue *new_conn_queue; //连接参数对象CQ_ITEM队列
    71.     cache_t *suffix_cache;
    72.     uint8_t item_lock_type; //控制线程锁的粒度
    73. } LIBEVENT_THREAD;
    74. /**
    75. 主线程结构体
    76. */
    77. typedef struct {
    78.     pthread_t thread_id; //线程id
    79.     struct event_base *base; //event_base
    80. } LIBEVENT_DISPATCHER_THREAD;
    81. typedef struct conn conn;
    82. struct conn {
    83.     int sfd; //连接的socket fd
    84.     sasl_conn_t *sasl_conn;
    85.     bool authenticated;
    86.     enum conn_states state; //当前的连接状态
    87.     enum bin_substates substate;
    88.     rel_time_t last_cmd_time;
    89.     struct event event; // 监听的事件
    90.     short ev_flags; //监听的事件 类型
    91.     short which; /** which events were just triggered */ //刚触发的事件
    92.     /**
    93.         读buffer会涉及两个方向上的“读”:
    94.         一个是从socket读进来到rbuf里面
    95.         一个是从rbuf里面把数据读出去解析,读buffer相当于一个中介,从socket读进来最终还是得被别人读出去解析,而
    96.         rcurr工作指针与rbytes就是在rbuf数据被读出去解析的时候用到,用来控制可以读出去被解析的数据还剩余多少。
    97.     */
    98.     char *rbuf; /** buffer to read commands into */ //读buffer
    99.     char *rcurr; /** but if we parsed some already, this is where we stopped */ //读buffer的当前指针
    100.     int rsize; /** total allocated size of rbuf */ //读buffer大小
    101.     int rbytes; /** how much data, starting from rcur, do we have unparsed */ //剩余buffer字节数
    102.     //下面4个属性和上面4个类似
    103.     char *wbuf;
    104.     char *wcurr;
    105.     int wsize;
    106.     int wbytes;
    107.     /** which state to go into after finishing current write */
    108.     enum conn_states write_and_go; //完成当前写操作后,连接状态将会置为此状态
    109.     void *write_and_free; /** free this memory after finishing writing */
    110.     char *ritem; /** when we read in an item's value, it goes here */ //这个指针指向item结构体中data中的value地址
    111.     int rlbytes; //尚未读完item的data的value的字节数
    112.     void *item; /* for commands set/add/replace */ //当执行set/add/replace 命令时,此指针用于指向分配的item空间
    113.     /* data for the swallow state */
    114.     int sbytes; /* how many bytes to swallow */
    115.     //下面是往socket写出数据时用的字段
    116.     struct iovec *iov; //iovec结构体数组
    117.     int iovsize; //*iov数组大小
    118.     int iovused; //*iov数组已被使用的元素个数
    119.     struct msghdr *msglist; //msghdr结构体数组,表示sendmsg要发送的消息列表
    120.     int msgsize; //*msglist数组大小
    121.     int msgused; //*msglist数组已使用的元素个数
    122.     int msgcurr; //当前要发送的msghdr
    123.     int msgbytes; //当前msghdr的字节数
    124.     item **ilist; //get key1 key2命令时,要发送给客户端的item列表
    125.     int isize; //列表大小
    126.     item **icurr; //当前要发送的item
    127.     int ileft; //剩余数目
    128.     char **suffixlist;
    129.     int suffixsize;
    130.     char **suffixcurr;
    131.     int suffixleft;
    132.     enum protocol protocol; /* which protocol this connection speaks */
    133.     enum network_transport transport; /* what transport is used by this connection */
    134.     //UDP相关的字段
    135.     int request_id; /* Incoming UDP request ID, if this is a UDP "connection" */
    136.     struct sockaddr_in6 request_addr; /* udp: Who sent the most recent request */
    137.     socklen_t request_addr_size;
    138.     unsigned char *hdrbuf; /* udp packet headers */
    139.     int hdrsize; /* number of headers' worth of space is allocated */
    140.     bool noreply; /* True if the reply should not be sent. */
    141.     /* current stats command */
    142.     struct {
    143.         char *buffer;
    144.         size_t size;
    145.         size_t offset;
    146.     } stats;
    147.     // 二进制相关的字段
    148.     protocol_binary_request_header binary_header;
    149.     uint64_t cas; /* the cas to return */
    150.     short cmd; /* current command being processed */
    151.     int opaque;
    152.     int keylen;
    153.     conn *next; /* Used for generating a list of conn structures */
    154.     LIBEVENT_THREAD *thread; /* Pointer to the thread object serving this connection */
    155. };
    156. //非阻塞方式获取互斥锁
    157. static inline int mutex_lock(pthread_mutex_t *mutex)
    158. {
    159.     while (pthread_mutex_trylock(mutex));
    160.     return 0;
    161. }
    162. //释放锁
    163. #define mutex_unlock(x) pthread_mutex_unlock(x)
    164. #include "stats.h"
    165. #include "slabs.h"
    166. #include "assoc.h"
    167. #include "items.h"
    168. #include "trace.h"
    169. #include "hash.h"
    170. #include "util.h"
  • 相关阅读:
    linux系统中如何进入退出vim编辑器,方法及区别
    [转]JAVA的动态代理机制及Spring的实现方式
    mybaties 缓存
    全面分析 Spring 的编程式事务管理及声明式事务管理
    面试(4)-spring-Spring面试题和答案
    vector的多套遍历方案
    【QT】QT下载与安装
    【QT】无需写connect代码关联信号和槽函数
    【QT】第一个QT程序(点击按钮,显示特定文本)
    【QT】error: 'SIGNAL' was not declared in this scope
  • 原文地址:https://www.cnblogs.com/guolanzhu/p/5850117.html
Copyright © 2011-2022 走看看