本文整理汇总了C++中dbDelete函数的典型用法代码示例。如果您正苦于以下问题:C++ dbDelete函数的具体用法?C++ dbDelete怎么用?C++ dbDelete使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了dbDelete函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。
示例1: spopCommand
void spopCommand(redisClient *c) {
robj *set, *ele;
int64_t llele;
int encoding;
if ((set = lookupKeyWriteOrReply(c,c->argv[1],shared.nullbulk)) == NULL ||
checkType(c,set,REDIS_SET)) return;
encoding = setTypeRandomElement(set,&ele,&llele);
if (encoding == REDIS_ENCODING_INTSET) {
addReplyBulkLongLong(c,llele);
set->ptr = intsetRemove(set->ptr,llele,NULL);
} else {
addReplyBulk(c,ele);
setTypeRemove(set,ele);
}
if (setTypeSize(set) == 0) dbDelete(c->db,c->argv[1]);
touchWatchedKey(c->db,c->argv[1]);
server.dirty++;
}
开发者ID:jrun,项目名称:redis,代码行数:20,代码来源:t_set.c
示例2: expireGenericCommand
void expireGenericCommand(redisClient *c, robj *key, robj *param, long offset) {
dictEntry *de;
long seconds;
if (getLongFromObjectOrReply(c, param, &seconds, NULL) != REDIS_OK) return;
seconds -= offset;
de = dictFind(c->db->dict,key->ptr);
if (de == NULL) {
addReply(c,shared.czero);
return;
}
/* EXPIRE with negative TTL, or EXPIREAT with a timestamp into the past
* should never be executed as a DEL when load the AOF or in the context
* of a slave instance.
*
* Instead we take the other branch of the IF statement setting an expire
* (possibly in the past) and wait for an explicit DEL from the master. */
if (seconds <= 0 && !server.loading && !server.masterhost) {
robj *aux;
redisAssert(dbDelete(c->db,key));
server.dirty++;
/* Replicate/AOF this as an explicit DEL. */
aux = createStringObject("DEL",3);
rewriteClientCommandVector(c,2,aux,key);
decrRefCount(aux);
touchWatchedKey(c->db,key);
addReply(c, shared.cone);
return;
} else {
time_t when = time(NULL)+seconds;
setExpire(c->db,key,when);
addReply(c,shared.cone);
touchWatchedKey(c->db,key);
server.dirty++;
return;
}
}
开发者ID:Elbandi,项目名称:redis,代码行数:41,代码来源:db.c
示例3: moveCommand
void moveCommand(redisClient *c) {
robj *o;
redisDb *src, *dst;
int srcid;
/* Obtain source and target DB pointers */
src = c->db;
srcid = c->db->id;
if (selectDb(c,atoi(c->argv[2]->ptr)) == REDIS_ERR) {
addReply(c,shared.outofrangeerr);
return;
}
dst = c->db;
selectDb(c,srcid); /* Back to the source DB */
/* If the user is moving using as target the same
* DB as the source DB it is probably an error. */
if (src == dst) {
addReply(c,shared.sameobjecterr);
return;
}
/* Check if the element exists and get a reference */
o = lookupKeyWrite(c->db,c->argv[1]);
if (!o) {
addReply(c,shared.czero);
return;
}
/* Try to add the element to the target DB */
if (dbAdd(dst,c->argv[1],o) == REDIS_ERR) {
addReply(c,shared.czero);
return;
}
incrRefCount(o);
/* OK! key moved, free the entry in the source DB */
dbDelete(src,c->argv[1]);
server.dirty++;
addReply(c,shared.cone);
}
开发者ID:andmej,项目名称:redis,代码行数:41,代码来源:db.c
示例4: zremrangebyscoreCommand
void zremrangebyscoreCommand(redisClient *c) {
double min;
double max;
long deleted;
robj *zsetobj;
zset *zs;
if ((getDoubleFromObjectOrReply(c, c->argv[2], &min, NULL) != REDIS_OK) ||
(getDoubleFromObjectOrReply(c, c->argv[3], &max, NULL) != REDIS_OK)) return;
if ((zsetobj = lookupKeyWriteOrReply(c,c->argv[1],shared.czero)) == NULL ||
checkType(c,zsetobj,REDIS_ZSET)) return;
zs = zsetobj->ptr;
deleted = zslDeleteRangeByScore(zs->zsl,min,max,zs->dict);
if (htNeedsResize(zs->dict)) dictResize(zs->dict);
if (dictSize(zs->dict) == 0) dbDelete(c->db,c->argv[1]);
if (deleted) touchWatchedKey(c->db,c->argv[1]);
server.dirty += deleted;
addReplyLongLong(c,deleted);
}
开发者ID:aditya,项目名称:redis,代码行数:21,代码来源:t_zset.c
示例5: lremCommand
void lremCommand(redisClient *c) {
robj *subject, *obj;
obj = c->argv[3] = tryObjectEncoding(c->argv[3]);
int toremove = atoi(c->argv[2]->ptr);
int removed = 0;
listTypeEntry entry;
subject = lookupKeyWriteOrReply(c,c->argv[1],shared.czero);
if (subject == NULL || checkType(c,subject,REDIS_LIST)) return;
/* Make sure obj is raw when we're dealing with a ziplist */
if (subject->encoding == REDIS_ENCODING_ZIPLIST)
obj = getDecodedObject(obj);
listTypeIterator *li;
if (toremove < 0) {
toremove = -toremove;
li = listTypeInitIterator(subject,-1,REDIS_HEAD);
} else {
li = listTypeInitIterator(subject,0,REDIS_TAIL);
}
while (listTypeNext(li,&entry)) {
if (listTypeEqual(&entry,obj)) {
listTypeDelete(&entry);
server.dirty++;
removed++;
if (toremove && removed == toremove) break;
}
}
listTypeReleaseIterator(li);
/* Clean up raw encoded object */
if (subject->encoding == REDIS_ENCODING_ZIPLIST)
decrRefCount(obj);
if (listTypeLength(subject) == 0) dbDelete(c->db,c->argv[1]);
addReplyLongLong(c,removed);
if (removed) signalModifiedKey(c->db,c->argv[1]);
}
开发者ID:brunobnb,项目名称:brtGHost,代码行数:40,代码来源:t_list.c
示例6: popGenericCommand
void popGenericCommand(redisClient *c, int where) {
robj *o = lookupKeyWriteOrReply(c,c->argv[1],shared.nullbulk);
if (o == NULL || checkType(c,o,REDIS_LIST)) return;
robj *value = listTypePop(o,where);
if (value == NULL) {
addReply(c,shared.nullbulk);
} else {
char *event = (where == REDIS_HEAD) ? "lpop" : "rpop";
addReplyBulk(c,value);
decrRefCount(value);
notifyKeyspaceEvent(REDIS_NOTIFY_LIST,event,c->argv[1],c->db->id);
if (listTypeLength(o) == 0) {
notifyKeyspaceEvent(REDIS_NOTIFY_GENERIC,"del",
c->argv[1],c->db->id);
dbDelete(c->db,c->argv[1]);
}
signalModifiedKey(c->db,c->argv[1]);
server.dirty++;
}
}
开发者ID:wangxuemin,项目名称:coding,代码行数:22,代码来源:t_list.c
示例7: rpoplpushCommand
void rpoplpushCommand(redisClient *c) {
robj *sobj, *value;
if ((sobj = lookupKeyWriteOrReply(c,c->argv[1],shared.nullbulk)) == NULL ||
checkType(c,sobj,REDIS_LIST)) return;
if (listTypeLength(sobj) == 0) {
addReply(c,shared.nullbulk);
} else {
robj *dobj = lookupKeyWrite(c->db,c->argv[2]);
if (dobj && checkType(c,dobj,REDIS_LIST)) return;
value = listTypePop(sobj,REDIS_TAIL);
rpoplpushHandlePush(c,c->argv[2],dobj,value);
/* listTypePop returns an object with its refcount incremented */
decrRefCount(value);
/* Delete the source list when it is empty */
if (listTypeLength(sobj) == 0) dbDelete(c->db,c->argv[1]);
touchWatchedKey(c->db,c->argv[1]);
server.dirty++;
}
}
开发者ID:GeorgeJahad,项目名称:redis,代码行数:22,代码来源:t_list.c
示例8: sremCommand
void sremCommand(redisClient *c) {
robj *set;
int j, deleted = 0;
if ((set = lookupKeyWriteOrReply(c,c->argv[1],shared.czero)) == NULL ||
checkType(c,set,REDIS_SET)) return;
for (j = 2; j < c->argc; j++) {
if (setTypeRemove(set,c->argv[j])) {
deleted++;
if (setTypeSize(set) == 0) {
dbDelete(c->db,c->argv[1]);
break;
}
}
}
if (deleted) {
signalModifiedKey(c->db,c->argv[1]);
server.dirty += deleted;
}
addReplyLongLong(c,deleted);
}
开发者ID:edolphin-ydf,项目名称:hydzhengtu,代码行数:22,代码来源:t_set.c
示例9: expireIfNeeded
int expireIfNeeded(redisDb *db, robj *key) {
mstime_t when = getExpire(db,key);//微秒
mstime_t now;
if (when < 0) return 0; /* No expire for this key */
/* Don't expire anything while loading. It will be done later. */
if (server.loading) return 0;
/* If we are in the context of a Lua script, we claim that time is
* blocked to when the Lua script started. This way a key can expire
* only the first time it is accessed and not in the middle of the
* script execution, making propagation to slaves / AOF consistent.
* See issue #1525 on Github for more information. */
now = server.lua_caller ? server.lua_time_start : mstime();
/* If we are running in the context of a slave, return ASAP:
* the slave key expiration is controlled by the master that will
* send us synthesized DEL operations for expired keys.
*
* Still we try to return the right information to the caller,
* that is, 0 if we think the key should be still valid, 1 if
* we think the key is expired at this time. */
if (server.masterhost != NULL) return now > when;
/* Return when this key has not expired */
if (now <= when) return 0;
/* Delete the key */
server.stat_expiredkeys++;
propagateExpire(db,key);
//事件函数的处理
notifyKeyspaceEvent(REDIS_NOTIFY_EXPIRED,
"expired",key,db->id);
//删除该键
return dbDelete(db,key);
}
开发者ID:hylaz,项目名称:redis,代码行数:38,代码来源:db.c
示例10: rpoplpushCommand
void rpoplpushCommand(redisClient *c) {
robj *sobj, *value;
int slotnum1 = keyHashSlot(c->argv[1]->ptr, sdslen(c->argv[1]->ptr));
int slotnum2 = keyHashSlot(c->argv[2]->ptr, sdslen(c->argv[2]->ptr));
if ((sobj = lookupKeyWriteOrReply(c,c->argv[1],shared.nullbulk,slotnum1)) == NULL ||
checkType(c,sobj,REDIS_LIST)) return;
if (listTypeLength(sobj) == 0) {
/* This may only happen after loading very old RDB files. Recent
* versions of Redis delete keys of empty lists. */
addReply(c,shared.nullbulk);
} else {
robj *dobj = lookupKeyWrite(c->db,c->argv[2],slotnum2);
robj *touchedkey = c->argv[1];
if (dobj && checkType(c,dobj,REDIS_LIST)) return;
value = listTypePop(sobj,REDIS_TAIL);
/* We saved touched key, and protect it, since rpoplpushHandlePush
* may change the client command argument vector (it does not
* currently). */
incrRefCount(touchedkey);
rpoplpushHandlePush(c,c->argv[2],dobj,value,slotnum2);
/* listTypePop returns an object with its refcount incremented */
decrRefCount(value);
/* Delete the source list when it is empty */
notifyKeyspaceEvent(REDIS_NOTIFY_LIST,"rpop",touchedkey,c->db->id);
if (listTypeLength(sobj) == 0) {
dbDelete(c->db,touchedkey,slotnum1);
notifyKeyspaceEvent(REDIS_NOTIFY_GENERIC,"del",
touchedkey,c->db->id);
}
signalModifiedKey(c->db,touchedkey,slotnum1);
decrRefCount(touchedkey);
server.dirty++;
}
}
开发者ID:frostyplanet,项目名称:jimdb,代码行数:38,代码来源:t_list.c
示例11: zremrangebyrankCommand
void zremrangebyrankCommand(redisClient *c) {
long start;
long end;
int llen;
long deleted;
robj *zsetobj;
zset *zs;
if ((getLongFromObjectOrReply(c, c->argv[2], &start, NULL) != REDIS_OK) ||
(getLongFromObjectOrReply(c, c->argv[3], &end, NULL) != REDIS_OK)) return;
if ((zsetobj = lookupKeyWriteOrReply(c,c->argv[1],shared.czero)) == NULL ||
checkType(c,zsetobj,REDIS_ZSET)) return;
zs = zsetobj->ptr;
llen = zs->zsl->length;
/* convert negative indexes */
if (start < 0) start = llen+start;
if (end < 0) end = llen+end;
if (start < 0) start = 0;
/* Invariant: start >= 0, so this test will be true when end < 0.
* The range is empty when start > end or start >= length. */
if (start > end || start >= llen) {
addReply(c,shared.czero);
return;
}
if (end >= llen) end = llen-1;
/* increment start and end because zsl*Rank functions
* use 1-based rank */
deleted = zslDeleteRangeByRank(zs->zsl,start+1,end+1,zs->dict);
if (htNeedsResize(zs->dict)) dictResize(zs->dict);
if (dictSize(zs->dict) == 0) dbDelete(c->db,c->argv[1]);
if (deleted) touchWatchedKey(c->db,c->argv[1]);
server.dirty += deleted;
addReplyLongLong(c, deleted);
}
开发者ID:JakSprats,项目名称:Alchemy-Database,代码行数:38,代码来源:t_zset.c
示例12: zremrangebyscoreCommand
void zremrangebyscoreCommand(redisClient *c) {
zrangespec range;
long deleted;
robj *o;
zset *zs;
/* Parse the range arguments. */
if (zslParseRange(c->argv[2],c->argv[3],&range) != REDIS_OK) {
addReplyError(c,"min or max is not a double");
return;
}
if ((o = lookupKeyWriteOrReply(c,c->argv[1],shared.czero)) == NULL ||
checkType(c,o,REDIS_ZSET)) return;
zs = o->ptr;
deleted = zslDeleteRangeByScore(zs->zsl,range,zs->dict);
if (htNeedsResize(zs->dict)) dictResize(zs->dict);
if (dictSize(zs->dict) == 0) dbDelete(c->db,c->argv[1]);
if (deleted) touchWatchedKey(c->db,c->argv[1]);
server.dirty += deleted;
addReplyLongLong(c,deleted);
}
开发者ID:JakSprats,项目名称:Alchemy-Database,代码行数:23,代码来源:t_zset.c
示例13: rpoplpushCommand
void rpoplpushCommand(redisClient *c) {
robj *sobj, *value;
if ((sobj = lookupKeyWriteOrReply(c,c->argv[1],shared.nullbulk)) == NULL ||
checkType(c,sobj,REDIS_LIST)) return;
if (listTypeLength(sobj) == 0) {
/* This may only happen after loading very old RDB files. Recent
* versions of Redis delete keys of empty lists. */
addReply(c,shared.nullbulk);
} else {
robj *dobj = lookupKeyWrite(c->db,c->argv[2]);
robj *touchedkey = c->argv[1];
if (dobj && checkType(c,dobj,REDIS_LIST)) return;
value = listTypePop(sobj,REDIS_TAIL);
/* We saved touched key, and protect it, since rpoplpushHandlePush
* may change the client command argument vector. */
incrRefCount(touchedkey);
rpoplpushHandlePush(c,c,c->argv[2],dobj,value);
/* listTypePop returns an object with its refcount incremented */
decrRefCount(value);
/* Delete the source list when it is empty */
if (listTypeLength(sobj) == 0) dbDelete(c->db,touchedkey);
signalModifiedKey(c->db,touchedkey);
decrRefCount(touchedkey);
server.dirty++;
/* Replicate this as a simple RPOP since the LPUSH side is replicated
* by rpoplpushHandlePush() call if needed (it may not be needed
* if a client is blocking wait a push against the list). */
rewriteClientCommandVector(c,2,
resetRefCount(createStringObject("RPOP",4)),
c->argv[1]);
}
}
开发者ID:CNCBASHER,项目名称:linuxcnc-1,代码行数:37,代码来源:t_list.c
示例14: expireIfNeeded
int expireIfNeeded(redisDb *db, robj *key) {
time_t when = getExpire(db,key);
if (when < 0) return 0; /* No expire for this key */
/* If we are running in the context of a slave, return ASAP:
* the slave key expiration is controlled by the master that will
* send us synthesized DEL operations for expired keys.
*
* Still we try to return the right information to the caller,
* that is, 0 if we think the key should be still valid, 1 if
* we think the key is expired at this time. */
if (server.masterhost != NULL) {
return time(NULL) > when;
}
/* Return when this key has not expired */
if (time(NULL) <= when) return 0;
/* Delete the key */
server.stat_expiredkeys++;
propagateExpire(db,key);
return dbDelete(db,key);
}
开发者ID:andmej,项目名称:redis,代码行数:24,代码来源:db.c
示例15: delCommand
void delCommand(redisClient *c) {
int deleted = 0, j;
for (j = 1; j < c->argc; j++) {
if (server.ds_enabled) {
lookupKeyRead(c->db,c->argv[j]);
/* FIXME: this can be optimized a lot, no real need to load
* a possibly huge value. */
}
if (dbDelete(c->db,c->argv[j])) {
signalModifiedKey(c->db,c->argv[j]);
server.dirty++;
deleted++;
} else if (server.ds_enabled) {
if (cacheKeyMayExist(c->db,c->argv[j]) &&
dsExists(c->db,c->argv[j]))
{
cacheScheduleIO(c->db,c->argv[j],REDIS_IO_SAVE);
deleted = 1;
}
}
}
addReplyLongLong(c,deleted);
}
开发者ID:andmej,项目名称:redis,代码行数:24,代码来源:db.c
示例16: zunionInterGenericCommand
//.........这里部分代码省略.........
} else {
zfree(src);
addReply(c,shared.syntaxerr);
return;
}
}
}
/* sort sets from the smallest to largest, this will improve our
* algorithm's performance */
qsort(src,setnum,sizeof(zsetopsrc),qsortCompareZsetopsrcByCardinality);
dstobj = createZsetObject();
dstzset = dstobj->ptr;
if (op == REDIS_OP_INTER) {
/* skip going over all entries if the smallest zset is NULL or empty */
if (src[0].dict && dictSize(src[0].dict) > 0) {
/* precondition: as src[0].dict is non-empty and the zsets are ordered
* from small to large, all src[i > 0].dict are non-empty too */
di = dictGetIterator(src[0].dict);
while((de = dictNext(di)) != NULL) {
double score, value;
score = src[0].weight * zunionInterDictValue(de);
for (j = 1; j < setnum; j++) {
dictEntry *other = dictFind(src[j].dict,dictGetEntryKey(de));
if (other) {
value = src[j].weight * zunionInterDictValue(other);
zunionInterAggregate(&score,value,aggregate);
} else {
break;
}
}
/* Only continue when present in every source dict. */
if (j == setnum) {
robj *o = dictGetEntryKey(de);
znode = zslInsert(dstzset->zsl,score,o);
incrRefCount(o); /* added to skiplist */
dictAdd(dstzset->dict,o,&znode->score);
incrRefCount(o); /* added to dictionary */
}
}
dictReleaseIterator(di);
}
} else if (op == REDIS_OP_UNION) {
for (i = 0; i < setnum; i++) {
if (!src[i].dict) continue;
di = dictGetIterator(src[i].dict);
while((de = dictNext(di)) != NULL) {
double score, value;
/* skip key when already processed */
if (dictFind(dstzset->dict,dictGetEntryKey(de)) != NULL)
continue;
/* initialize score */
score = src[i].weight * zunionInterDictValue(de);
/* because the zsets are sorted by size, its only possible
* for sets at larger indices to hold this entry */
for (j = (i+1); j < setnum; j++) {
dictEntry *other = dictFind(src[j].dict,dictGetEntryKey(de));
if (other) {
value = src[j].weight * zunionInterDictValue(other);
zunionInterAggregate(&score,value,aggregate);
}
}
robj *o = dictGetEntryKey(de);
znode = zslInsert(dstzset->zsl,score,o);
incrRefCount(o); /* added to skiplist */
dictAdd(dstzset->dict,o,&znode->score);
incrRefCount(o); /* added to dictionary */
}
dictReleaseIterator(di);
}
} else {
/* unknown operator */
redisAssert(op == REDIS_OP_INTER || op == REDIS_OP_UNION);
}
if (dbDelete(c->db,dstkey)) {
touchWatchedKey(c->db,dstkey);
touched = 1;
server.dirty++;
}
if (dstzset->zsl->length) {
dbAdd(c->db,dstkey,dstobj);
addReplyLongLong(c, dstzset->zsl->length);
if (!touched) touchWatchedKey(c->db,dstkey);
server.dirty++;
} else {
decrRefCount(dstobj);
addReply(c, shared.czero);
}
zfree(src);
}
开发者ID:JakSprats,项目名称:Alchemy-Database,代码行数:101,代码来源:t_zset.c
示例17: handleClientsBlockedOnLists
//函数会在redis每次执行完单个命令,事务块或lua脚本之后被调用
//对于所有被阻塞在client的key来说,只要key被执行了PUSH,那么这个key会被加入到server.ready_keys中
//处理client的阻塞状态
void handleClientsBlockedOnLists(void) {
//只要server.ready_keys还有要解除阻塞的key,就循环遍历server.ready_keys链表
while(listLength(server.ready_keys) != 0) {
list *l;
/* Point server.ready_keys to a fresh list and save the current one
* locally. This way as we run the old list we are free to call
* signalListAsReady() that may push new elements in server.ready_keys
* when handling clients blocked into BRPOPLPUSH. */
//备份一个server.ready_keys链表
l = server.ready_keys;
//生成一个新的空链表
server.ready_keys = listCreate();
//只要链表中还有就绪的key
while(listLength(l) != 0) {
listNode *ln = listFirst(l); //链表头结点地址
readyList *rl = ln->value; //保存链表节点的值,每个值都是readyList结构
/* First of all remove this key from db->ready_keys so that
* we can safely call signalListAsReady() against this key. */
//从rl->db->ready_keys中删除就绪的key
dictDelete(rl->db->ready_keys,rl->key);
/* If the key exists and it's a list, serve blocked clients
* with data. */
//以读操作将就绪key的值读出来
robj *o = lookupKeyWrite(rl->db,rl->key);
//读出的value对象必须是列表类型
if (o != NULL && o->type == OBJ_LIST) {
dictEntry *de;
/* We serve clients in the same order they blocked for
* this key, from the first blocked to the last. */
// blocking_keys是一个字典,字典的键是造成client阻塞的键,字典的值是链表,保存被阻塞的client
// 根据key取出被阻塞的client
de = dictFind(rl->db->blocking_keys,rl->key);
// 链表非空
if (de) {
// 获取de节点的值
list *clients = dictGetVal(de);
// 获取链表的长度
int numclients = listLength(clients);
//遍历链表的所有节点
while(numclients--) {
// 第一个client节点地址
listNode *clientnode = listFirst(clients);
// 取出节点的值,是一个client类型
client *receiver = clientnode->value;
// 从client类型中的target获得要PUSH出的dstkey,该键保存在target中
robj *dstkey = receiver->bpop.target;
// 获取弹出的位置,根据BRPOPLPUSH命令
int where = (receiver->lastcmd &&
receiver->lastcmd->proc == blpopCommand) ?
LIST_HEAD : LIST_TAIL;
// 从列表中弹出元素
robj *value = listTypePop(o,where);
// 弹出成功
if (value) {
/* Protect receiver->bpop.target, that will be
* freed by the next unblockClient()
* call. */
//增加dstkey的引用计数,保护该键,在unblockClient函数中释放
if (dstkey) incrRefCount(dstkey);
//取消client的阻塞状态
unblockClient(receiver);
// 将value推入造成client阻塞的键上,
if (serveClientBlockedOnList(receiver,
rl->key,dstkey,rl->db,value,
where) == C_ERR)
{
/* If we failed serving the client we need
* to also undo the POP operation. */
// 如果推入失败,则需要键弹出的value还原回去
listTypePush(o,value,where);
}
// 释放dstkey和value
if (dstkey) decrRefCount(dstkey);
decrRefCount(value);
} else {
break;
}
}
}
// 如果弹出了所有元素,将key从数据库中删除
if (listTypeLength(o) == 0) {
dbDelete(rl->db,rl->key);
}
/* We don't call signalModifiedKey() as it was already called
* when an element was pushed on the list. */
}
/* Free this item. */
//.........这里部分代码省略.........
开发者ID:therenine,项目名称:redis_source_annotation,代码行数:101,代码来源:t_list.c
示例18: blockingPopGenericCommand
// BRPOP BLPOP 命令的底层实现
// BLPOP key [key ...] timeout
void blockingPopGenericCommand(client *c, int where) {
robj *o;
mstime_t timeout;
int j;
// 以秒为单位取出timeout值
if (getTimeoutFromObjectOrReply(c,c->argv[c->argc-1],&timeout,UNIT_SECONDS)
!= C_OK) return;
//遍历所有的key
for (j = 1; j < c->argc-1; j++) {
//以写操作取出当前key的值
o = lookupKeyWrite(c->db,c->argv[j]);
// value对象不为空
if (o != NULL) {
// 如果value对象的类型不是列表类型,发送类型错误信息
if (o->type != OBJ_LIST) {
addReply(c,shared.wrongtypeerr);
return;
} else {
// 列表长度不为0
if (listTypeLength(o) != 0) {
/* Non empty list, this is like a non normal [LR]POP. */
// 保存事件名称
char *event = (where == LIST_HEAD) ? "lpop" : "rpop";
// 保存弹出的value对象
robj *value = listTypePop(o,where);
serverAssert(value != NULL);
// 发送回复给client
addReplyMultiBulkLen(c,2);
addReplyBulk(c,c->argv[j]);
addReplyBulk(c,value);
// 释放value
decrRefCount(value);
// 发送事件通知
notifyKeyspaceEvent(NOTIFY_LIST,event,
c->argv[j],c->db->id);
//如果弹出元素后列表为空
if (listTypeLength(o) == 0) {
//从数据库中删除当前的key
dbDelete(c->db,c->argv[j]);
// 发送"del"的事件通知
notifyKeyspaceEvent(NOTIFY_GENERIC,"del",
c->argv[j],c->db->id);
}
//数据库的键被修改,发送信号
signalModifiedKey(c->db,c->argv[j]);
//更新脏键
server.dirty++;
/* Replicate it as an [LR]POP instead of B[LR]POP. */
// 传播一个[LR]POP 而不是B[LR]POP
rewriteClientCommandVector(c,2,
(where == LIST_HEAD) ? shared.lpop : shared.rpop,
c->argv[j]);
return;
}
}
}
}
/* If we are inside a MULTI/EXEC and the list is empty the only thing
* we can do is treating it as a timeout (even with timeout 0). */
// 如果命令在一个事务中执行,则发送一个空回复以避免死等待
if (c->flags & CLIENT_MULTI) {
addReply(c,shared.nullmultibulk);
return;
}
/* If the list is empty or the key does not exists we must block */
// 参数中的所有键都不存在,则阻塞这些键
blockForKeys(c, c->argv + 1, c->argc - 2, timeout, NULL);
}
开发者ID:therenine,项目名称:redis_source_annotation,代码行数:76,代码来源:t_list.c
示例19: sunionDiffGenericCommand
void sunionDiffGenericCommand(redisClient *c, robj **setkeys, int setnum, robj *dstkey, int op) {
robj **sets = zmalloc(sizeof(robj*)*setnum);
setTypeIterator *si;
robj *ele, *dstset = NULL;
int j, cardinality = 0;
for (j = 0; j < setnum; j++) {
robj *setobj = dstkey ?
lookupKeyWrite(c->db,setkeys[j]) :
lookupKeyRead(c->db,setkeys[j]);
if (!setobj) {
sets[j] = NULL;
continue;
}
if (checkType(c,setobj,REDIS_SET)) {
zfree(sets);
return;
}
sets[j] = setobj;
}
/* We need a temp set object to store our union. If the dstkey
* is not NULL (that is, we are inside an SUNIONSTORE operation) then
* this set object will be the resulting object to set into the target key*/
dstset = createIntsetObject();
/* Iterate all the elements of all the sets, add every element a single
* time to the result set */
for (j = 0; j < setnum; j++) {
if (op == REDIS_OP_DIFF && j == 0 && !sets[j]) break; /* result set is empty */
if (!sets[j]) continue; /* non existing keys are like empty sets */
si = setTypeInitIterator(sets[j]);
while((ele = setTypeNextObject(si)) != NULL) {
if (op == REDIS_OP_UNION || j == 0) {
if (setTypeAdd(dstset,ele)) {
cardinality++;
}
} else if (op == REDIS_OP_DIFF) {
if (setTypeRemove(dstset,ele)) {
cardinality--;
}
}
decrRefCount(ele);
}
setTypeReleaseIterator(si);
/* Exit when result set is empty. */
if (op == REDIS_OP_DIFF && cardinality == 0) break;
}
/* Output the content of the resulting set, if not in STORE mode */
if (!dstkey) {
addReplyMultiBulkLen(c,cardinality);
si = setTypeInitIterator(dstset);
while((ele = setTypeNextObject(si)) != NULL) {
addReplyBulk(c,ele);
decrRefCount(ele);
}
setTypeReleaseIterator(si);
decrRefCount(dstset);
} else {
/* If we have a target key where to store the resulting set
* create this key with the result set inside */
dbDelete(c->db,dstkey);
if (setTypeSize(dstset) > 0) {
dbAdd(c->db,dstkey,dstset);
addReplyLongLong(c,setTypeSize(dstset));
} else {
decrRefCount(dstset);
addReply(c,shared.czero);
}
touchWatchedKey(c->db,dstkey);
server.dirty++;
}
zfree(sets);
}
开发者ID:jrun,项目名称:redis,代码行数:77,代码来源:t_set.c
示例20: sinterGenericCommand
void sinterGenericCommand(redisClient *c, robj **setkeys, unsigned long setnum, robj *dstkey) {
robj **sets = zmalloc(sizeof(robj*)*setnum);
setTypeIterator *si;
robj *eleobj, *dstset = NULL;
int64_t intobj;
void *replylen = NULL;
unsigned long j, cardinality = 0;
int encoding;
for (j = 0; j < setnum; j++) {
robj *setobj = dstkey ?
lookupKeyWrite(c->db,setkeys[j]) :
lookupKeyRead(c->db,setkeys[j]);
if (!setobj) {
zfree(sets);
if (dstkey) {
if (dbDelete(c->db,dstkey)) {
touchWatchedKey(c->db,dstkey);
server.dirty++;
}
addReply(c,shared.czero);
} else {
addReply(c,shared.emptymultibulk);
}
return;
}
if (checkType(c,setobj,REDIS_SET)) {
zfree(sets);
return;
}
sets[j] = setobj;
}
/* Sort sets from the smallest to largest, this will improve our
* algorithm's performace */
qsort(sets,setnum,sizeof(robj*),qsortCompareSetsByCardinality);
/* The first thing we should output is the total number of elements...
* since this is a multi-bulk write, but at this stage we don't know
* the intersection set size, so we use a trick, append an empty object
* to the output list and save 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 */
si = setTypeInitIterator(sets[0]);
while((encoding = setTypeNext(si,&eleobj,&intobj)) != -1) {
for (j = 1; j < setnum; j++) {
if (encoding == REDIS_ENCODING_INTSET) {
/* intset with intset is simple... and fast */
if (sets[j]->encoding == REDIS_ENCODING_INTSET &&
!intsetFind((intset*)sets[j]->ptr,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) {
eleobj = createStringObjectFromLongLong(intobj);
if (!setTypeIsMember(sets[j],eleobj)) {
decrRefCount(eleobj);
break;
}
decrRefCount(eleobj);
}
} else if (encoding == REDIS_ENCODING_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);
//.........这里部分代码省略.........
开发者ID:jrun,项目名称:redis,代码行数:101,代码来源:t_set.c
注:本文中的dbDelete函数示例由纯净天空整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论