加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

15天玩转redis —— 第五篇 集合对象类型

发布时间:2020-12-16 04:45:36 所属栏目:安全 来源:网络整理
导读:这篇我们来看看Redis五大类型中的第四大类型:“集合类型”,集合类型还是蛮有意思的,第一个是因为它算是只使用key的Dictionary简易版, 这样说来的话,它就比Dictionary节省很多内存消耗,第二个是因为它和C#中的HashSet是一个等同类型,废话不多说,先看r

  这篇我们来看看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( setTypeIsMember(robj *subject,robj * (subject->encoding == dictFind((dict*)subject->ptr,value) != } (subject->encoding == (isObjectRepresentableAsLongLong(value,&llval) == intsetFind((intset*)subject-> } redisPanic( setTypeIterator *setTypeInitIterator(robj * setTypeIterator *si = zmalloc( si->subject = si->encoding = subject-> (si->encoding == si->di = dictGetIterator(subject-> } (si->encoding == si->ii = } redisPanic( setTypeReleaseIterator(setTypeIterator * (si->encoding == dictReleaseIterator(si-> setTypeNext(setTypeIterator *si,robj **objele,int64_t * (si->encoding == dictEntry *de = dictNext(si-> (de == NULL) - *objele = } (si->encoding == (!intsetGet(si->subject->ptr,si->ii++ - si-> robj *setTypeNextObject(setTypeIterator * robj * encoding = setTypeNext(si,&objele,& -: redisPanic( NULL; encoding setTypeRandomElement(robj *setobj,int64_t * (setobj->encoding == dictEntry *de = dictGetRandomKey(setobj-> *objele = } (setobj->encoding == *llele = intsetRandom(setobj-> } redisPanic( setobj-> unsigned setTypeSize(robj * (subject->encoding == dictSize((dict*)subject-> } (subject->encoding == intsetLen((intset*)subject-> } redisPanic( setTypeConvert(robj *setobj, setTypeIterator * redisAssertWithInfo(NULL,setobj,setobj->type == REDIS_SET && setobj->encoding == (enc == dict *d = dictCreate(& robj * dictExpand(d,intsetLen(setobj-> si = (setTypeNext(si,NULL,&intele) != - element = redisAssertWithInfo(NULL,element,dictAdd(d,NULL) == setobj->encoding = zfree(setobj-> setobj->ptr = } redisPanic( saddCommand(redisClient * robj * j,added = = lookupKeyWrite(c->db,c->argv[ ( == = setTypeCreate(c->argv[ dbAdd(c->db,c->argv[], } (->type != (j = ; j < c->argc; j++ c->argv[j] = tryObjectEncoding(c-> (setTypeAdd(,c->argv[j])) added++ signalModifiedKey(c->db,c->argv[ notifyKeyspaceEvent(REDIS_NOTIFY_SET,,c->db-> server.dirty += sremCommand(redisClient * robj * j,deleted = ,keyremoved = (( = lookupKeyWriteOrReply(c,shared.czero)) == NULL || checkType(c,,REDIS_SET)) (j = ; j < c->argc; j++ (setTypeRemove(,c-> deleted++ (setTypeSize() == dbDelete(c->db,c->argv[ keyremoved = signalModifiedKey(c->db,c->argv[ notifyKeyspaceEvent(REDIS_NOTIFY_SET,,c->db-> notifyKeyspaceEvent(REDIS_NOTIFY_GENERIC,,c->argv[ c->db-> server.dirty += smoveCommand(redisClient * robj *srcset,*dstset,* srcset = lookupKeyWrite(c->db,c->argv[ dstset = lookupKeyWrite(c->db,c->argv[ ele = c->argv[] = tryObjectEncoding(c->argv[ (srcset == (checkType(c,srcset,REDIS_SET) || (dstset && checkType(c,dstset,REDIS_SET))) (srcset == addReply(c,setTypeIsMember(srcset,ele) ? (! notifyKeyspaceEvent(REDIS_NOTIFY_SET,c->db-> (setTypeSize(srcset) == dbDelete(c->db,c->argv[ notifyKeyspaceEvent(REDIS_NOTIFY_GENERIC,c->db-> signalModifiedKey(c->db,c->argv[ signalModifiedKey(c->db,c->argv[ server.dirty++ (! dstset = dbAdd(c->db,c->argv[ server.dirty++ notifyKeyspaceEvent(REDIS_NOTIFY_SET,c->argv[],c->db-> sismemberCommand(redisClient * robj * (( = lookupKeyReadOrReply(c,shared.czero)) == NULL || checkType(c,REDIS_SET)) c->argv[] = tryObjectEncoding(c->argv[ (setTypeIsMember(,c->argv[ scardCommand(redisClient * robj * ((o = lookupKeyReadOrReply(c,shared.czero)) == NULL || checkType(c,o,REDIS_SET)) spopCommand(redisClient * robj *,*ele,* (( = lookupKeyWriteOrReply(c,shared.nullbulk)) == NULL || checkType(c,REDIS_SET)) encoding = setTypeRandomElement(,&ele,& (encoding == ele = ->ptr = intsetRemove(-> } setTypeRemove( notifyKeyspaceEvent(REDIS_NOTIFY_SET,,c->db-> aux = createStringObject(, rewriteClientCommandVector(c,,aux,ele); (setTypeSize() == dbDelete(c->db,c->argv[ notifyKeyspaceEvent(REDIS_NOTIFY_GENERIC,c->db-> signalModifiedKey(c->db,c->argv[ server.dirty++ " variant. The normal version of the SRANDMEMBER_SUB_STRATEGY_MUL 3 srandmemberWithCountCommand(redisClient * unsigned uniq = robj *,* dict * (getLongFromObjectOrReply(c,&l,NULL) != REDIS_OK) (l >= count = } count = - uniq = (( = lookupKeyReadOrReply(c,shared.emptymultibulk)) == NULL || checkType(c,REDIS_SET)) size = setTypeSize( (count == (! (count-- encoding = setTypeRandomElement(,& (encoding == } (count >= sunionDiffGenericCommand(c,c->argv+, d = dictCreate(& (count*SRANDMEMBER_SUB_STRATEGY_MUL > setTypeIterator * si = setTypeInitIterator( ((encoding = setTypeNext(si,&llele)) != - retval = (encoding == retval = } retval = redisAssert(retval == redisAssert(dictSize(d) == (size > dictEntry * de = size-- unsigned added = (added < encoding = setTypeRandomElement(,& (encoding == ele = } ele = (dictAdd(d,ele,NULL) == added++ dictIterator * dictEntry * di = ((de = dictNext(di)) != srandmemberCommand(redisClient * robj *,* (c->argc == } (c->argc > (( = lookupKeyReadOrReply(c,shared.nullbulk)) == NULL || checkType(c,REDIS_SET)) encoding = setTypeRandomElement(,& (encoding == } qsortCompareSetsByCardinality( *s1, * setTypeSize(*(robj**)s1)-setTypeSize(*(robj** qsortCompareSetsByRevCardinality( *s1, * robj *o1 = *(robj**)s1,*o2 = *(robj** (o2 ? setTypeSize(o2) : ) - (o1 ? setTypeSize(o1) : sinterGenericCommand(redisClient *c,unsigned setnum,robj * robj **sets = zmalloc((robj*)* setTypeIterator * robj *eleobj,*dstset = *replylen = unsigned j,cardinality = (j = ; j < setnum; j++ robj *setobj = dstkey ? lookupKeyWrite(c-> lookupKeyRead(c-> (! (dbDelete(c-> signalModifiedKey(c-> server.dirty++ } sets[j] = qsort(sets,setnum,(robj* (! replylen = } dstset = si = setTypeInitIterator(sets[ ((encoding = setTypeNext(si,&eleobj,&intobj)) != - (j = ; j < setnum; j++ (sets[j] == sets[]) (encoding == (sets[j]->encoding == REDIS_ENCODING_INTSET && !intsetFind((intset*)sets[j]-> } (sets[j]->encoding == eleobj = (! } (encoding == (eleobj->encoding == REDIS_ENCODING_INT && sets[j]->encoding == REDIS_ENCODING_INTSET && !intsetFind((intset*)sets[j]->ptr,()eleobj-> } (! (j == (! (encoding == cardinality++ } (encoding == eleobj = } deleted = dbDelete(c-> (setTypeSize(dstset) > dbAdd(c-> notifyKeyspaceEvent(REDIS_NOTIFY_SET, dstkey,c->db-> } notifyKeyspaceEvent(REDIS_NOTIFY_GENERIC, dstkey,c->db-> signalModifiedKey(c-> server.dirty++ } sinterCommand(redisClient * sinterGenericCommand(c,c->argc- sinterstoreCommand(redisClient * sinterGenericCommand(c,c->argv+,c->argc-,c->argv[ REDIS_OP_UNION 0 REDIS_OP_DIFF 1 REDIS_OP_INTER 2 sunionDiffGenericCommand(redisClient *c, robj **sets = zmalloc((robj*)* setTypeIterator * robj *ele,*dstset = j,cardinality = diff_algo = (j = ; j < setnum; j++ robj *setobj = dstkey ? lookupKeyWrite(c-> lookupKeyRead(c-> (! sets[j] = sets[j] = (op == REDIS_OP_DIFF && sets[ algo_one_work = ,algo_two_work = (j = ; j < setnum; j++ (sets[j] == NULL) algo_one_work += setTypeSize(sets[ algo_two_work += algo_one_work /= diff_algo = (algo_one_work <= algo_two_work) ? : (diff_algo == && setnum > qsort(sets+,setnum-, dstset = (op == (j = ; j < setnum; j++ (!sets[j]) ; si = ((ele = setTypeNextObject(si)) != (setTypeAdd(dstset,ele)) cardinality++ } (op == REDIS_OP_DIFF && sets[] && diff_algo == si = setTypeInitIterator(sets[ ((ele = setTypeNextObject(si)) != (j = ; j < setnum; j++ (!sets[j]) ; (sets[j] == sets[]) ; (setTypeIsMember(sets[j],ele)) (j == cardinality++ } (op == REDIS_OP_DIFF && sets[] && diff_algo == (j = ; j < setnum; j++ (!sets[j]) ; si = ((ele = setTypeNextObject(si)) != (j == (setTypeAdd(dstset,ele)) cardinality++ } (setTypeRemove(dstset,ele)) cardinality-- (cardinality == ) (! si = ((ele = setTypeNextObject(si)) != } deleted = dbDelete(c-> (setTypeSize(dstset) > dbAdd(c-> op == REDIS_OP_UNION ? : dstkey,c->db-> } notifyKeyspaceEvent(REDIS_NOTIFY_GENERIC, dstkey,c->db-> signalModifiedKey(c-> server.dirty++ sunionCommand(redisClient * sunionDiffGenericCommand(c,REDIS_OP_UNION); sunionstoreCommand(redisClient * sunionDiffGenericCommand(c,REDIS_OP_UNION); sdiffCommand(redisClient * sunionDiffGenericCommand(c,REDIS_OP_DIFF); sdiffstoreCommand(redisClient * sunionDiffGenericCommand(c,REDIS_OP_DIFF); sscanCommand(redisClient * robj * unsigned (parseScanCursorOrReply(c,&cursor) == REDIS_ERR) (( = lookupKeyReadOrReply(c,shared.emptyscan)) == NULL || checkType(c,REDIS_SET)) scanGenericCommand(c, }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读