设为首页 加入收藏

TOP

Redis数据类型与指令详解之集合(t_set)(三)
2014-11-24 07:45:28 来源: 作者: 【 】 浏览:10
Tags:Redis 数据 类型 指令 详解 集合 t_set
e the pointer to later modify it with the * right length */ if (!dstkey) { replylen = addDeferredMultiBulkLength(c); } else { /* If we have a target key where to store the resulting set * create this key with an empty set inside */ dstset = createIntsetObject(); } /* Iterate all the elements of the first (smallest) set, and test * the element against all the other sets, if at least one set does * not include the element it is discarded */ /** 求多个集合交集的算法思想: 首先按照集合元素个数对集合进行qsort,然后遍历排序后的第一个集合中的元素,查看该元素在 其他集合中是否存在,如果在其他集合中都存在,那么该元素为一个结果 */ si = setTypeInitIterator(sets[0]); while((encoding = setTypeNext(si,&eleobj,&intobj)) != -1) { for (j = 1; j < setnum; j++) { if (sets[j] == sets[0]) continue;//这段代码没意义啊 if (encoding == REDIS_ENCODING_INTSET) {//intset /* intset with intset is simple... and fast */ //集合sets[j]编码为intset if (sets[j]->encoding == REDIS_ENCODING_INTSET && !intsetFind((intset*)sets[j]->ptr,intobj))//在集合sets[j]中没有找到集合sets[0]的intobj { break; /* in order to compare an integer with an object we * have to use the generic function, creating an object * for this */ } else if (sets[j]->encoding == REDIS_ENCODING_HT) {//集合sets[j]编码为HT,sets[0]为INTSET eleobj = createStringObjectFromLongLong(intobj);//将sets[0]中的intobj转换为sds if (!setTypeIsMember(sets[j],eleobj)) {//如果eleobj不在集合sets[j]中 decrRefCount(eleobj); break; } decrRefCount(eleobj); } } else if (encoding == REDIS_ENCODING_HT) {//HT /* Optimization... if the source object is integer * encoded AND the target set is an intset, we can get * a much faster path. */ if (eleobj->encoding == REDIS_ENCODING_INT && sets[j]->encoding == REDIS_ENCODING_INTSET && !intsetFind((intset*)sets[j]->ptr,(long)eleobj->ptr)) { break; /* else... object to object check is easy as we use the * type agnostic API here. */ } else if (!setTypeIsMember(sets[j],eleobj)) { break; } } } /* Only take action when all sets contain the member */ if (j == setnum) { if (!dstkey) { if (encoding == REDIS_ENCODING_HT) addReplyBulk(c,eleobj); else addReplyBulkLongLong(c,intobj); cardinality++; } else {//添加到临时目标集合 if (encoding == REDIS_ENCODING_INTSET) { eleobj = createStringObjectFromLongLong(intobj); setTypeAdd(dstset,eleobj); decrRefCount(eleobj); } else { setTypeAdd(dstset,eleobj); } } } } setTypeReleaseIterator(si); if (dstkey) { /* Store the resulting set into the target, if the intersection * is not an empty set. */ int deleted = dbDelete(c->db,dstkey);//覆盖原来的目标集合 if (setTypeSize(dstset) > 0) { dbAdd(c->db,dstkey,dstset); addReplyLongLong(c,setTypeSize(dstset)); notifyKeyspaceEvent(REDIS_NOTIFY_SET,"sinterstore", dstkey,c->db->id); } else {//空集 decrRefCount(dstset); addReply(c,shared.czero); if (deleted) notifyKeyspaceEvent(REDIS_NOTIFY_GENERIC,"del", dstkey,c->db->id); } signalModifiedKey(c->db,dstkey); server.dirty++; } else { setDeferredMultiBulkLength(c,replylen,cardinality); } zfree(sets); } /*SINTER key [key...]*/ void sinterCommand(redisClient *c) {//计算所有给定集合的交集 sinterGenericCommand(c,c->argv+1,c->argc-1,NULL); } /*SINTER destination key [key...]*/ void sinterstoreCommand(redisClient *c) {//计算所有给定集合的交集,但存储在集合destination中 sinterGenericCommand(c,c->argv+2,c->argc-2,c->argv[1]); }

集合求差算法

集合求差有两个指令:SDIFF与SDIFFSTORE

SDIFF key [key ...]
返回所有给定集合之间的差集,不存在的集合key视为空集。
时间复杂度: O(N),N 是所有给定集合的成员数量之和。
SDIFFSTORE destination key [key ...]
与SDIFF 类似,但它将差集的结果保存到集合destina

首页 上一页 1 2 3 4 下一页 尾页 3/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇数据挖掘之企业危机管理 下一篇数据挖掘之朴素贝叶斯算法

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·TCP/UDP协议_百度百科 (2025-12-26 12:20:11)
·什么是TCP和UDP协议 (2025-12-26 12:20:09)
·TCP和UDP详解 (非常 (2025-12-26 12:20:06)
·Python 教程 - W3Sch (2025-12-26 12:00:51)
·Python基础教程,Pyt (2025-12-26 12:00:48)