/* The set *was* an intset and this value is not integer
* encodable, so dictAdd should always work. */
- redisAssert(dictAdd(subject->ptr,value,NULL) == DICT_OK);
+ redisAssertWithInfo(NULL,value,dictAdd(subject->ptr,value,NULL) == DICT_OK);
incrRefCount(value);
return 1;
}
if (si->encoding == REDIS_ENCODING_HT) {
dictEntry *de = dictNext(si->di);
if (de == NULL) return -1;
- *objele = dictGetEntryKey(de);
+ *objele = dictGetKey(de);
} else if (si->encoding == REDIS_ENCODING_INTSET) {
if (!intsetGet(si->subject->ptr,si->ii++,llele))
return -1;
int setTypeRandomElement(robj *setobj, robj **objele, int64_t *llele) {
if (setobj->encoding == REDIS_ENCODING_HT) {
dictEntry *de = dictGetRandomKey(setobj->ptr);
- *objele = dictGetEntryKey(de);
+ *objele = dictGetKey(de);
} else if (setobj->encoding == REDIS_ENCODING_INTSET) {
*llele = intsetRandom(setobj->ptr);
} else {
* set. */
void setTypeConvert(robj *setobj, int enc) {
setTypeIterator *si;
- redisAssert(setobj->type == REDIS_SET &&
- setobj->encoding == REDIS_ENCODING_INTSET);
+ redisAssertWithInfo(NULL,setobj,setobj->type == REDIS_SET &&
+ setobj->encoding == REDIS_ENCODING_INTSET);
if (enc == REDIS_ENCODING_HT) {
int64_t intele;
si = setTypeInitIterator(setobj);
while (setTypeNext(si,NULL,&intele) != -1) {
element = createStringObjectFromLongLong(intele);
- redisAssert(dictAdd(d,element,NULL) == DICT_OK);
+ redisAssertWithInfo(NULL,element,dictAdd(d,element,NULL) == DICT_OK);
}
setTypeReleaseIterator(si);
void saddCommand(redisClient *c) {
robj *set;
+ int j, added = 0;
set = lookupKeyWrite(c->db,c->argv[1]);
- c->argv[2] = tryObjectEncoding(c->argv[2]);
if (set == NULL) {
set = setTypeCreate(c->argv[2]);
dbAdd(c->db,c->argv[1],set);
return;
}
}
- if (setTypeAdd(set,c->argv[2])) {
- signalModifiedKey(c->db,c->argv[1]);
- server.dirty++;
- addReply(c,shared.cone);
- } else {
- addReply(c,shared.czero);
+
+ for (j = 2; j < c->argc; j++) {
+ c->argv[j] = tryObjectEncoding(c->argv[j]);
+ if (setTypeAdd(set,c->argv[j])) added++;
}
+ if (added) signalModifiedKey(c->db,c->argv[1]);
+ server.dirty += added;
+ addReplyLongLong(c,added);
}
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;
- c->argv[2] = tryObjectEncoding(c->argv[2]);
- if (setTypeRemove(set,c->argv[2])) {
- if (setTypeSize(set) == 0) dbDelete(c->db,c->argv[1]);
+ 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++;
- addReply(c,shared.cone);
- } else {
- addReply(c,shared.czero);
+ server.dirty += deleted;
}
+ addReplyLongLong(c,deleted);
}
void smoveCommand(redisClient *c) {
}
void spopCommand(redisClient *c) {
- robj *set, *ele;
+ robj *set, *ele, *aux;
int64_t llele;
int encoding;
encoding = setTypeRandomElement(set,&ele,&llele);
if (encoding == REDIS_ENCODING_INTSET) {
- addReplyBulkLongLong(c,llele);
+ ele = createStringObjectFromLongLong(llele);
set->ptr = intsetRemove(set->ptr,llele,NULL);
} else {
- addReplyBulk(c,ele);
+ incrRefCount(ele);
setTypeRemove(set,ele);
}
+
+ /* Replicate/AOF this command as an SREM operation */
+ aux = createStringObject("SREM",4);
+ rewriteClientCommandVector(c,3,aux,c->argv[1],ele);
+ decrRefCount(ele);
+ decrRefCount(aux);
+
+ addReplyBulk(c,ele);
if (setTypeSize(set) == 0) dbDelete(c->db,c->argv[1]);
signalModifiedKey(c->db,c->argv[1]);
server.dirty++;
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 with intset is simple... and fast */
if (sets[j]->encoding == REDIS_ENCODING_INTSET &&