diff options
-rw-r--r-- | src/bitops.c | 2 | ||||
-rw-r--r-- | src/db.c | 24 | ||||
-rw-r--r-- | src/geo.c | 2 | ||||
-rw-r--r-- | src/module.c | 6 | ||||
-rw-r--r-- | src/server.h | 8 | ||||
-rw-r--r-- | src/sort.c | 2 | ||||
-rw-r--r-- | src/t_set.c | 4 | ||||
-rw-r--r-- | src/t_string.c | 18 | ||||
-rw-r--r-- | src/t_zset.c | 4 |
9 files changed, 43 insertions, 27 deletions
diff --git a/src/bitops.c b/src/bitops.c index 5190e1035..f69e6b4c6 100644 --- a/src/bitops.c +++ b/src/bitops.c @@ -777,7 +777,7 @@ void bitopCommand(client *c) { /* Store the computed value into the target key */ if (maxlen) { o = createObject(OBJ_STRING,res); - setKey(c,c->db,targetkey,o); + setKey(c,c->db,targetkey,o,0); notifyKeyspaceEvent(NOTIFY_STRING,"set",targetkey,c->db->id); decrRefCount(o); server.dirty++; @@ -243,25 +243,29 @@ void dbOverwrite(redisDb *db, robj *key, robj *val) { * 1) The ref count of the value object is incremented. * 2) clients WATCHing for the destination key notified. * 3) The expire time of the key is reset (the key is made persistent), - * unless 'keepttl' is true. + * unless 'SETKEY_KEEPTTL' is enabled in flags. + * 4) The key lookup can take place outside this interface outcome will be + * delivered with 'SETKEY_ALREADY_EXIST' or 'SETKEY_DOESNT_EXIST' * * All the new keys in the database should be created via this interface. * The client 'c' argument may be set to NULL if the operation is performed * in a context where there is no clear client performing the operation. */ -void genericSetKey(client *c, redisDb *db, robj *key, robj *val, int keepttl, int signal) { - if (lookupKeyWrite(db,key) == NULL) { +void setKey(client *c, redisDb *db, robj *key, robj *val, int flags) { + int keyfound = 0; + + if (flags & SETKEY_ALREADY_EXIST) + keyfound = 1; + else if (!(flags & SETKEY_DOESNT_EXIST)) + keyfound = (lookupKeyWrite(db,key) != NULL); + + if (!keyfound) { dbAdd(db,key,val); } else { dbOverwrite(db,key,val); } incrRefCount(val); - if (!keepttl) removeExpire(db,key); - if (signal) signalModifiedKey(c,db,key); -} - -/* Common case for genericSetKey() where the TTL is not retained. */ -void setKey(client *c, redisDb *db, robj *key, robj *val) { - genericSetKey(c,db,key,val,0,1); + if (!(flags & SETKEY_KEEPTTL)) removeExpire(db,key); + if (!(flags & SETKEY_NO_SIGNAL)) signalModifiedKey(c,db,key); } /* Return a random key, in form of a Redis object. @@ -820,7 +820,7 @@ void georadiusGeneric(client *c, int srcKeyIndex, int flags) { if (returned_items) { zsetConvertToListpackIfNeeded(zobj,maxelelen,totelelen); - setKey(c,c->db,storekey,zobj); + setKey(c,c->db,storekey,zobj,0); decrRefCount(zobj); notifyKeyspaceEvent(NOTIFY_ZSET,flags & GEOSEARCH ? "geosearchstore" : "georadiusstore",storekey, c->db->id); diff --git a/src/module.c b/src/module.c index 37bfa2173..53ba70f77 100644 --- a/src/module.c +++ b/src/module.c @@ -3079,7 +3079,7 @@ int RM_GetToDbIdFromOptCtx(RedisModuleKeyOptCtx *ctx) { int RM_StringSet(RedisModuleKey *key, RedisModuleString *str) { if (!(key->mode & REDISMODULE_WRITE) || key->iter) return REDISMODULE_ERR; RM_DeleteKey(key); - genericSetKey(key->ctx->client,key->db,key->key,str,0,0); + setKey(key->ctx->client,key->db,key->key,str,SETKEY_NO_SIGNAL); key->value = str; return REDISMODULE_OK; } @@ -3159,7 +3159,7 @@ int RM_StringTruncate(RedisModuleKey *key, size_t newlen) { if (key->value == NULL) { /* Empty key: create it with the new size. */ robj *o = createObject(OBJ_STRING,sdsnewlen(NULL, newlen)); - genericSetKey(key->ctx->client,key->db,key->key,o,0,0); + setKey(key->ctx->client,key->db,key->key,o,SETKEY_NO_SIGNAL); key->value = o; decrRefCount(o); } else { @@ -5437,7 +5437,7 @@ int RM_ModuleTypeSetValue(RedisModuleKey *key, moduleType *mt, void *value) { if (!(key->mode & REDISMODULE_WRITE) || key->iter) return REDISMODULE_ERR; RM_DeleteKey(key); robj *o = createModuleObject(mt,value); - genericSetKey(key->ctx->client,key->db,key->key,o,0,0); + setKey(key->ctx->client,key->db,key->key,o,SETKEY_NO_SIGNAL); decrRefCount(o); key->value = o; return REDISMODULE_OK; diff --git a/src/server.h b/src/server.h index fd5762db9..9eca98230 100644 --- a/src/server.h +++ b/src/server.h @@ -2645,8 +2645,12 @@ int objectSetLRUOrLFU(robj *val, long long lfu_freq, long long lru_idle, void dbAdd(redisDb *db, robj *key, robj *val); int dbAddRDBLoad(redisDb *db, sds key, robj *val); void dbOverwrite(redisDb *db, robj *key, robj *val); -void genericSetKey(client *c, redisDb *db, robj *key, robj *val, int keepttl, int signal); -void setKey(client *c, redisDb *db, robj *key, robj *val); + +#define SETKEY_KEEPTTL 1 +#define SETKEY_NO_SIGNAL 2 +#define SETKEY_ALREADY_EXIST 4 +#define SETKEY_DOESNT_EXIST 8 +void setKey(client *c, redisDb *db, robj *key, robj *val, int flags); robj *dbRandomKey(redisDb *db); int dbSyncDelete(redisDb *db, robj *key); int dbDelete(redisDb *db, robj *key); diff --git a/src/sort.c b/src/sort.c index 1eb61f83a..436c7fb0e 100644 --- a/src/sort.c +++ b/src/sort.c @@ -570,7 +570,7 @@ void sortCommandGeneric(client *c, int readonly) { } } if (outputlen) { - setKey(c,c->db,storekey,sobj); + setKey(c,c->db,storekey,sobj,0); notifyKeyspaceEvent(NOTIFY_LIST,"sortstore",storekey, c->db->id); server.dirty += outputlen; diff --git a/src/t_set.c b/src/t_set.c index 72743a6fd..ec9749f13 100644 --- a/src/t_set.c +++ b/src/t_set.c @@ -987,7 +987,7 @@ void sinterGenericCommand(client *c, robj **setkeys, /* Store the resulting set into the target, if the intersection * is not an empty set. */ if (setTypeSize(dstset) > 0) { - setKey(c,c->db,dstkey,dstset); + setKey(c,c->db,dstkey,dstset,0); addReplyLongLong(c,setTypeSize(dstset)); notifyKeyspaceEvent(NOTIFY_SET,"sinterstore", dstkey,c->db->id); @@ -1191,7 +1191,7 @@ void sunionDiffGenericCommand(client *c, robj **setkeys, int setnum, /* If we have a target key where to store the resulting set * create this key with the result set inside */ if (setTypeSize(dstset) > 0) { - setKey(c,c->db,dstkey,dstset); + setKey(c,c->db,dstkey,dstset,0); addReplyLongLong(c,setTypeSize(dstset)); notifyKeyspaceEvent(NOTIFY_SET, op == SET_OP_UNION ? "sunionstore" : "sdiffstore", diff --git a/src/t_string.c b/src/t_string.c index f1c1fdca2..e1917958b 100644 --- a/src/t_string.c +++ b/src/t_string.c @@ -77,6 +77,9 @@ static int getExpireMillisecondsOrReply(client *c, robj *expire, int flags, int void setGenericCommand(client *c, int flags, robj *key, robj *val, robj *expire, int unit, robj *ok_reply, robj *abort_reply) { long long milliseconds = 0; /* initialized to avoid any harmness warning */ + int found = 0; + int setkey_flags = 0; + if (expire && getExpireMillisecondsOrReply(c, expire, flags, unit, &milliseconds) != C_OK) { return; } @@ -85,8 +88,10 @@ void setGenericCommand(client *c, int flags, robj *key, robj *val, robj *expire, if (getGenericCommand(c) == C_ERR) return; } - if ((flags & OBJ_SET_NX && lookupKeyWrite(c->db,key) != NULL) || - (flags & OBJ_SET_XX && lookupKeyWrite(c->db,key) == NULL)) + found = (lookupKeyWrite(c->db,key) != NULL); + + if ((flags & OBJ_SET_NX && found) || + (flags & OBJ_SET_XX && !found)) { if (!(flags & OBJ_SET_GET)) { addReply(c, abort_reply ? abort_reply : shared.null[c->resp]); @@ -94,7 +99,10 @@ void setGenericCommand(client *c, int flags, robj *key, robj *val, robj *expire, return; } - genericSetKey(c,c->db,key, val,flags & OBJ_KEEPTTL,1); + setkey_flags |= (flags & OBJ_KEEPTTL) ? SETKEY_KEEPTTL : 0; + setkey_flags |= found ? SETKEY_ALREADY_EXIST : SETKEY_DOESNT_EXIST; + + setKey(c,c->db,key,val,setkey_flags); server.dirty++; notifyKeyspaceEvent(NOTIFY_STRING,"set",key,c->db->id); @@ -418,7 +426,7 @@ void getdelCommand(client *c) { void getsetCommand(client *c) { if (getGenericCommand(c) == C_ERR) return; c->argv[2] = tryObjectEncoding(c->argv[2]); - setKey(c,c->db,c->argv[1],c->argv[2]); + setKey(c,c->db,c->argv[1],c->argv[2],0); notifyKeyspaceEvent(NOTIFY_STRING,"set",c->argv[1],c->db->id); server.dirty++; @@ -567,7 +575,7 @@ void msetGenericCommand(client *c, int nx) { for (j = 1; j < c->argc; j += 2) { c->argv[j+1] = tryObjectEncoding(c->argv[j+1]); - setKey(c,c->db,c->argv[j],c->argv[j+1]); + setKey(c,c->db,c->argv[j],c->argv[j+1],0); notifyKeyspaceEvent(NOTIFY_STRING,"set",c->argv[j],c->db->id); } server.dirty += (c->argc-1)/2; diff --git a/src/t_zset.c b/src/t_zset.c index 952d24709..06c2d2372 100644 --- a/src/t_zset.c +++ b/src/t_zset.c @@ -2762,7 +2762,7 @@ void zunionInterDiffGenericCommand(client *c, robj *dstkey, int numkeysIndex, in if (dstkey) { if (dstzset->zsl->length) { zsetConvertToListpackIfNeeded(dstobj, maxelelen, totelelen); - setKey(c, c->db, dstkey, dstobj); + setKey(c, c->db, dstkey, dstobj, 0); addReplyLongLong(c, zsetLength(dstobj)); notifyKeyspaceEvent(NOTIFY_ZSET, (op == SET_OP_UNION) ? "zunionstore" : @@ -2955,7 +2955,7 @@ static void zrangeResultEmitLongLongForStore(zrange_result_handler *handler, static void zrangeResultFinalizeStore(zrange_result_handler *handler, size_t result_count) { if (result_count) { - setKey(handler->client, handler->client->db, handler->dstkey, handler->dstobj); + setKey(handler->client, handler->client->db, handler->dstkey, handler->dstobj, 0); addReplyLongLong(handler->client, result_count); notifyKeyspaceEvent(NOTIFY_ZSET, "zrangestore", handler->dstkey, handler->client->db->id); server.dirty++; |