- 28 Mar, 2013 1 commit
-
-
antirez authored
-
- 27 Mar, 2013 2 commits
- 25 Mar, 2013 1 commit
-
-
antirez authored
Fixes #621.
-
- 12 Feb, 2013 2 commits
- 28 Jan, 2013 1 commit
-
-
antirez authored
-
- 21 Jan, 2013 1 commit
-
-
antirez authored
UNSUBSCRIBE and PUNSUBSCRIBE commands are designed to mass-unsubscribe the client respectively all the channels and patters if called without arguments. However when these functions are called without arguments, but there are no channels or patters we are subscribed to, the old behavior was to don't reply at all. This behavior is broken, as every command should always reply. Also it is possible that we are no longer subscribed to a channels but we are subscribed to patters or the other way around, and the client should be notified with the correct number of subscriptions. Also it is not pretty that sometimes we did not receive a reply at all in a redis-cli session from these commands, blocking redis-cli trying to read the reply. This fixes issue #714.
-
- 19 Jan, 2013 2 commits
- 15 Jan, 2013 1 commit
-
-
antirez authored
-
- 10 Jan, 2013 1 commit
-
-
antirez authored
-
- 02 Dec, 2012 1 commit
-
-
antirez authored
-
- 30 Nov, 2012 2 commits
-
-
antirez authored
SDIFF used an algorithm that was O(N) where N is the total number of elements of all the sets involved in the operation. The algorithm worked like that: ALGORITHM 1: 1) For the first set, add all the members to an auxiliary set. 2) For all the other sets, remove all the members of the set from the auxiliary set. So it is an O(N) algorithm where N is the total number of elements in all the sets involved in the diff operation. Cristobal Viedma suggested to modify the algorithm to the following: ALGORITHM 2: 1) Iterate all the elements of the first set. 2) For every element, check if the element also exists in all the other remaining sets. 3) Add the element to the auxiliary set only if it does not exist in any of the other sets. The complexity of this algorithm on the worst case is O(N*M) where N is the size of the first set and M the total number of sets involved in the operation. However when there are elements in common, with this algorithm we stop the computation for a given element as long as we find a duplicated element into another set. I (antirez) added an additional step to algorithm 2 to make it faster, that is to sort the set to subtract from the biggest to the smallest, so that it is more likely to find a duplicate in a larger sets that are checked before the smaller ones. WHAT IS BETTER? None of course, for instance if the first set is much larger than the other sets the second algorithm does a lot more work compared to the first algorithm. Similarly if the first set is much smaller than the other sets, the original algorithm will less work. So this commit makes Redis able to guess the number of operations required by each algorithm, and select the best at runtime according to the input received. However, since the second algorithm has better constant times and can do less work if there are duplicated elements, an advantage is given to the second algorithm.
-
antirez authored
-
- 29 Nov, 2012 1 commit
-
-
antirez authored
-
- 22 Nov, 2012 4 commits
- 14 Nov, 2012 2 commits
- 12 Nov, 2012 1 commit
-
-
antirez authored
The previous behavior was to return -1 if: 1) Existing key but without an expire set. 2) Non existing key. Now the second case is handled in a different, and TTL will return -2 if the key does not exist at all. PTTL follows the same behavior as well.
-
- 07 Nov, 2012 2 commits
-
-
antirez authored
With COPY now MIGRATE does not remove the key from the source instance. With REPLACE it uses RESTORE REPLACE on the target host so that even if the key already eixsts in the target instance it will be overwritten. The options can be used together.
-
antirez authored
The REPLACE option deletes an existing key with the same name (if any) and materializes the new one. The default behavior without RESTORE is to return an error if a key already exists.
-
- 06 Nov, 2012 1 commit
-
-
antirez authored
So instead to reply with a generic error like: -ERR ... wrong kind of value ... now it replies with: -WRONGTYPE ... wrong kind of value ... This makes this particular error easy to check without resorting to (fragile) pattern matching of the error string (however the error string used to be consistent already). Client libraries should return a specific exeption type for this error. Most of the commit is about fixing unit tests.
-
- 22 Oct, 2012 1 commit
-
-
antirez authored
When calling SCRIPT KILL currently you can get two errors: * No script in timeout (busy) state. * The script already performed a write. It is useful to be able to distinguish the two errors, but right now both start with "ERR" prefix, so string matching (that is fragile) must be used. This commit introduces two different prefixes. -NOTBUSY and -UNKILLABLE respectively to reply with an error when no script is busy at the moment, and when the script already executed a write operation and can not be killed.
-
- 03 Oct, 2012 1 commit
-
-
antirez authored
When SORT is called with the option BY set to a string constant not inclduing the wildcard character "*", there is no way to sort the output so any ordering is valid. This allows the SORT internals to optimize its work and don't really sort the output at all. However it was odd that this option was not able to retain the natural order of a sorted set. This feature was requested by users multiple times as sometimes to call SORT with GET against sorted sets as a way to mass-fetch objects can be handy. This commit introduces two things: 1) The ability of SORT to return sorted sets elements in their natural ordering when `BY nosort` is specified, accordingly to `DESC / ASC` options. 2) The ability of SORT to optimize this case further if LIMIT is passed as well, avoiding to really fetch the whole sorted set, but directly obtaining the specified range. Because in this case the sorting is always deterministic, no post-sorting activity is performed when SORT is called from a Lua script. This commit fixes issue #98.
-
- 01 Oct, 2012 1 commit
-
- 28 Sep, 2012 1 commit
-
-
antirez authored
Lua arrays can't contain nil elements (see http://www.lua.org/pil/19.1.html for more information), so Lua scripts were not able to return a multi-bulk reply containing nil bulk elements inside. This commit introduces a special conversion: a table with just a "nilbulk" field set to a boolean value is converted by Redis as a nil bulk reply, but at the same time for Lua this type is not a "nil" so can be used inside Lua arrays. This type is also assigned to redis.NIL, so the following two forms are equivalent and will be able to return a nil bulk reply as second element of a three elements array: EVAL "return {1,redis.NIL,3}" 0 EVAL "return {1,{nilbulk=true},3}" 0 The result in redis-cli will be: 1) (integer) 1 2) (nil) 3) (integer) 3
-
- 21 Sep, 2012 1 commit
-
-
antirez authored
-
- 17 Sep, 2012 1 commit
-
-
antirez authored
Redis provides support for blocking operations such as BLPOP or BRPOP. This operations are identical to normal LPOP and RPOP operations as long as there are elements in the target list, but if the list is empty they block waiting for new data to arrive to the list. All the clients blocked waiting for th same list are served in a FIFO way, so the first that blocked is the first to be served when there is more data pushed by another client into the list. The previous implementation of blocking operations was conceived to serve clients in the context of push operations. For for instance: 1) There is a client "A" blocked on list "foo". 2) The client "B" performs `LPUSH foo somevalue`. 3) The client "A" is served in the context of the "B" LPUSH, synchronously. Processing things in a synchronous way was useful as if "A" pushes a value that is served by "B", from the point of view of the database is a NOP (no operation) thing, that is, nothing is replicated, nothing is written in the AOF file, and so forth. However later we implemented two things: 1) Variadic LPUSH that could add multiple values to a list in the context of a single call. 2) BRPOPLPUSH that was a version of BRPOP that also provided a "PUSH" side effect when receiving data. This forced us to make the synchronous implementation more complex. If client "B" is waiting for data, and "A" pushes three elemnents in a single call, we needed to propagate an LPUSH with a missing argument in the AOF and replication link. We also needed to make sure to replicate the LPUSH side of BRPOPLPUSH, but only if in turn did not happened to serve another blocking client into another list ;) This were complex but with a few of mutually recursive functions everything worked as expected... until one day we introduced scripting in Redis. Scripting + synchronous blocking operations = Issue #614. Basically you can't "rewrite" a script to have just a partial effect on the replicas and AOF file if the script happened to serve a few blocked clients. The solution to all this problems, implemented by this commit, is to change the way we serve blocked clients. Instead of serving the blocked clients synchronously, in the context of the command performing the PUSH operation, it is now an asynchronous and iterative process: 1) If a key that has clients blocked waiting for data is the subject of a list push operation, We simply mark keys as "ready" and put it into a queue. 2) Every command pushing stuff on lists, as a variadic LPUSH, a script, or whatever it is, is replicated verbatim without any rewriting. 3) Every time a Redis command, a MULTI/EXEC block, or a script, completed its execution, we run the list of keys ready to serve blocked clients (as more data arrived), and process this list serving the blocked clients. 4) As a result of "3" maybe more keys are ready again for other clients (as a result of BRPOPLPUSH we may have push operations), so we iterate back to step "3" if it's needed. The new code has a much simpler semantics, and a simpler to understand implementation, with the disadvantage of not being able to "optmize out" a PUSH+BPOP as a No OP. This commit will be tested with care before the final merge, more tests will be added likely.
-
- 05 Sep, 2012 2 commits
-
-
antirez authored
Bug #582 was not present in 32 bit builds of Redis as getObjectFromLong() will return an error for overflow. This commit makes sure that the test does not fail because of the error returned when running against 32 bit builds.
-
Haruto Otake authored
remove unsafe and unnecessary cast. until now, this cast may lead segmentation fault when end > UINT_MAX setbit foo 0 1 bitcount 0 4294967295 => ok bitcount 0 4294967296 => cause segmentation fault. Note by @antirez: the commit was modified a bit to also change the string length type to long, since it's guaranteed to be at max 512 MB in size, so we can work with the same type across all the code path. A regression test was also added.
-
- 04 Sep, 2012 1 commit
-
-
antirez authored
SORT is able to return (faster than when ordering) unordered output if the "BY" clause is used with a constant value. However we try to play well with scripting requirements of determinism providing always sorted outputs when SORT (and other similar commands) are called by Lua scripts. However we used the general mechanism in place in scripting in order to reorder SORT output, that is, if the command has the "S" flag set, the Lua scripting engine will take an additional step when converting a multi bulk reply to Lua value, calling a Lua sorting function. This is suboptimal as we can do it faster inside SORT itself. This is also broken as issue #545 shows us: basically when SORT is used with a constant BY, and additionally also GET is used, the Lua scripting engine was trying to order the output as a flat array, while it was actually a list of key-value pairs. What we do know is to recognized if the caller of SORT is the Lua client (since we can check this using the REDIS_LUA_CLIENT flag). If so, and if a "don't sort" condition is triggered by the BY option with a constant string, we force the lexicographical sorting. This commit fixes this bug and improves the performance, and at the same time simplifies the implementation. This does not mean I'm smart today, it means I was stupid when I committed the original implementation ;)
-
- 31 Aug, 2012 1 commit
-
-
antirez authored
Redis used to crash with a call like the following: EVAL "redis.call()" 0 Now the explicit check for at least one argument prevents the problem. This commit fixes issue #655.
-
- 12 Jun, 2012 1 commit
-
-
antirez authored
The new fuzzy tester also removes elements from the hash instead of just adding random fields. This should increase the probability to find bugs in the implementations of the hash type internal representations.
-
- 11 Jun, 2012 1 commit
-
-
antirez authored
A new stress test was added to stress test the code converting a ziplist into an hash table. In this commit also randomValue helper function was modified to also return negative values.
-
- 02 Jun, 2012 2 commits
-
-
antirez authored
wait_for_condition is now used instead of the usual "after 1000" (that is the way to sleep in Tcl). This should avoid to find the replica in a state where it is loading the RDB in memory, returning -LOADING error. This test used to fail when running the test over valgrind, due to the added latencies.
-
Alex Mitrofanov authored
(additional commit notes by antirez@gmail.com): The rdbIsObjectType() macro was not updated when the new RDB object type of ziplist encoded hashes was added. As a result RESTORE, that uses rdbLoadObjectType(), failed when a ziplist encoded hash was loaded. This does not affected normal RDB loading because in that case we use the lower-level function rdbLoadType(). The commit also adds a regression test.
-