redisソース解析(五)——zipmap
23637 ワード
バージョン:redis-5.0.4参考資料:redis設計と実装ファイル:srcのzipmap.c zipmap.h
一、注釈
zipmapはziplistと似ていますが、主な目的はメモリの節約です.
1.記憶方式:
2.それぞれの値の意味
二、zipmap.c
コードは比較的簡単です.
1、len
ノード長が254未満、すなわち1バイトの場合、len属性は1文字のセグメント長のみであり、254以上の場合、len属性は5バイト長であり、最初のバイトは0 xFE(10進数の254)に設定され、後の4バイトの記憶長さ
2、zm
3、API
一、注釈
zipmapはziplistと似ていますが、主な目的はメモリの節約です.
1.記憶方式:
Memory layout of a zipmap, for the map "foo" => "bar", "hello" => "world":
<zmlen><len>"foo"<len><free>"bar"<len>"hello"<len><free>"world"
2.それぞれの値の意味
<zmlen>: 1 , zipmap 。
zipmap 254 , zipmap 。
<len> ( )。
<len>: .
( 8 ) 0 253 , 。
254, 。
255 .
<free> value
<free> , 。
, "foo" "hi", 。
, , free , 。
<free> 8 , , zipmap, 。
二、zipmap.c
コードは比較的簡単です.
1、len
ノード長が254未満、すなわち1バイトの場合、len属性は1文字のセグメント長のみであり、254以上の場合、len属性は5バイト長であり、最初のバイトは0 xFE(10進数の254)に設定され、後の4バイトの記憶長さ
// l
// len 254 1 , 254
#define ZIPMAP_LEN_BYTES(_l) (((_l) < ZIPMAP_BIGLEN) ? 1 : sizeof(unsigned int)+1)
// 254, , len
// 254, len , 0xFE( 254),
static unsigned int zipmapDecodeLength(unsigned char *p) {
unsigned int len = *p;
//254
if (len < ZIPMAP_BIGLEN) return len;
memcpy(&len,p+1,sizeof(unsigned int));
memrev32ifbe(&len);
return len;
}
/* Encode the length 'l' writing it in 'p'. If p is NULL it just returns
* the amount of bytes required to encode such a length. */
// l p , p null l
static unsigned int zipmapEncodeLength(unsigned char *p, unsigned int len) {
if (p == NULL) {
return ZIPMAP_LEN_BYTES(len);
} else {
if (len < ZIPMAP_BIGLEN) {
p[0] = len;
return 1;
} else {
// 0xFE( 254),
p[0] = ZIPMAP_BIGLEN;
memcpy(p+1,&len,sizeof(len));
memrev32ifbe(p+1);
return 1+sizeof(len);
}
}
}
2、zm
// map
unsigned char *zipmapNew(void) {
unsigned char *zm = zmalloc(2);
zm[0] = 0;//
zm[1] = ZIPMAP_END;// ,255
return zm;
}
static unsigned char *zipmapLookupRaw(unsigned char *zm, unsigned char *key, unsigned int klen, unsigned int *totlen) {
//p zm , map , zm[0],zm[1],
// zm[1], map zlend( ZIPMAP_END)
unsigned char *p = zm+1, *k = NULL;
unsigned int l,llen;
while(*p != ZIPMAP_END) {
unsigned char free;
/* Match or skip the key */
l = zipmapDecodeLength(p);
llen = zipmapEncodeLength(NULL,l);
if (key != NULL && k == NULL && l == klen && !memcmp(p+llen,key,l)) {
/* Only return when the user doesn't care
* for the total length of the zipmap. */
if (totlen != NULL) {
k = p;
} else {
return p;
}
}
p += llen+l;
/* Skip the value as well */
l = zipmapDecodeLength(p);
p += zipmapEncodeLength(NULL,l);
free = p[0];
p += l+1+free; /* +1 to skip the free byte */
}
// ,p map , len,
if (totlen != NULL) *totlen = (unsigned int)(p-zm)+1;
return k;
}
3、API
//
unsigned char *zipmapNew(void);
//
unsigned char *zipmapSet(unsigned char *zm, unsigned char *key, unsigned int klen, unsigned char *val, unsigned int vlen, int *update);
//
unsigned char *zipmapDel(unsigned char *zm, unsigned char *key, unsigned int klen, int *deleted);
// (zipmapNext) zm[0]
unsigned char *zipmapRewind(unsigned char *zm);
//
unsigned char *zipmapNext(unsigned char *zm, unsigned char **key, unsigned int *klen, unsigned char **value, unsigned int *vlen);
//
int zipmapGet(unsigned char *zm, unsigned char *key, unsigned int klen, unsigned char **value, unsigned int *vlen);
//key
int zipmapExists(unsigned char *zm, unsigned char *key, unsigned int klen);
//
unsigned int zipmapLen(unsigned char *zm);
// zipmap
size_t zipmapBlobLen(unsigned char *zm);
// p
void zipmapRepr(unsigned char *p);