新聞中心
Redis的集合底層實(shí)現(xiàn):精妙機(jī)制運(yùn)行效率高

成都創(chuàng)新互聯(lián)是一家集網(wǎng)站建設(shè),臨武企業(yè)網(wǎng)站建設(shè),臨武品牌網(wǎng)站建設(shè),網(wǎng)站定制,臨武網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營(yíng)銷,網(wǎng)絡(luò)優(yōu)化,臨武網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競(jìng)爭(zhēng)力。可充分滿足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶成長(zhǎng)自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。
Redis是一款高性能的NoSQL數(shù)據(jù)庫(kù),集合是其中重要的數(shù)據(jù)結(jié)構(gòu)之一。它的底層實(shí)現(xiàn)非常精妙,基于跳表和字典實(shí)現(xiàn)的結(jié)構(gòu),讓集合操作的運(yùn)行效率非常高。
集合的底層數(shù)據(jù)結(jié)構(gòu)
Redis的集合底層數(shù)據(jù)結(jié)構(gòu)是由兩個(gè)結(jié)構(gòu)體組成的:
“`c
typedef struct {
//表示集合的字典
dict *dict;
} dictSet;
typedef struct {
//表示集合的跳表
zskiplist *zsl;
} zset;
其中,dictSet結(jié)構(gòu)體利用了字典結(jié)構(gòu)dict,在代碼中實(shí)現(xiàn)如下:
```c
typedef struct dict {
dictType *type;
void *privdata;
dictht ht[2];
unsigned long rehashidx; /* rehashing not in progress if rehashidx == -1 */
int iterators; /* number of iterators currently running */
} dict;
另外一個(gè)zset結(jié)構(gòu)體則利用了跳表結(jié)構(gòu)zskiplist,在代碼中實(shí)現(xiàn)如下:
“`c
typedef struct zskiplist {
struct zskiplistNode *header, *tl;
unsigned long length;
int level;
} zskiplist;
typedef struct zskiplistNode {
robj *obj;
double score;
struct zskiplistNode *backward;
struct zskiplistLevel {
struct zskiplistNode *forward;
unsigned int span;
} level[];
} zskiplistNode;
從這兩個(gè)結(jié)構(gòu)體可以看出,在Redis中,集合被實(shí)現(xiàn)了兩種不同的方式,一種是字典結(jié)構(gòu),另一種是跳表結(jié)構(gòu)。其中字典結(jié)構(gòu)的實(shí)現(xiàn)比較簡(jiǎn)單,直接利用了dict結(jié)構(gòu),而跳表結(jié)構(gòu)則比較復(fù)雜,利用了zskiplistNode結(jié)構(gòu)以及一些操作跳表的函數(shù)。
集合的操作
Redis的集合提供了大量的操作方法,如添加元素、刪除元素、判斷元素是否存在、求并集、求交集、求差集等。下面以添加元素為例,看看Redis是如何實(shí)現(xiàn)集合的操作的。
以添加元素為例,Redis提供了兩種不同的方法,一種是使用字典結(jié)構(gòu)實(shí)現(xiàn),一種是使用跳表結(jié)構(gòu)實(shí)現(xiàn)。這兩種方法的實(shí)現(xiàn)代碼如下:
使用字典:
```c
int dictAdd(dict *d, void *key, void *val)
{
dictEntry *entry = dictAddRaw(d,key,NULL);
if (!entry) return DICT_ERR;
dictSetVal(d, entry, val);
return DICT_OK;
}
使用跳表:
“`c
zskiplistNode *zslInsert(zskiplist *zsl, double score, robj *obj) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
assert(!isnan(score));
x = zsl->header;
for (i = zsl->level-1; i >= 0; i–) {
/* store rank that is crossed to reach the insert position */
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
while (x->level[i].forward &&
(x->level[i].forward->score
(x->level[i].forward->score == score &&
compareStringObjects(x->level[i].forward->obj,obj)
rank[i] += x->level[i].span;
x = x->level[i].forward;
}
update[i] = x;
}
/* we assume the element is not already inside, since we allow duplicated
* scores, and the re-insertion of score and redisObject is rare enough
* to just handle it with O(N) brute force search. */
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i
rank[i] = 0;
update[i] = zsl->header;
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
x = zslCreateNode(level,score,obj);
for (i = 0; i
x->level[i].forward = update[i]->level[i].forward;
update[i]->level[i].forward = x;
x->level[i].span = update[i]->level[i].span – (rank[0] – rank[i]);
update[i]->level[i].span = (rank[0] – rank[i]) + 1;
}
for (i = level; i level; i++) {
update[i]->level[i].span++;
}
x->backward = (update[0] == zsl->header) ? NULL : update[0];
if (x->level[0].forward)
x->level[0].forward->backward = x;
else
zsl->tl = x;
zsl->length++;
return x;
}
通過分析代碼可以發(fā)現(xiàn),雖然Redis使用了兩種不同的數(shù)據(jù)結(jié)構(gòu)來實(shí)現(xiàn)集合,但是在具體操作這些數(shù)據(jù)結(jié)構(gòu)上,兩者的代碼是非常相似的。
集合的優(yōu)點(diǎn)
利用跳表和字典結(jié)構(gòu)實(shí)現(xiàn)的集合,有以下幾個(gè)優(yōu)點(diǎn):
1.查找速度快:跳表是一種高級(jí)數(shù)據(jù)結(jié)構(gòu),能夠在運(yùn)行時(shí)達(dá)到O(log n)的平均速度,因此Redis內(nèi)部使用跳表的方式能夠大大提高集合操作的效率。
2.插入和刪除速度快:跳表是鏈表的變種,因此它具有鏈表的插入和刪除速度快的優(yōu)點(diǎn),具有O(1)的插入和刪除時(shí)間復(fù)雜度。
3.支持有序集合:集合的有序集合可以在哪些元素之間引入一個(gè)排序關(guān)系,從而提供了一些額外的功能,例如范圍查找操作。
結(jié)語(yǔ)
Redis內(nèi)部使用跳表和字典結(jié)構(gòu)來實(shí)現(xiàn)集合,可以提供非常高效的操作速度,而且也保證了集合的數(shù)據(jù)完整性和安全性。對(duì)于Redis的使用者來說,了解Redis集合的底層實(shí)現(xiàn)對(duì)于合理利用Redis更加高效,可以讓Redis發(fā)揮出更大的作用。
香港服務(wù)器選創(chuàng)新互聯(lián),2H2G首月10元開通。
創(chuàng)新互聯(lián)(www.cdcxhl.com)互聯(lián)網(wǎng)服務(wù)提供商,擁有超過10年的服務(wù)器租用、服務(wù)器托管、云服務(wù)器、虛擬主機(jī)、網(wǎng)站系統(tǒng)開發(fā)經(jīng)驗(yàn)。專業(yè)提供云主機(jī)、虛擬主機(jī)、域名注冊(cè)、VPS主機(jī)、云服務(wù)器、香港云服務(wù)器、免備案服務(wù)器等。
當(dāng)前題目:Redis的集合底層實(shí)現(xiàn)精妙機(jī)制運(yùn)行效率高(redis的集合底層實(shí)現(xiàn))
標(biāo)題來源:http://m.fisionsoft.com.cn/article/cdischs.html


咨詢
建站咨詢
