//tair's new expire generic Command //something interesting with tair's expire protocol //if seconds < 0 then //we consider that you don't care with expire,will nothing to do //else if seconds == 0 then //we consider that you want remove the existing timeout on key(just as redis's persist) //else if seconds > 0 && seconds <= now time then //we consider that you give us duration, like 10s(just as redis's expire) //else if seconds > now time then //we conssider that you give us UNIX timestamp (seconds since January 1, 1970)(just as redis's expireat) //so it's equal persist + expire + expireat void expireXGenericCommand(redisClient *c, robj *key, robj *param) { dictEntry *de; long seconds; time_t when; if (getLongFromObject(param, &seconds) != REDIS_OK) { c->returncode = REDIS_ERR_IS_NOT_INTEGER; return; } de = dictFind(c->db->dict,key->ptr); if (de == NULL) { c->returncode = REDIS_OK_NOT_EXIST; return; } if (seconds > 0) { time_t now = time(NULL); if (seconds <= now) { when = now+seconds; } else { when = seconds; } setExpire(c->db,key,when); c->server->dirty++; } else if(seconds == 0 && removeExpire(c->db, c->argv[1])) { c->server->dirty++; } c->returncode = REDIS_OK; return; }
void setGenericCommand(redisClient *c, int nx, robj *key, robj *val, robj *expire) { int retval; long seconds = 0; /* initialized to avoid an harmness warning */ robj *oldval; c->returncode = REDIS_ERR; if (expire) { if (getLongFromObject(expire, &seconds) != REDIS_OK) { c->returncode = REDIS_ERR_IS_NOT_INTEGER; return; } } oldval = lookupKeyWriteWithVersion(c->db,key,&(c->version)); /* Force expire of old key if needed */ if(oldval != NULL) { if(checkType(c, oldval, REDIS_STRING)) { c->returncode = REDIS_ERR_WRONG_TYPE_ERROR; return; } uint16_t version = sdsversion(key->ptr); if(c->version_care && version != 0 && version != c->version) { c->returncode = REDIS_ERR_VERSION_ERROR; return; } else { sdsversion_change(key->ptr, c->version); } } else { sdsversion_change(key->ptr, 0); } if(c->version_care) { sdsversion_add(key->ptr, 1); } retval = dbAdd(c->db,key,val); if (retval == REDIS_ERR) { if (!nx) { dbSuperReplace(c->db,key,val); incrRefCount(val); } else { c->returncode = REDIS_OK_BUT_ALREADY_EXIST; return; } } else { incrRefCount(val); } c->db->dirty++; if (expire) { setExpire(c->db,key,seconds); } else if(c->expiretime == 0) { removeXExpire(c->db, key); } c->returncode = REDIS_OK; }