欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

redis中跳表zset的具體使用

 更新時間:2024年01月15日 09:40:48   作者:大牛寫代碼  
Redis跳表zset是一種結(jié)合了跳表和有序集合的高效數(shù)據(jù)結(jié)構(gòu),適用于實現(xiàn)排序和大規(guī)模數(shù)據(jù)的快速查詢,本文主要介紹了redis中跳表zset的具體使用,感興趣的可以了解一下

跳表的基本思想

Skip List(跳躍列表)這種隨機的數(shù)據(jù)結(jié)構(gòu),可以看做是一個二叉樹的變種,它在性能上與紅黑樹、AVL樹很相近;但是Skip List(跳躍列表)的實現(xiàn)相比前兩者要簡單很多,目前Redis的zset實現(xiàn)采用了Skip List(跳躍列表)。

在這里插入圖片描述

特點

1、分層,每層由有序鏈表構(gòu)成
2、頭節(jié)點在每層出現(xiàn)
3、某個節(jié)點如果在上層出現(xiàn),那在下層也出現(xiàn)
4、節(jié)點的層數(shù)是隨機的

節(jié)點與結(jié)構(gòu)

跳躍表節(jié)點zskiplistNode

/* ZSETs use a specialized version of Skiplists */
typedef struct zskiplistNode {
    sds ele;
    double score;
    struct zskiplistNode *backward;
    struct zskiplistLevel {
        struct zskiplistNode *forward;
        unsigned long span;
    } level[];
} zskiplistNode;

屬性

  • ele:存儲字符串?dāng)?shù)據(jù)
  • score:存儲排序分值
  • *backward:指針,指向當(dāng)前節(jié)點最底層的前一個節(jié)點
  • level[]:柔性數(shù)組,隨機生成1-64的值
  • forward:指向本層下一個節(jié)點
  • span:本層下個節(jié)點到本節(jié)點的元素個數(shù)

跳躍表鏈表

typedef struct zskiplist {
    struct zskiplistNode *header, *tail;
    unsigned long length;
    int level;
} zskiplist;

屬性

  • header,tail:頭節(jié)點和尾節(jié)點
  • length:跳躍表長度(不包括頭節(jié)點)
  • tail:跳躍表高度

跳表的設(shè)計思想和優(yōu)勢

1、能夠同時擁有鏈表和數(shù)優(yōu)勢的數(shù)據(jù)結(jié)構(gòu),既有鏈表插入快的特點又有數(shù)組查詢快的特點
2、隨機跨越層數(shù)
3、最底層的鏈表是雙向鏈表,包含所有元素
4、對于有序鏈表查詢優(yōu)化,相比較于平衡數(shù)來說,更好實現(xiàn)
5、內(nèi)存占用上來看,相比較于平衡數(shù)會更少

API解析

Tip:以下的zsl為zskiplist

zslCreate(創(chuàng)建跳躍表)

/* Create a new skiplist. */
zskiplist *zslCreate(void) {
    int j;
    zskiplist *zsl;

    zsl = zmalloc(sizeof(*zsl));
    zsl->level = 1;
    zsl->length = 0;
    zsl->header = zslCreateNode(ZSKIPLIST_MAXLEVEL,0,NULL);
    for (j = 0; j < ZSKIPLIST_MAXLEVEL; j++) {
        zsl->header->level[j].forward = NULL;
        zsl->header->level[j].span = 0;
    }
    zsl->header->backward = NULL;
    zsl->tail = NULL;
    return zsl;
}

大致流程:
1、定義一個zsl,申請內(nèi)存,賦初始值
2、調(diào)用zslCreateNode創(chuàng)建出頭節(jié)點
3、每層頭節(jié)點賦初始值
4、尾節(jié)點賦null值

zslCreateNode(創(chuàng)建節(jié)點)

/* Create a skiplist node with the specified number of levels.
 * The SDS string 'ele' is referenced by the node after the call. */
zskiplistNode *zslCreateNode(int level, double score, sds ele) {
    zskiplistNode *zn =
        zmalloc(sizeof(*zn)+level*sizeof(struct zskiplistLevel));
    zn->score = score;
    zn->ele = ele;
    return zn;
}

大致流程:
1、申請內(nèi)存(節(jié)點內(nèi)存和柔性數(shù)組的內(nèi)存)
2、屬性賦值

zslGetRank(查找排位)

排位就是累積跨越的節(jié)點數(shù)量

unsigned long zslGetRank(zskiplist *zsl, double score, sds ele) {
    zskiplistNode *x;
    unsigned long rank = 0;
    int i;

    x = zsl->header;
    for (i = zsl->level-1; i >= 0; i--) {
        while (x->level[i].forward &&
            (x->level[i].forward->score < score ||
                (x->level[i].forward->score == score &&
                sdscmp(x->level[i].forward->ele,ele) <= 0))) {
            rank += x->level[i].span;
            x = x->level[i].forward;
        }

        /* x might be equal to zsl->header, so test if obj is non-NULL */
        if (x->ele && x->score == score && sdscmp(x->ele,ele) == 0) {
            return rank;
        }
    }
    return 0;
}

大致流程:
1、從最上層開始遍歷節(jié)點并對比元素,對比score
2、如果當(dāng)前分值大雨下一個分值,則累加span(比對分值,如果分值一樣就比對ele)
3、指向本層的下一個節(jié)點
4、如果找到了,也就是ele相同,則返回

