亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

redis源碼學習之壓縮列表

2019-11-14 12:08:24
字體:
來源:轉載
供稿:網友

壓縮列表

列表鍵和哈希鍵的底層實現。是為了節約內存而實現。

壓縮列表是一段連續的內存,每個屬性都會有固定的編碼大小,例如對于字符串來說,我們需要知道字符串的長度,假設小于63字節,那么我們只需要一個字節的大小來表示(2位標識,6位數據);而存儲的結構是整型的數的話,我們只需要1個字節來表示該整型是16/32/64位整型。

壓縮列表用一段連續內存表示unsigned char *類型指針來訪問,不過它人為的規定了這一段連續內存的數據類型: 前4個字節(uint32_t)表示整個ziplist的長度所占用的內存數:zlbytes; 再往后4個字節表示表尾節點到壓縮列表的字節數:zltail; 然后2個字節(uint16_t)表示壓縮列表中節點數目:zllen; 之后就是數據內容zlentry; 最后壓縮列表有1個字節的特殊值標記列表末尾:zlend:0xFF

根據上述說明,redis定義了一些宏來獲取各個元素的值,主要是進行地址運算,因為header的大小固定:

// 定位到 ziplist 的 bytes 屬性,該屬性記錄了整個 ziplist 所占用的內存字節數// 用于取出 bytes 屬性的現有值,或者為 bytes 屬性賦予新值#define ZIPLIST_BYTES(zl) (*((uint32_t*)(zl)))// 定位到 ziplist 的 offset 屬性,該屬性記錄了到達表尾節點的偏移量// 用于取出 offset 屬性的現有值,或者為 offset 屬性賦予新值#define ZIPLIST_TAIL_OFFSET(zl) (*((uint32_t*)((zl)+sizeof(uint32_t))))// 定位到 ziplist 的 length 屬性,該屬性記錄了 ziplist 包含的節點數量// 用于取出 length 屬性的現有值,或者為 length 屬性賦予新值#define ZIPLIST_LENGTH(zl) (*((uint16_t*)((zl)+sizeof(uint32_t)*2)))// 返回 ziplist 表頭的大小#define ZIPLIST_HEADER_SIZE (sizeof(uint32_t)*2+sizeof(uint16_t))// 返回指向 ziplist 第一個節點(的起始位置)的指針#define ZIPLIST_ENTRY_HEAD(zl) ((zl)+ZIPLIST_HEADER_SIZE)// 返回指向 ziplist 最后一個節點(的起始位置)的指針#define ZIPLIST_ENTRY_TAIL(zl) ((zl)+intrev32ifbe(ZIPLIST_TAIL_OFFSET(zl)))// 返回指向 ziplist 末端 ZIP_END (的起始位置)的指針#define ZIPLIST_ENTRY_END(zl) ((zl)+intrev32ifbe(ZIPLIST_BYTES(zl))-1)

對字節長度進行編碼,有兩個數據類型,一個是字節長度,一個是編碼字節長度所需要的長度。

在Redis設計與實現中,給了兩個表格,分別是字節數組編碼(在源碼中又叫字符串),整數編碼。

現在給定一個長度len,需要對其進行編碼。首先源碼中定義了一些宏,分別表示不同字節范圍表示的編碼。

/* * 字符串編碼類型 */#define ZIP_STR_06B (0 << 6)//長度小于等于63字節#define ZIP_STR_14B (1 << 6)//長度小于等于16383字節#define ZIP_STR_32B (2 << 6)//長度小于等于4294967295字節/* * 整數編碼類型 */#define ZIP_INT_16B (0xc0 | 0<<4)//1100 0000#define ZIP_INT_32B (0xc0 | 1<<4)//1101 0000#define ZIP_INT_64B (0xc0 | 2<<4)//1110 0000#define ZIP_INT_24B (0xc0 | 3<<4)//1111 0000#define ZIP_INT_8B 0xfe//1111 1110

這種編碼方式很好理解,對于長度小于等于63字節編碼,編碼方式應該是00xxxxxx,除了高位兩位的標識位,后六位能表示的數字范圍為0~63,這是1個字節的情況。當數據變大時,一個字節顯然不能滿足條件了,因此就需要加一個字節(8+6 位)的編碼長度來表示長度。

如果是整型類型編碼就容易多了,不同于字節數組需要記錄數據長度,整型數據總是只需要1個字節來表示整型數據類型。

