redis代碼結構之三類型庫-string

來源:互聯網
上載者:User

redis代碼結構之三類型庫-list 

1. 類型庫概述

下面介紹redis核心的內容以及所支援的資料類型及操作。首先看一下相應的資料結構:

typedef char *sds; //該檔案返回的基本上都是sds,即char *,也是實際儲存內容的地址。struct sdshdr {    int len; //內容擁有的空間,不包括該結構的本身的大小,也不包括buf最後的結束符’\0’    int free; //剩下的可用記憶體空間,buf中可能有一些沒有使用,這些的長度就是free的值    char buf[]; //實際的儲存內容=strlen(buf)+free=len};

該類型是redis使用最多的類型,它類似c++的string類型。相應的函數包括sds sdsnewlen(const void *init, size_t initlen) ,它首先申請sh = zmalloc(sizeof(struct sdshdr)+initlen+1);記憶體(註:sizeof(struct sdshdr)=8),initlen就是sdshdr->len,而init則會被memcpy到sdshdr->buf裡,並且此時sdshdr->free為0。最後返回(char*)sh->buf,即實際內容的地址。其它的就類似於string的方法。 

typedef struct redisObject {    unsigned type:4;    unsigned storage:2;     /* REDIS_VM_MEMORY or REDIS_VM_SWAPPING */    unsigned encoding:4;    unsigned lru:22;        /* lru time (relative to server.lruclock) */    int refcount;    void *ptr;} robj;

該結構定義了redis的操作對象的抽象資料類型。
Type:定義該資料的類型,當前的redis支援5種資料類型:REDIS_STRING、REDIS_LIST、REDIS_SET、REDIS_ZSET、REDIS_HASH。
Storage:定義資料當前的位置記憶體還是硬碟的swap。
Encoding:定義資料類型使用的編碼方式或者叫記憶體的儲存方式,當前redis支援8種encoding。各種類型及所支援的編碼見下表:

類型

REDIS_STRING(t_string.c)

REDIS_LIST(t_list.c,ziplist.c)

REDIS_SET(t_set.c)

REDIS_ZSET(t_zset.c)

REDIS_HASH(t_hash.c)

命令

set,mset

lpush,rpush,lpop,rpop

sadd

zadd

Hset,hmset

編碼

REDIS_ENCODING_RAW, REDIS_ENCODING_INT

REDIS_ENCODING_ZIPLIST, REDIS_ENCODING_LINKEDLIST

REDIS_ENCODING_HT, REDIS_ENCODING_INTSET

REDIS_ENCODING_ZIPLIST, REDIS_ENCODING_SKIPLIST

REDIS_ENCODING_HT, REDIS_ENCODING_ZIPMAP

資料的類型是由使用者的命令決定的,另外所有的key都使用REDIS_STRING類型(在dbAdd的時候再提取出實際的內容sds copy = sdsdup(key->ptr);,這個就是真正儲存到dict裡的key值),並且它的encoding只為REDIS_ENCODING_RAW;而編碼則是由server根據配置及當前的系統情況進行選擇的(這個條件我們在後面的每種類型中分別介紹)。
Lru:
Refcount:該對象的引用個數
Ptr:指向實際儲存的內容
Server在接收到client請求的時候總是先把命令的所有成員轉換成type=REDIS_STRING,encoding = REDIS_ENCODING_RAW為的robj類型儲存到client->argv[]裡(0是命令,1是key,2,3..是value【2可能是expire值】,這個過程在processInlineBuffer或者processMultibulkBuffer函數裡完成)。同時在調用每個命令相應的處理函數的時候,大多數命令都會對value先進行一個tryObjectEncoding,即判斷該value是否可表示為long類型string2l(s,sdslen(s),&value),如果可以的話就使用shared.integers[value],或者encoding
= REDIS_ENCODING_INT,代碼如下:

if (!string2l(s,sdslen(s),&value)) return o;…if (server.maxmemory == 0 && value >= 0 && value < REDIS_SHARED_INTEGERS &&   pthread_equal(pthread_self(),server.mainthread)) {    decrRefCount(o);      incrRefCount(shared.integers[value]);      return shared.integers[value];} else {     o->encoding = REDIS_ENCODING_INT;     sdsfree(o->ptr);     o->ptr = (void*) value;     return o;}下面我們分別介紹五種資料類型的相應結構及操作。(每種類型的操作指令及含義可參考http://www.w3ccollege.org/redis/redis-command-manual.html)2. REDIS_STRING(t_string.c)該類型的命令包括:set,setnx,setex,mset,incr,append等等。這裡我們只介紹set命令,它相應的命令回呼函數為
setCommand(redisClient *c) {    c->argv[2] = tryObjectEncoding(c->argv[2]);    setGenericCommand(c,0,c->argv[1],c->argv[2],NULL);}

該類型的大多數命令都是通過調用setGenericCommand函數為內部介面:

void setGenericCommand(redisClient *c, int nx, robj *key, robj *val, robj *expire) {    long seconds = 0; /* initialized to avoid an harmness warning */    if (expire) {//設定到期時間的操作        if (getLongFromObjectOrReply(c, expire, &seconds, NULL) != REDIS_OK)            return;        if (seconds <= 0) {            addReplyError(c,"invalid expire time in SETEX");            return;        }    }    //如果該key存在,並且命令要求在key不存在時才set,此時則返回    if (lookupKeyWrite(c->db,key) != NULL && nx) {        addReply(c,shared.czero);        return;    }    setKey(c->db,key,val); //向字典中追加key,val    server.dirty++;//設定dirty持久化時使用    if (expire) setExpire(c->db,key,time(NULL)+seconds);//向expire dict中添加該事件    addReply(c, nx ? shared.cone : shared.ok);}

這就是set操作的過程,很簡單。其內部的setKey就是調用db.c,dict.c的函數。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.