]> git.saurik.com Git - redis.git/blobdiff - tests/unit/type/set.tcl
Test for SRANDMEMBER with <count>.
[redis.git] / tests / unit / type / set.tcl
index 5608a6480546676c1e29a90b16debb8b7bd4de34..33416d944b0a8abbb48f89d3948bd43f7cd6f949 100644 (file)
@@ -59,6 +59,13 @@ start_server {
         assert_encoding hashtable myset
     }
 
+    test {Variadic SADD} {
+        r del myset
+        assert_equal 3 [r sadd myset a b c]
+        assert_equal 2 [r sadd myset A a b c B]
+        assert_equal [lsort {A a b c B}] [lsort [r smembers myset]]
+    }
+
     test "Set encoding after DEBUG RELOAD" {
         r del myintset myhashset mylargeintset
         for {set i 0} {$i <  100} {incr i} { r sadd myintset $i }
@@ -90,6 +97,20 @@ start_server {
         assert_equal {3 5} [lsort [r smembers myset]]
     }
 
+    test {SREM with multiple arguments} {
+        r del myset
+        r sadd myset a b c d
+        assert_equal 0 [r srem myset k k k]
+        assert_equal 2 [r srem myset b d x y]
+        lsort [r smembers myset]
+    } {a c}
+
+    test {SREM variadic version with more args needed to destroy the key} {
+        r del myset
+        r sadd myset 1 2 3
+        r srem myset 1 2 3 4 5 6 7 8
+    } {3}
+
     foreach {type} {hashtable intset} {
         for {set i 1} {$i <= 5} {incr i} {
             r del [format "set%d" $i]
@@ -185,6 +206,13 @@ start_server {
         }
     }
 
+    test "SDIFF with first set empty" {
+        r del set1 set2 set3
+        r sadd set2 1 2 3 4
+        r sadd set3 a b c d
+        r sdiff set1 set2 set3
+    } {}
+
     test "SINTER against non-set should throw error" {
         r set key1 x
         assert_error "ERR*wrong kind*" {r sinter key1 noset}
@@ -195,6 +223,23 @@ start_server {
         assert_error "ERR*wrong kind*" {r sunion key1 noset}
     }
 
+    test "SINTER should handle non existing key as empty" {
+        r del set1 set2 set3
+        r sadd set1 a b c
+        r sadd set2 b c d
+        r sinter set1 set2 set3
+    } {}
+
+    test "SINTER with same integer elements but different encoding" {
+        r del set1 set2
+        r sadd set1 1 2 3
+        r sadd set2 1 2 3 a
+        r srem set2 a
+        assert_encoding intset set1
+        assert_encoding hashtable set2
+        lsort [r sinter set1 set2]
+    } {1 2 3}
+
     test "SINTERSTORE against non existing keys should delete dstkey" {
         r set setres xxx
         assert_equal 0 [r sinterstore setres foo111 bar222]
@@ -226,6 +271,118 @@ start_server {
         }
     }
 
+    test "SRANDMEMBER with <count> against non existing key" {
+        r srandmember nonexisting_key 100
+    } {}
+
+    foreach {type contents} {
+        hashtable {
+            1 5 10 50 125 50000 33959417 4775547 65434162
+            12098459 427716 483706 2726473884 72615637475
+            MARY PATRICIA LINDA BARBARA ELIZABETH JENNIFER MARIA
+            SUSAN MARGARET DOROTHY LISA NANCY KAREN BETTY HELEN
+            SANDRA DONNA CAROL RUTH SHARON MICHELLE LAURA SARAH
+            KIMBERLY DEBORAH JESSICA SHIRLEY CYNTHIA ANGELA MELISSA
+            BRENDA AMY ANNA REBECCA VIRGINIA KATHLEEN
+        }
+        intset {
+            0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
+            20 21 22 23 24 25 26 27 28 29
+            30 31 32 33 34 35 36 37 38 39
+            40 41 42 43 44 45 46 47 48 49
+        }
+    } {
+        test "SRANDMEMBER with <count> - $type" {
+            create_set myset $contents
+            unset -nocomplain myset
+            array set myset {}
+            foreach ele [r smembers myset] {
+                set myset($ele) 1
+            }
+            assert_equal [lsort $contents] [lsort [array names myset]]
+
+            # Make sure that a count of 0 is handled correctly.
+            assert_equal [r srandmember myset 0] {}
+
+            # We'll stress different parts of the code, see the implementation
+            # of SRANDMEMBER for more information, but basically there are
+            # four different code paths.
+            #
+            # PATH 1: Use negative count.
+            #
+            # 1) Check that it returns repeated elements.
+            set res [r srandmember myset -100]
+            assert_equal [llength $res] 100
+
+            # 2) Check that all the elements actually belong to the
+            # original set.
+            foreach ele $res {
+                assert {[info exists myset($ele)]}
+            }
+
+            # 3) Check that eventually all the elements are returned.
+            unset -nocomplain auxset
+            set iterations 1000
+            while {$iterations != 0} {
+                incr iterations -1
+                set res [r srandmember myset -10]
+                foreach ele $res {
+                    set auxset($ele) 1
+                }
+                if {[lsort [array names myset]] eq
+                    [lsort [array names auxset]]} {
+                    break;
+                }
+            }
+            assert {$iterations != 0}
+
+            # PATH 2: positive count (unique behavior) with requested size
+            # equal or greater than set size.
+            foreach size {50 100} {
+                set res [r srandmember myset $size]
+                assert_equal [llength $res] 50
+                assert_equal [lsort $res] [lsort [array names myset]]
+            }
+
+            # PATH 3: Ask almost as elements as there are in the set.
+            # In this case the implementation will duplicate the original
+            # set and will remove random elements up to the requested size.
+            #
+            # PATH 4: Ask a number of elements definitely smaller than
+            # the set size.
+            #
+            # We can test both the code paths just changing the size but
+            # using the same code.
+
+            foreach size {45 5} {
+                set res [r srandmember myset $size]
+                assert_equal [llength $res] $size
+
+                # 1) Check that all the elements actually belong to the
+                # original set.
+                foreach ele $res {
+                    assert {[info exists myset($ele)]}
+                }
+
+                # 2) Check that eventually all the elements are returned.
+                unset -nocomplain auxset
+                set iterations 1000
+                while {$iterations != 0} {
+                    incr iterations -1
+                    set res [r srandmember myset -10]
+                    foreach ele $res {
+                        set auxset($ele) 1
+                    }
+                    if {[lsort [array names myset]] eq
+                        [lsort [array names auxset]]} {
+                        break;
+                    }
+                }
+                assert {$iterations != 0}
+            }
+        }
+    }
+
     proc setup_move {} {
         r del myset3 myset4
         create_set myset1 {1 a b}
@@ -296,6 +453,13 @@ start_server {
         assert_error "ERR*wrong kind*" {r smove myset2 x foo}
     }
 
+    test "SMOVE with identical source and destination" {
+        r del set
+        r sadd set a b c
+        r smove set set b
+        lsort [r smembers set]
+    } {a b c}
+
     tags {slow} {
         test {intsets implementation stress testing} {
             for {set j 0} {$j < 20} {incr j} {