15天玩转redis —— 第五篇 集合对象类型
这篇我们来看看Redis五大类型中的第四大类型:“集合类型”,集合类型还是蛮有意思的,第一个是因为它算是只使用key的Dictionary简易版, 这样说来的话,它就比Dictionary节省很多内存消耗,第二个是因为它和C#中的HashSet是一个等同类型,废话不多说,先看redis手册,如下: 上面就是redis中的set类型使用到的所有方法,还是老话,常用的方法也就那么四个(CURD)。。。
这个方法毫无疑问,就是向集合里面添加数据,比如下面这样,我往fruits集合里面添加喜爱的水果。 .:>
.:>
.:>)
)
.:>
上面这个sadd你也看到了,我往集合里面成功添加了两个元素,现在你可能不满足这么简单的添加,你或许想知道set这个集合在redis底层是使用 什么来实现的,你可以用object encoding查看一下便知: .:>
.:>
看到了吧,是hashtable这个吊毛,现在闭上眼睛都能想到,肯定就是只用key的dictionary啦,对不对,如果你还有疑问的话,我还可以找到底层 代码给你看,好不啦??? 有没有看到dictAdd方法,而其中的第三个参数正好是Null。。。对应着*val形参,你看牛叉不牛叉。。。然后我再带你看看dictAdd方法的定义。 好了,关于hashtable的实现理论,我在上一篇文章中也已经说过了,这里就不再赘叙了。
? ? 既然元素进来了,总不能不出来吧,这里的第一个SPOP:有一点奇怪的是,这种奇怪的方法其实在我们 C#中的HashSet并没有好办法解决,就比如”这个随机“就有点烦人了,下面这是我能想到的方法。 刚才随便插了一句话,下面我们继续SAdd,再SPop出来。 .:>
.:>
.:>
.:>)
)
)
)
)
.:>
.:>
.:>)
)
)
.:>
这个方法确实还是蛮好的,起码它是原子性操作,如果要我自己实现的话,起码还是要10行左右代码的。
? ? 既然说到了CURD,那怎么能少了D呢,它的功能定义就是: 下面我随便举个例子,删除fruits中的pear。 .:>)
)
)
.:>
.:>)
)
.:>
? 就比如Set函数,它的源代码全部都在 “t.set.c” 中。
#include
sunionDiffGenericCommand(redisClient *c,robj **setkeys, setnum,robj *dstkey,
robj *setTypeCreate(robj * (isObjectRepresentableAsLongLong(value,NULL) ==
setTypeAdd(robj *subject,robj * (subject->encoding == (dictAdd(subject->ptr,value,NULL) == } (subject->encoding == (isObjectRepresentableAsLongLong(value,&llval) == uint8_t success = subject->ptr = intsetAdd(subject->ptr,llval,&
(intsetLen(subject->ptr) > }
redisAssertWithInfo(NULL,dictAdd(subject->ptr,NULL) == } redisPanic(
setTypeRemove(robj *setobj,robj * (setobj->encoding == (dictDelete(setobj->ptr,value) == (htNeedsResize(setobj->ptr)) dictResize(setobj-> } (setobj->encoding == (isObjectRepresentableAsLongLong(value,&llval) == setobj->ptr = intsetRemove(setobj->ptr,& (success) } redisPanic( |