memcached 结构体详解

/*
 * NOTE: If you modify this table you _MUST_ update the function state_text
 */
/**
 * Possible states of a connection.
 */
enum conn_states {
    conn_listening,  /**< the socket which listens for connections */监听socket连接
    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 */向客户端写入response,主要在outstring和write_and_free中调用,向客户端返回buf中的信息,一般为出错信息。
    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 */向客户端输出item
    conn_max_state   /**< Max state value (used for assertion) */
};



 /**
 * The structure representing a connection into memcached.
 */
每个网络连接的封装
conn typedef struct conn conn;
struct conn {
    int    sfd;//连接的socket
    sasl_conn_t *sasl_conn;
    enum conn_states  state;//连接的状态,用于状态机drive_machine
    enum bin_substates substate;
    struct event event;
    short  ev_flags;
    //libevent调度中用于保存触发原因的变量
    short  which;   /** which events were just triggered */

     //socket的读缓存,存放的是commands信息,用于libevent的回调函数拷贝数据
    char   *rbuf;   /** buffer to read commands into */

    //当前所在缓存偏移量,初始时指向rbuf的指针,表示还没有解析的数据位置
    char   *rcurr;  /** but if we parsed some already, this is where we stopped */

    //缓存数据的大小,也就是rbuf的大小,通过malloc函数创建
    int    rsize;   /** total allocated size of rbuf */

    //从rcur开始,还没有解析的数据的长度
    int    rbytes;  /** how much data, starting from rcur, do we have unparsed */

    char   *wbuf;//socket的写缓存
    char   *wcurr;//当前所在缓存的的偏移量,初始指向wbuf指针,表示还没有发送的数据位置
    int    wsize;//写缓存的大小
    int    wbytes;//还没有发送的数据的长度
    /** which state to go into after finishing current write */
    //当处理完当前的数据后,connection转换到的目的状态
    enum conn_states  write_and_go;
    //当处理完当前的数据后,需要释放的内存资源
    void   *write_and_free; /** free this memory after finishing writing */

    //item的value缓存,存储了item的value值
    char   *ritem;  /** when we read in an item's value, it goes here */
    int    rlbytes;//需要读取的item value的剩余字节数

    /* data for the nread state */

    /**
     * item is used to hold an item structure created after reading the command
     * line of set/add/replace commands, but before we finished reading the actual
     * data. The data is read into ITEM_data(item) to avoid extra copying.
     */

    void   *item;     /* for commands set/add/replace  */

    /* data for the swallow state */
    int    sbytes;    /* how many bytes to swallow */

    /* data for the mwrite state */
    //memcached的向client写操作时通过sendmsg完成,与sendmsg相关的数据结构:struct iovec,struct msghdr, struct sockaddr
    struct iovec *iov;//iovec结构体的数组
    int    iovsize;   /* number of elements allocated in iov[] */
    int    iovused;   /* number of elements used in iov[] */

    struct msghdr *msglist;//msghdr数组指针,在sendmsg中用于表示需要发送的消息列表
    int    msgsize;   /* number of elements allocated in msglist[] */
    int    msgused;   /* number of elements used in msglist[] */
    int    msgcurr;   /* element in msglist[] being transmitted now */
    int    msgbytes;  /* number of bytes in current msg */

    //需要发送到client的item的列表,这个主要针对get key1 key2
    item   **ilist;   /* list of items to write out */
    int    isize;   //list大小
    item   **icurr; //指向当前正在发送的item元素的指针
    int    ileft;   //剩下的需要发送的item数目

    //需要发送到client的cas版本的列表
    char   **suffixlist;
    int    suffixsize;//list大小
    char   **suffixcurr;//指向当前正在发送的cas版本的指针
    int    suffixleft;剩下的需要发送的cas版本的数目

    enum protocol protocol;   /* which protocol this connection speaks */
    enum network_transport transport; /* what transport is used by this connection */

    /* data for UDP clients */
    int    request_id; /* Incoming UDP request ID, if this is a UDP "connection" */
    struct sockaddr request_addr; /* 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;

    /* Binary protocol stuff */
    /* This is where the binary header goes */
    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 */
};


process_update_command()在执行命令之前,他首先要获得一些有效信息,如下面列的:

key - 键
nkey - 键长
flags - 标记位(在PHP当中使用flags来区别数据是否进过压缩)
exptime - 过期时间
vlen - 内容的长度
req_cas_id - 如果是cas模式,这里是版本号

 
        conn *c = conn_new(item->sfd, item->init_state, item->event_flags,   
                          item->read_buffer_size, item->is_udp, me->base); 
item->sfd是已经建立的连接的描述符,通过conn_new函数为该描述符注册libevent的读事件,me->base是代表自己的一个线程结构体,就是说对该描述符的事件处理交给当前这个workers线程处理. 


 

你可能感兴趣的:(struct,socket,memcached,command,structure)