redis學習筆記(7) 壓縮字典zipmap

2021-07-11 15:22:56 字數 2643 閱讀 3984

在hashtable實現中,redis引入了zipmap資料結構,保證在hashtable剛建立以及元素較少時,用更少的記憶體來儲存,同時對查詢的效率也不會受太大的影響。

zipmap利用字串實現了簡單的hash表,來儲存少量key-value對。

zipmap的記憶體布局如下:

1)zmlen:1個位元組 ,記錄當前zipmap中key-value對的數量。由於zmlen只有1個位元組,因此規定其表示的數量只能為0~254,當zmlen>254時,就需要遍歷整個zipmap來得到key-value對的個數。

2)len: 用於記錄key或value的長度,有兩種情況,當len的第乙個位元組為0~253時,那麼len就只占用這乙個位元組。的那個len的第乙個位元組為254時,那麼len將用後面的4個位元組來表示。因此len要麼占用1位元組,要麼占用5位元組。

3)free:1位元組 ,表示隨後的value後面的空閒位元組數,這主要是改變key的value引起的,如將」foo」 => 「bar」變為」foo」 => 「hi」,那麼會導致1個位元組的空閒空間。當free的位元組數過大用1個位元組不足以表示時,zipmap就會重新分配記憶體,保證字串盡量緊湊。

4)end:1個位元組 ,為0xff,用於標誌zipmap的結束

乙個簡單的示例如下:

「\x02\x03foo\x03\x00bar\x05hello\x05\x00world\xff」

可以發現:zmlen=2 key1_len=3 key1=」foo」 value1_len=3 free_len=0 value1=」bar」

key2_len=5 key2=」hello」 value2_len=5 free_len=0 value2=」world」 end=0xff

即當前zipmap中共有兩個key-value對,分別為 「foo」 => 「bar」 和 「hello」 => 「world」

unsigned

char *zipmapnew(void)

對於乙個空的zipmap只有2個位元組,1個位元組的zmlen=0,1乙個位元組的end=0xff

//在zm中查詢key,當totlen=null時,表示不需要得到整個zipmap占用的位元組數

static

unsigned

char *zipmaplookupraw(unsigned

char *zm, unsigned

char *key, unsigned

int klen, unsigned

int *totlen) else

}//跳過當前key-value對,比較下乙個

p += llen+l;

l = zipmapdecodelength(p);

p += zipmapencodelength(null,l);

free = p[0];

p += l+1+free; /* +1 to skip the free byte */

}//否則用totlen記錄zipmap占用的位元組數

if (totlen != null) *totlen = (unsigned

int)(p-zm)+1;

return k;

}

unsigned

char *zipmapset(unsigned

char *zm, unsigned

char *key, unsigned

int klen, unsigned

char *val, unsigned

int vlen, int *update) else

}//將當前key-value對後面的內容向後移動,預留空間

empty = freelen-reqlen;

if (empty >= zipmap_value_max_free) else

//向zipmap中寫入key-value對

p += zipmapencodelength(p,klen);

memcpy(p,key,klen);

p += klen;

p += zipmapencodelength(p,vlen);

*p++ = vempty;

memcpy(p,val,vlen);

return zm;

}

int zipmapget(unsigned

char *zm, unsigned

char *key, unsigned

int klen, unsigned

char **value, unsigned

int *vlen)

返回1時表示查詢成功。當查詢成功時,將value的位址和value_len分別儲存在value和vlen中返回。

本文所引用的原始碼全部來自redis3.0.7版本

redis學習參考資料:

redis 設計與實現(第二版)

Redis學習筆記 字典型別

在上篇部落格中在介紹字串型別的時候漏掉了乙個比較重要的內容,在這裡簡單補充下.getbit key offset setbit key offset value bitcount key start end bittop operation destkey key key getbit 獲取字串型別...

BAT呼叫7z壓縮程式

echo off set zip c program files 7 zip 7z.exe set timestamp date 6,4 date 0,2 date 3,2 set dir c temp echo zip echo dir echo timestamp explorer arc zi...

7z壓縮與解壓命令

在寫很多任務具的時候,可能會用到7z命令來進行壓縮與解壓操作。這裡記錄二個比較常用的操作 壓縮 解壓。在dos視窗下輸入7z命令,會顯示7z的使用引數詳情 usage 7z a add files to archive b benchmark d delete files from archive ...