X-Git-Url: https://git.saurik.com/redis.git/blobdiff_plain/a3cf9041218518f235a297b2f2d0d08ef9a5c4e5..d4d3a70da2c9be4c5aa67a0be735568dbe436568:/src/dscache.c diff --git a/src/dscache.c b/src/dscache.c index faf87e84..46300e63 100644 --- a/src/dscache.c +++ b/src/dscache.c @@ -903,61 +903,6 @@ int waitForSwappedKey(redisClient *c, robj *key) { return 1; } -#if 0 -/* Preload keys for any command with first, last and step values for - * the command keys prototype, as defined in the command table. */ -void waitForMultipleSwappedKeys(redisClient *c, struct redisCommand *cmd, int argc, robj **argv) { - int j, last; - if (cmd->vm_firstkey == 0) return; - last = cmd->vm_lastkey; - if (last < 0) last = argc+last; - for (j = cmd->vm_firstkey; j <= last; j += cmd->vm_keystep) { - redisAssert(j < argc); - waitForSwappedKey(c,argv[j]); - } -} - -/* Preload keys needed for the ZUNIONSTORE and ZINTERSTORE commands. - * Note that the number of keys to preload is user-defined, so we need to - * apply a sanity check against argc. */ -void zunionInterBlockClientOnSwappedKeys(redisClient *c, struct redisCommand *cmd, int argc, robj **argv) { - int i, num; - REDIS_NOTUSED(cmd); - - num = atoi(argv[2]->ptr); - if (num > (argc-3)) return; - for (i = 0; i < num; i++) { - waitForSwappedKey(c,argv[3+i]); - } -} - -/* Preload keys needed to execute the entire MULTI/EXEC block. - * - * This function is called by blockClientOnSwappedKeys when EXEC is issued, - * and will block the client when any command requires a swapped out value. */ -void execBlockClientOnSwappedKeys(redisClient *c, struct redisCommand *cmd, int argc, robj **argv) { - int i, margc; - struct redisCommand *mcmd; - robj **margv; - REDIS_NOTUSED(cmd); - REDIS_NOTUSED(argc); - REDIS_NOTUSED(argv); - - if (!(c->flags & REDIS_MULTI)) return; - for (i = 0; i < c->mstate.count; i++) { - mcmd = c->mstate.commands[i].cmd; - margc = c->mstate.commands[i].argc; - margv = c->mstate.commands[i].argv; - - if (mcmd->vm_preload_proc != NULL) { - mcmd->vm_preload_proc(c,mcmd,margc,margv); - } else { - waitForMultipleSwappedKeys(c,mcmd,margc,margv); - } - } -} -#endif - /* Is this client attempting to run a command against swapped keys? * If so, block it ASAP, load the keys in background, then resume it. * @@ -969,14 +914,40 @@ void execBlockClientOnSwappedKeys(redisClient *c, struct redisCommand *cmd, int * Return 1 if the client is marked as blocked, 0 if the client can * continue as the keys it is going to access appear to be in memory. */ int blockClientOnSwappedKeys(redisClient *c, struct redisCommand *cmd) { - int *keyindex, numkeys, j; - - keyindex = getKeysFromCommand(cmd,c->argv,c->argc,&numkeys, - REDIS_GETKEYS_PRELOAD); - for (j = 0; j < numkeys; j++) waitForSwappedKey(c,c->argv[keyindex[j]]); - getKeysFreeResult(keyindex); - -#warning "Handle EXEC here" + int *keyindex, numkeys, j, i; + + /* EXEC is a special case, we need to preload all the commands + * queued into the transaction */ + if (cmd->proc == execCommand) { + struct redisCommand *mcmd; + robj **margv; + int margc; + + if (!(c->flags & REDIS_MULTI)) return 0; + for (i = 0; i < c->mstate.count; i++) { + mcmd = c->mstate.commands[i].cmd; + margc = c->mstate.commands[i].argc; + margv = c->mstate.commands[i].argv; + + keyindex = getKeysFromCommand(mcmd,margv,margc,&numkeys, + REDIS_GETKEYS_PRELOAD); + for (j = 0; j < numkeys; j++) { + redisLog(REDIS_DEBUG,"Preloading %s", + (char*)margv[keyindex[j]]->ptr); + waitForSwappedKey(c,margv[keyindex[j]]); + } + getKeysFreeResult(keyindex); + } + } else { + keyindex = getKeysFromCommand(cmd,c->argv,c->argc,&numkeys, + REDIS_GETKEYS_PRELOAD); + for (j = 0; j < numkeys; j++) { + redisLog(REDIS_DEBUG,"Preloading %s", + (char*)c->argv[keyindex[j]]->ptr); + waitForSwappedKey(c,c->argv[keyindex[j]]); + } + getKeysFreeResult(keyindex); + } /* If the client was blocked for at least one key, mark it as blocked. */ if (listLength(c->io_keys)) {