zslDelete(刪除節(jié)點)

int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
    zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
    int i;

    x = zsl->header;
    for (i = zsl->level-1; i >= 0; i--) {
        while (x->level[i].forward &&
                (x->level[i].forward->score < score ||
                    (x->level[i].forward->score == score &&
                     sdscmp(x->level[i].forward->ele,ele) < 0)))
        {
            x = x->level[i].forward;
        }
        update[i] = x;
    }
    /* We may have multiple elements with the same score, what we need
     * is to find the element with both the right score and object. */
    x = x->level[0].forward;
    if (x && score == x->score && sdscmp(x->ele,ele) == 0) {
        zslDeleteNode(zsl, x, update);
        if (!node)
            zslFreeNode(x);
        else
            *node = x;
        return 1;
    }
    return 0; /* not found */
}

大致流程:
1、遍歷跳表
2、比對分值,比對ele
3、如分值小于或等于當(dāng)前值,并且ele不相等,繼續(xù)下一個并記錄節(jié)點
4、如分值和ele都相同,調(diào)用zslDeleteNode刪除該節(jié)點

跳表是在很多排名以及分?jǐn)?shù)相關(guān)的場景中使用頻率極高的數(shù)據(jù)結(jié)構(gòu),也是設(shè)計的極其巧妙的一種結(jié)構(gòu),希望本篇文章能幫助各位更加深入的理解這種結(jié)構(gòu)。

到此這篇關(guān)于redis中跳表zset的具體使用的文章就介紹到這了,更多相關(guān)redis 跳表zset內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java實現(xiàn)多級緩存的方法詳解

    Java實現(xiàn)多級緩存的方法詳解

    對于高并發(fā)系統(tǒng)來說,有三個重要的機制來保障其高效運行,它們分別是:緩存、限流和熔斷,所以本文就來和大家探討一下多級緩存的實現(xiàn)方法,希望對大家有所幫助
    2024-02-02
  • 關(guān)于在Redis中使用Pipelining加速查詢的問題

    關(guān)于在Redis中使用Pipelining加速查詢的問題

    這篇文章主要介紹了在Redis中使用Pipelining加速查詢,Redis是一個client-server模式的TCP服務(wù),也被稱為Request/Response協(xié)議的實現(xiàn),本文通過一個例子給大家詳細(xì)介紹,感興趣的朋友一起看看吧
    2022-05-05
  • redission分布式鎖防止重復(fù)初始化問題

    redission分布式鎖防止重復(fù)初始化問題

    這篇文章主要介紹了redission分布式鎖防止重復(fù)初始化問題,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-11-11
  • 基于Redis實現(xiàn)基本搶紅包算法詳解

    基于Redis實現(xiàn)基本搶紅包算法詳解

    [key, value]的緩存數(shù)據(jù)庫, Redis官方性能描述非常高, 所以面對高并發(fā)場景, 使用Redis來克服高并發(fā)壓力是一個不錯的手段, 本文主要基于Redis來實現(xiàn)基本的搶紅包系統(tǒng)設(shè)計,感興趣的朋友跟隨小編一起看看吧
    2024-04-04
  • Redis如何正確關(guān)閉和開啟持久化

    Redis如何正確關(guān)閉和開啟持久化

    本文主要介紹了Redis如何正確關(guān)閉和開啟持久化,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • 解決redis-cli報錯Could not connect to Redis at 127.0.0.1:6379: Connection refused

    解決redis-cli報錯Could not connect to Redis&

    這篇文章主要介紹了解決redis-cli報錯Could not connect to Redis at 127.0.0.1:6379: Connection refused,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • Redis+Lua腳本實現(xiàn)計數(shù)器接口防刷功能(升級版)

    Redis+Lua腳本實現(xiàn)計數(shù)器接口防刷功能(升級版)

    這篇文章主要介紹了Redis+Lua腳本實現(xiàn)計數(shù)器接口防刷功能,使用腳本使得set命令和expire命令一同達(dá)到Redis被執(zhí)行且不會被干擾,在很大程度上保證了原子操作,對Redis實現(xiàn)計數(shù)器接口防刷功能感興趣的朋友一起看看吧
    2022-02-02
  • Redis6.0搭建集群Redis-cluster的方法

    Redis6.0搭建集群Redis-cluster的方法

    這篇文章主要介紹了Redis6.0搭建集群Redis-cluster的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • 如何監(jiān)聽Redis中Key值的變化(SpringBoot整合)

    如何監(jiān)聽Redis中Key值的變化(SpringBoot整合)

    測試過程中我們有一部分常量值放入redis,共大部分應(yīng)用調(diào)用,但在測試過程中經(jīng)常有人會清空redis,回歸測試,下面這篇文章主要給大家介紹了關(guān)于如何監(jiān)聽Redis中Key值變化的相關(guān)資料,需要的朋友可以參考下
    2024-03-03
  • 基于Redis實現(xiàn)抽獎功能及問題小結(jié)

    基于Redis實現(xiàn)抽獎功能及問題小結(jié)

    這篇文章主要介紹了基于Redis實現(xiàn)抽獎功能,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-08-08

最新評論