前言:set類似于數(shù)學(xué)上面的集合概念,包含的元素?zé)o序,不能重復(fù),能進(jìn)行交、并、差操作。
一、內(nèi)部原理
set數(shù)據(jù)結(jié)構(gòu),也是隨著元素數(shù)目的多少而變化。當(dāng)set中添加的元素都是整數(shù)且元素數(shù)據(jù)較少時,set使用intset為底層的數(shù)據(jù)結(jié)構(gòu),否則,set使用dict作為底層的數(shù)據(jù)結(jié)構(gòu)。
intset是什么?
從字面意思可以看出是由整數(shù)組成的集合。是一個整數(shù)組成的有序集合,便于進(jìn)行二分查找,快速判斷一個元素是否屬于這個集合。內(nèi)存分配上也是一整塊連續(xù)的內(nèi)存空間,而且根據(jù)數(shù)值的大小采取了不同的編碼,對內(nèi)存使用進(jìn)行了優(yōu)化。
intset數(shù)據(jù)結(jié)構(gòu)如下:
typedef struct intset { uint32_t encoding;/*數(shù)據(jù)編碼,表示intset中每個數(shù)據(jù)元素用幾個字節(jié)來存儲。有三種:數(shù)據(jù)編碼,表示intset中每個數(shù)據(jù)元素用幾個字節(jié)來存儲。 1.INTSET_ENC_INT16表示每個元素用2個字節(jié)存儲, 2.INTSET_ENC_INT32表示每個元素用4個字節(jié)存儲, 3.INTSET_ENC_INT64表示每個元素用8個字節(jié)存儲。 因此,intset中存儲的整數(shù)最多只能占用64bit*/ uint32_t length; /*元素個數(shù)。encoding和length組成了intset頭部。*/ int8_t contents[]; /*是一個柔性數(shù)組,表示intset的header后面緊跟著數(shù)據(jù)元素。這個數(shù)組的總長度(即總字節(jié)數(shù))等于encoding * length*/ } intset;
注:intset可能會隨著數(shù)據(jù)的添加而改變它的數(shù)據(jù)編碼,創(chuàng)建時intset使用占內(nèi)存最小的INTSET_ENC_INT16作為編碼,每增加一個元素,則根據(jù)大小決定是否對數(shù)據(jù)編碼進(jìn)行改變。
例子:
如上圖:
1、新建一個intset只有一個header,總共8個字節(jié),encoding=2,length=0。
2.、添加6,15之后,因為數(shù)值較小,所以encoding不變,length=2。
3、添加32768的時候,超過了兩個字節(jié)(2個字節(jié)能表達(dá)的數(shù)據(jù)范圍是-32768~32767),此時encoding升級到INTSET_ENC_INT32為4,即用4個字節(jié)表示一個元素。
4、添加元素都是按照從小到大的順序。
5、intset是按little endian模式存儲的。在上圖intset添加完所有數(shù)據(jù)之后,32768=>0x00008000
什么時間轉(zhuǎn)為dict?
1、大于512,默認(rèn)設(shè)置:set-max-intset-entries 512
2、超出最大范圍-264~264-1
3、元素里面包含非數(shù)字
set底層用dict時,key是要添加的元素,value為NULL。
區(qū)別:
小集合(整數(shù))用intset存儲節(jié)省內(nèi)存。dict帶來的開銷很大(包含元數(shù)據(jù)信息,兩個hash表、鏈表指針等等)
從時間復(fù)雜度上看,intset是o(log n),而dict可以認(rèn)為是o(1)(因為zipmap),但是intset元素個數(shù)較少,影響不大
二、相關(guān)操作
SADD key member [member ...]
將一個或多個元素加入到集合key中,已存在被忽略。若不存在,則創(chuàng)建。
SCARD key
返回集合key的數(shù)目。
SDIFF key [key ...]
返回集合之間的差集
SDIFFSTORE destination key [key ...]
返回集合之間的差集,并將結(jié)果存儲到目標(biāo)集合。
SINTER key [key ...]
返回集合集合之間的交集
SINTERSTORE destination key [key ...]
返回集合之間的交集,并將結(jié)果存儲到目標(biāo)集合。
SISMEMBER key member
判斷元素是否屬于集合key的成員。
SMOVE source destination member
將元素從源集合移動到目標(biāo)集合。
SPOP key
隨機(jī)移除key集合的某一元素,并返回該元素。
SRANDMEMBER key [count]
隨機(jī)返回一個key集合的元素,若提供count參數(shù),則返回一個包含count個元素的數(shù)組。
SREM key member [member ...]
移除集合中的一個或多個元素。不存在則忽略。
SUNION key [key ...]
返回若干個集合的并集。
SUNIONSTORE destination key [key ...]
返回若干個集合的并集,并存儲在目標(biāo)集合
http://www.cnblogs.com/programlearning/p/7053396.html