在redis源碼src/ziplist.c中用zipEncodeLength函數來描述上述過程。

static unsigned int zipEncodeLength(unsigned char *p, unsigned char encoding, unsigned int rawlen) { unsigned char len = 1, buf[5]; // 編碼字符串 if (ZIP_IS_STR(encoding)) { /* Although encoding is given it may not be set for strings, * so we determine it here using the raw length. */ if (rawlen <= 0x3f) {//63 if (!p) return len;//1 buf[0] = ZIP_STR_06B | rawlen; } else if (rawlen <= 0x3fff) {//16383 len += 1;//2 if (!p) return len; buf[0] = ZIP_STR_14B | ((rawlen >> 8) & 0x3f); buf[1] = rawlen & 0xff; } else { len += 4;//5 if (!p) return len; buf[0] = ZIP_STR_32B; buf[1] = (rawlen >> 24) & 0xff; buf[2] = (rawlen >> 16) & 0xff; buf[3] = (rawlen >> 8) & 0xff; buf[4] = rawlen & 0xff; } // 編碼整數 } else { /* Implies integer encoding, so length is always 1. */ if (!p) return len; buf[0] = encoding; } /* Store this length at p */ // 將編碼后的長度寫入 p memcpy(p,buf,len); // 返回編碼所需的字節數 return len;}

插入元素

主要過程是: 1.確定插入位置:頭插/尾插。 分為頭部和尾部來討論, 如果在頭部插入,則待插入元素所需要的字節數就是頭部元素PRelen的值。 如果在尾部插入,則尾部元素的字節長度就是p節點的prelen長度。 2.嘗試將字符串轉換為長整型,比如“123”->123 轉換成功將根據encoding獲取不同編碼獲取不同大小例如uint_32位4個字節,否則使用字符串原始長度,例如“hello”長度為5個字節,將這個長度值加到reqlen上,reqlen為新添加節點的長度,包括content的長度和header的長度。 3.將prelen編碼長度加到reqlen上 4.將encoding編碼長度加到reqlen上 5.之后就是最復雜的一步了,就考慮如果在頭部插入元素,且原來頭部元素的prelen不夠編碼新的元素,他們之間產生一個差值,這個差值也要計算到重新分配ziplist時的大小。 比如,原節點的prelen為1個字節(記錄content小于254的情況),現在插入一個很長的節點,則需要5個字節的空間保存,那么這個額外多出來的4個字節nextdiff則需要記錄進來。 6.重新申請ziplist大小,為原長度curlen+新節點長度reqlen+第5步所說的nextdiff。 7.調整原來的元素,為新元素挪動位置。 8.將header寫入新元素地址,此時需要挪動指針,方便拷貝content。這部分想了很久:

// 一切搞定,將前置節點的長度寫入新節點的 header p += zipPrevEncodeLength(p,prevlen); // 將節點值的長度寫入新節點的 header p += zipEncodeLength(p,encoding,slen);//這里寫入同時還要移動p的位置,方便后面memcpy拷入content // 寫入節點值 if (ZIP_IS_STR(encoding)) { // T = O(N) memcpy(p,s,slen); } else { // T = O(1) zipSaveInteger(p,value,encoding); }
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产综合香蕉五月婷在线| 91夜夜未满十八勿入爽爽影院| 久久全国免费视频| 在线视频欧美日韩| 在线视频日本亚洲性| 国产精品永久免费观看| 亚洲伊人久久综合| 欧美另类在线观看| 欧美午夜精品久久久久久浪潮| 欧美日韩日本国产| 亚洲国产欧美一区二区丝袜黑人| 国产一区二区三区在线看| 欧美一性一乱一交一视频| 日韩在线中文字| www.亚洲一二| 日日骚久久av| 欧美大片在线免费观看| 亚洲精品永久免费| 国产精自产拍久久久久久| 91精品国产沙发| 亚洲成年人在线播放| 色婷婷综合久久久久| 91在线精品播放| 欧美大胆a视频| 欧美国产中文字幕| 成人免费xxxxx在线观看| 91国产视频在线播放| 国产一区二区三区在线免费观看| 欧美三级免费观看| 懂色av影视一区二区三区| 7777免费精品视频| 日本道色综合久久影院| 97超级碰在线看视频免费在线看| 国产精品你懂得| 中文字幕欧美精品日韩中文字幕| 欧美日韩一二三四五区| 欧美精品做受xxx性少妇| 日韩欧美精品网址| 性欧美办公室18xxxxhd| 国产女人18毛片水18精品| 精品夜色国产国偷在线| 2019最新中文字幕| 国产精品香蕉av| 日韩激情av在线免费观看| 亚洲欧美一区二区三区情侣bbw| 国产一区二区三区直播精品电影| 亚洲一区二区黄| 亚洲视频自拍偷拍| 亚洲精品电影网在线观看| 欧美成人精品在线播放| 中文字幕日韩在线播放| 亚洲精品日韩激情在线电影| 亚洲美女av在线播放| 日韩在线观看免费全| 91高清免费在线观看| 精品视频偷偷看在线观看| 日韩精品在线免费| 欧美亚洲在线播放| 亚洲欧美国内爽妇网| 亚洲国产精品yw在线观看| 国产欧美一区二区白浆黑人| www.欧美免费| 色老头一区二区三区| 日韩精品中文字| 国产精品99久久久久久久久久久久| 在线观看中文字幕亚洲| 亚洲人午夜精品免费| 欧美日韩国产丝袜美女| 日韩在线免费av| 成人女保姆的销魂服务| 色一情一乱一区二区| 亚洲一区亚洲二区| 免费97视频在线精品国自产拍| 中文在线资源观看视频网站免费不卡| 自拍视频国产精品| 疯狂蹂躏欧美一区二区精品| 日韩高清中文字幕| 久久99久久亚洲国产| 欧美性猛交xxxx乱大交3| 91久久久久久久久久久| 日韩av在线天堂网| 国产精品第2页| 亚洲欧洲日本专区| 91久久久久久久久久久| 亚洲欧美日韩中文在线制服| www日韩欧美| 国产成人+综合亚洲+天堂| 亚洲欧美日韩爽爽影院| 日韩激情片免费| 欧美成人精品一区二区三区| 国产精品网站大全| 国产精品成人国产乱一区| 日本高清+成人网在线观看| 日韩激情av在线播放| 久久99精品久久久久久噜噜| 欧美电影免费观看大全| 国产噜噜噜噜久久久久久久久| 久久这里只有精品99| 欧美激情区在线播放| 夜夜嗨av色综合久久久综合网| 日韩激情在线视频| 亚洲欧美一区二区激情| 亚洲欧美日韩国产中文专区| 中文字幕欧美视频在线| 欧美激情亚洲精品| 国产精品久久一| 日韩电影中文字幕在线| 成人精品一区二区三区电影免费| 亚洲aⅴ日韩av电影在线观看| 日韩成人激情视频| 久久99精品久久久久久青青91| 亚洲国产精久久久久久久| 亚洲电影免费观看高清完整版| 成人高清视频观看www| 国产精品久久二区| 欧美性xxxx极品高清hd直播| 欧美激情在线视频二区| 国内精品久久久| 久久久精品视频成人| 久久亚洲精品中文字幕冲田杏梨| 亚洲视频在线观看免费| 欧美国产日韩在线| 成人av.网址在线网站| 欧美一级视频一区二区| 国模叶桐国产精品一区| 久久久999精品视频| 黑人巨大精品欧美一区免费视频| 欧美日韩国产专区| 国产精品96久久久久久又黄又硬| 欧美电影《睫毛膏》| 久久久久久久久久亚洲| 日韩在线小视频| 国产精品久久久久久亚洲调教| 国产精品视频免费观看www| 日韩中文字幕国产精品| 国产亚洲激情在线| 亚洲国产成人精品电影| 国产精品草莓在线免费观看| 久久天天躁狠狠躁夜夜爽蜜月| 亚洲欧美国产精品久久久久久久| 在线视频欧美日韩精品| 精品无码久久久久久国产| 日本欧美一级片| 国产精品爽爽爽| 国产日韩欧美夫妻视频在线观看| 一区二区三区天堂av| 97视频免费在线观看| 成人午夜在线视频一区| 亚洲精品欧美一区二区三区| 亚洲成年人影院在线| 亚洲美女性生活视频| 久久av在线看| 777777777亚洲妇女| 欧美成人午夜激情在线| 欧美天天综合色影久久精品| 91欧美精品午夜性色福利在线| 成人免费在线视频网址| 自拍亚洲一区欧美另类| 青青草原成人在线视频| 久久精品男人天堂| 国产这里只有精品| www亚洲欧美| 国产欧美一区二区三区久久| 国产精品a久久久久久|