数据结构介绍
item是memcached中存储的最小单元。数据结构的话,我觉得这个代码一贴,一目了然了。
typedef struct _stritem {
struct _stritem *next;
struct _stritem *prev;
struct _stritem *h_next; /* hash chain next */
rel_time_t time; /* least recent access */
rel_time_t exptime; /* expire time */
int nbytes; /* size of data */
unsigned short refcount;
uint8_t nsuffix; /* length of flags-and-length string */
uint8_t it_flags; /* ITEM_* above */
uint8_t slabs_clsid;/* which slab class we're in */
uint8_t nkey; /* key length, w/terminating null and padding */
void * end[0];
/* 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;
注释写的很清楚了,后面还有三个东东,end[0]柔性数组
- key
- suffix
- data
item的操作是基于三个数据结构
#define LARGEST_ID 255 static item *heads[LARGEST_ID]; static item *tails[LARGEST_ID]; static unsigned int sizes[LARGEST_ID];
初始化大家都是NULL都是0
heads 就是存储各个slab的LRU链表头指针(tails同理),LRU?头指针?很清晰,为了从头插入链表
sizes则记录这每个slabLRU链表的长度
几个基本操作
static size_t item_make_header(const uint8_t nkey, const int flags, const int nbytes, char *suffix, uint8_t *nsuffix)
制作header,返回total size
static void item_link_q(item *it)
item插入到LRU链表头
static void item_unlink_q(item *it)
其实就是删除双向链表中的元素操作
int do_item_link(item *it) { assoc_insert(it); item_link_q(it); return 1; }
插入hash表,插入LRU链表
item *do_item_alloc(char *key, const size_t nkey, const int flags, const rel_time_t exptime, const int nbytes)
- 获取header size
- 根据header size查找应该在那个slab
- 从slabs中分配
void item_free(item *it)
调用slabs_free
it_flags
#define ITEM_LINKED 1 #define ITEM_DELETED 2 /* temp */ #define ITEM_SLABBED 4
记录item状态,item状态变迁之前检查flag