100 Commits

Author SHA1 Message Date
antirez
e9f1288faf Test: regression for issue #801. 2012-12-02 20:43:11 +01:00
antirez
68e2d2ce07 SDIFF is now able to select between two algorithms for speed.
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.
2012-11-30 16:36:42 +01:00
antirez
f76b95e713 SDIFF fuzz test added. 2012-11-30 01:35:34 +01:00
antirez
a037c6abf5 Type mismatch errors are now prefixed with WRONGTYPE.
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.
2012-11-06 20:25:34 +01:00
antirez
0a1a7308a1 Test for SRANDMEMBER with <count>. 2012-09-21 11:55:36 +02:00
antirez
8574733f48 A reimplementation of blocking operation internals.
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.
2012-09-17 10:26:46 +02:00
antirez
3e0309f0a9 Added a new hash fuzzy tester.
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.
2012-06-12 15:21:54 +02:00
antirez
c1be7c2610 New test: hash ziplist -> hashtable encoding conversion.
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.
2012-06-11 15:19:46 +02:00
antirez
e093a09c2f Fixed issue #516 (ZINTERSTORE mixing sets and zsets).
Weeks ago trying to fix an harmless GCC warning I introduced a bug in
the ziplist-encoded implementations of sorted sets.

The bug completely broke zuiNext() iterator, that is used in the
ZINTERSTORE and ZUNIONSTORE implementation, so those two commands are no
longer reliable starting from Redis version 2.4.12 and latest 2.6.0-RC
releases.

This commit fixes the problem and adds a regression test.
2012-05-23 11:12:43 +02:00
antirez
e12b40d3be Ziplist encoding now tested with negative integers as well. 2012-04-23 17:27:46 +02:00
antirez
9d80adcf99 Test SDIFF with first set empty. 2012-04-18 18:13:31 +02:00
antirez
bfdb8667fd Test SINTER against same integer elements, but different set encoding. 2012-04-18 18:10:48 +02:00
antirez
f56007b3d5 Test SINTER with non existing key. 2012-04-18 18:05:02 +02:00
antirez
9611f24607 Added an SMOVE test where src and dest key are the same. 2012-04-18 18:00:12 +02:00
antirez
25b016e4d3 New hash fuzzing test. 2012-04-18 17:56:17 +02:00
antirez
353f01d462 Explicit RPOP/LPOP tests. 2012-04-18 17:32:48 +02:00
antirez
62d36c3d16 Test LINSERT syntax error. 2012-04-18 17:22:14 +02:00
antirez
eab7143b2c Test LINDEX out of range index. 2012-04-18 17:17:53 +02:00
antirez
afadac1728 Merge conflicts resolved. 2012-03-09 22:07:45 +01:00
antirez
5c54ab0b7f Issue #330 regression test. 2012-02-16 16:13:40 +01:00
Pieter Noordhuis
ae204e5428 Encode small hashes with a ziplist 2012-01-02 22:14:10 -08:00
antirez
d000c35b60 Added regression test for ZUNIONSTORE creating NaN (github issue #264) 2011-12-23 09:34:06 +01:00
antirez
26d2ed1ce4 more valgrind (and other archs) friendly testing of floating number related features. 2011-11-16 14:40:50 +01:00
antirez
85056993ed valgrind handles floating point numbers differently for some reason, so using "simpler" numbers to make tests happy. 2011-11-16 13:35:22 +01:00
antirez
0321c79b42 HINCRBYFLOAT tests 2011-11-15 15:26:10 +01:00
antirez
33dcbd6df7 string to number API is now more strict not accepting spaces before or after the number. A few tests converted to match the new error messages using the word float instead of double. 2011-11-14 15:34:44 +01:00
antirez
e9dee96c29 regression test for bug 593 added 2011-09-12 10:53:49 +02:00
Pieter Noordhuis
49fd303a6b HDEL: Abort deleting fields when hash is removed 2011-07-27 12:29:40 +02:00
antirez
02d67a4fbc fix a test timing issue when running the test over valgrind 2011-07-11 15:44:38 +02:00
antirez
d801f7a4be the test runs less iterations of slow tests if no --accurate is given. 2011-07-11 12:15:35 +02:00
antirez
8843375b2a list test further split into smaller units 2011-07-11 11:41:23 +02:00
antirez
a8644e8a26 list test split into smaller parts 2011-07-11 11:30:46 +02:00
antirez
7192cd5cb7 Fix for bug 561 and other related problems 2011-06-20 17:19:36 +02:00
antirez
8304f37085 ZREM tests 2011-05-31 20:30:54 +02:00
antirez
86ee8a8f25 Fix for the variadic version of SREM. Regression test added. 2011-05-31 20:14:29 +02:00
antirez
6975baed26 disabled development test entry, tests moved in the right place 2011-05-31 18:49:12 +02:00
antirez
4ea2be056b Fix for ZUNIONSTORE bug when there is an empty set among input sets. Regression test added. 2011-05-19 17:58:52 +02:00
antirez
1f1d9e584b ZINTERSTORE regressiont test with two sets, intset+hashtable 2011-05-12 20:20:40 +02:00
antirez
ca50eb1977 Variadic SREM 2011-04-19 17:37:03 +02:00
antirez
1a0dcc6a67 variadic HDEL with tests 2011-04-19 17:07:55 +02:00
antirez
d0d6042e7f Variadic SADD tests 2011-04-15 18:28:25 +02:00
antirez
ab1b8e3a73 tests for variadic list push 2011-04-15 16:52:07 +02:00
Pieter Noordhuis
a6ca3077d4 Test for ENCODING_SKIPLIST instead of ENCODING_RAW 2011-04-06 16:17:07 +02:00
Pieter Noordhuis
733dee1f1c Test that sorted sets are removed when empty 2011-03-22 09:28:45 +01:00
Pieter Noordhuis
e615ae62cb Test both sorted set encodings for every test 2011-03-14 10:54:37 +01:00
Pieter Noordhuis
dc940c96f0 Test for empty inner range when looking for elements in range 2011-03-11 18:18:02 +01:00
Pieter Noordhuis
f68fbab536 Test for ranges where min > max 2011-03-08 10:57:39 +01:00
Pieter Noordhuis
acb51177dc Move logic concerned with zset ranges
This also optimizes ZREVRANGEBYSCORE for pathological cases where a
sorted set contains many elements with the same score. Previously,
it would traverse the list from back to front in such a case.
2011-03-08 10:57:24 +01:00
Pieter Noordhuis
845da0b0d3 Fix case and indent 2010-12-06 16:04:42 +01:00
Pieter Noordhuis
0e83e79f73 Check other blocked clients when value could not be pushed 2010-12-06 16:04:10 +01:00