123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536 |
- start_server {tags {"hash"}} {
- test {HSET/HLEN - Small hash creation} {
- array set smallhash {}
- for {set i 0} {$i < 8} {incr i} {
- set key __avoid_collisions__[randstring 0 8 alpha]
- set val __avoid_collisions__[randstring 0 8 alpha]
- if {[info exists smallhash($key)]} {
- incr i -1
- continue
- }
- r hset smallhash $key $val
- set smallhash($key) $val
- }
- list [r hlen smallhash]
- } {8}
- test {Is the small hash encoded with a ziplist?} {
- assert_encoding ziplist smallhash
- }
- test {HSET/HLEN - Big hash creation} {
- array set bighash {}
- for {set i 0} {$i < 1024} {incr i} {
- set key __avoid_collisions__[randstring 0 8 alpha]
- set val __avoid_collisions__[randstring 0 8 alpha]
- if {[info exists bighash($key)]} {
- incr i -1
- continue
- }
- r hset bighash $key $val
- set bighash($key) $val
- }
- list [r hlen bighash]
- } {1024}
- test {Is the big hash encoded with an hash table?} {
- assert_encoding hashtable bighash
- }
- test {HGET against the small hash} {
- set err {}
- foreach k [array names smallhash *] {
- if {$smallhash($k) ne [r hget smallhash $k]} {
- set err "$smallhash($k) != [r hget smallhash $k]"
- break
- }
- }
- set _ $err
- } {}
- test {HGET against the big hash} {
- set err {}
- foreach k [array names bighash *] {
- if {$bighash($k) ne [r hget bighash $k]} {
- set err "$bighash($k) != [r hget bighash $k]"
- break
- }
- }
- set _ $err
- } {}
- test {HGET against non existing key} {
- set rv {}
- lappend rv [r hget smallhash __123123123__]
- lappend rv [r hget bighash __123123123__]
- set _ $rv
- } {{} {}}
- test {HSET in update and insert mode} {
- set rv {}
- set k [lindex [array names smallhash *] 0]
- lappend rv [r hset smallhash $k newval1]
- set smallhash($k) newval1
- lappend rv [r hget smallhash $k]
- lappend rv [r hset smallhash __foobar123__ newval]
- set k [lindex [array names bighash *] 0]
- lappend rv [r hset bighash $k newval2]
- set bighash($k) newval2
- lappend rv [r hget bighash $k]
- lappend rv [r hset bighash __foobar123__ newval]
- lappend rv [r hdel smallhash __foobar123__]
- lappend rv [r hdel bighash __foobar123__]
- set _ $rv
- } {0 newval1 1 0 newval2 1 1 1}
- test {HSETNX target key missing - small hash} {
- r hsetnx smallhash __123123123__ foo
- r hget smallhash __123123123__
- } {foo}
- test {HSETNX target key exists - small hash} {
- r hsetnx smallhash __123123123__ bar
- set result [r hget smallhash __123123123__]
- r hdel smallhash __123123123__
- set _ $result
- } {foo}
- test {HSETNX target key missing - big hash} {
- r hsetnx bighash __123123123__ foo
- r hget bighash __123123123__
- } {foo}
- test {HSETNX target key exists - big hash} {
- r hsetnx bighash __123123123__ bar
- set result [r hget bighash __123123123__]
- r hdel bighash __123123123__
- set _ $result
- } {foo}
- test {HMSET wrong number of args} {
- catch {r hmset smallhash key1 val1 key2} err
- format $err
- } {*wrong number*}
- test {HMSET - small hash} {
- set args {}
- foreach {k v} [array get smallhash] {
- set newval [randstring 0 8 alpha]
- set smallhash($k) $newval
- lappend args $k $newval
- }
- r hmset smallhash {*}$args
- } {OK}
- test {HMSET - big hash} {
- set args {}
- foreach {k v} [array get bighash] {
- set newval [randstring 0 8 alpha]
- set bighash($k) $newval
- lappend args $k $newval
- }
- r hmset bighash {*}$args
- } {OK}
- test {HMGET against non existing key and fields} {
- set rv {}
- lappend rv [r hmget doesntexist __123123123__ __456456456__]
- lappend rv [r hmget smallhash __123123123__ __456456456__]
- lappend rv [r hmget bighash __123123123__ __456456456__]
- set _ $rv
- } {{{} {}} {{} {}} {{} {}}}
- test {HMGET against wrong type} {
- r set wrongtype somevalue
- assert_error "*wrong*" {r hmget wrongtype field1 field2}
- }
- test {HMGET - small hash} {
- set keys {}
- set vals {}
- foreach {k v} [array get smallhash] {
- lappend keys $k
- lappend vals $v
- }
- set err {}
- set result [r hmget smallhash {*}$keys]
- if {$vals ne $result} {
- set err "$vals != $result"
- break
- }
- set _ $err
- } {}
- test {HMGET - big hash} {
- set keys {}
- set vals {}
- foreach {k v} [array get bighash] {
- lappend keys $k
- lappend vals $v
- }
- set err {}
- set result [r hmget bighash {*}$keys]
- if {$vals ne $result} {
- set err "$vals != $result"
- break
- }
- set _ $err
- } {}
- test {HKEYS - small hash} {
- lsort [r hkeys smallhash]
- } [lsort [array names smallhash *]]
- test {HKEYS - big hash} {
- lsort [r hkeys bighash]
- } [lsort [array names bighash *]]
- test {HVALS - small hash} {
- set vals {}
- foreach {k v} [array get smallhash] {
- lappend vals $v
- }
- set _ [lsort $vals]
- } [lsort [r hvals smallhash]]
- test {HVALS - big hash} {
- set vals {}
- foreach {k v} [array get bighash] {
- lappend vals $v
- }
- set _ [lsort $vals]
- } [lsort [r hvals bighash]]
- test {HGETALL - small hash} {
- lsort [r hgetall smallhash]
- } [lsort [array get smallhash]]
- test {HGETALL - big hash} {
- lsort [r hgetall bighash]
- } [lsort [array get bighash]]
- test {HDEL and return value} {
- set rv {}
- lappend rv [r hdel smallhash nokey]
- lappend rv [r hdel bighash nokey]
- set k [lindex [array names smallhash *] 0]
- lappend rv [r hdel smallhash $k]
- lappend rv [r hdel smallhash $k]
- lappend rv [r hget smallhash $k]
- unset smallhash($k)
- set k [lindex [array names bighash *] 0]
- lappend rv [r hdel bighash $k]
- lappend rv [r hdel bighash $k]
- lappend rv [r hget bighash $k]
- unset bighash($k)
- set _ $rv
- } {0 0 1 0 {} 1 0 {}}
- test {HDEL - more than a single value} {
- set rv {}
- r del myhash
- r hmset myhash a 1 b 2 c 3
- assert_equal 0 [r hdel myhash x y]
- assert_equal 2 [r hdel myhash a c f]
- r hgetall myhash
- } {b 2}
- test {HDEL - hash becomes empty before deleting all specified fields} {
- r del myhash
- r hmset myhash a 1 b 2 c 3
- assert_equal 3 [r hdel myhash a b c d e]
- assert_equal 0 [r exists myhash]
- }
- test {HEXISTS} {
- set rv {}
- set k [lindex [array names smallhash *] 0]
- lappend rv [r hexists smallhash $k]
- lappend rv [r hexists smallhash nokey]
- set k [lindex [array names bighash *] 0]
- lappend rv [r hexists bighash $k]
- lappend rv [r hexists bighash nokey]
- } {1 0 1 0}
- test {Is a ziplist encoded Hash promoted on big payload?} {
- r hset smallhash foo [string repeat a 1024]
- r debug object smallhash
- } {*hashtable*}
- test {HINCRBY against non existing database key} {
- r del htest
- list [r hincrby htest foo 2]
- } {2}
- test {HINCRBY against non existing hash key} {
- set rv {}
- r hdel smallhash tmp
- r hdel bighash tmp
- lappend rv [r hincrby smallhash tmp 2]
- lappend rv [r hget smallhash tmp]
- lappend rv [r hincrby bighash tmp 2]
- lappend rv [r hget bighash tmp]
- } {2 2 2 2}
- test {HINCRBY against hash key created by hincrby itself} {
- set rv {}
- lappend rv [r hincrby smallhash tmp 3]
- lappend rv [r hget smallhash tmp]
- lappend rv [r hincrby bighash tmp 3]
- lappend rv [r hget bighash tmp]
- } {5 5 5 5}
- test {HINCRBY against hash key originally set with HSET} {
- r hset smallhash tmp 100
- r hset bighash tmp 100
- list [r hincrby smallhash tmp 2] [r hincrby bighash tmp 2]
- } {102 102}
- test {HINCRBY over 32bit value} {
- r hset smallhash tmp 17179869184
- r hset bighash tmp 17179869184
- list [r hincrby smallhash tmp 1] [r hincrby bighash tmp 1]
- } {17179869185 17179869185}
- test {HINCRBY over 32bit value with over 32bit increment} {
- r hset smallhash tmp 17179869184
- r hset bighash tmp 17179869184
- list [r hincrby smallhash tmp 17179869184] [r hincrby bighash tmp 17179869184]
- } {34359738368 34359738368}
- test {HINCRBY fails against hash value with spaces (left)} {
- r hset smallhash str " 11"
- r hset bighash str " 11"
- catch {r hincrby smallhash str 1} smallerr
- catch {r hincrby smallhash str 1} bigerr
- set rv {}
- lappend rv [string match "ERR*not an integer*" $smallerr]
- lappend rv [string match "ERR*not an integer*" $bigerr]
- } {1 1}
- test {HINCRBY fails against hash value with spaces (right)} {
- r hset smallhash str "11 "
- r hset bighash str "11 "
- catch {r hincrby smallhash str 1} smallerr
- catch {r hincrby smallhash str 1} bigerr
- set rv {}
- lappend rv [string match "ERR*not an integer*" $smallerr]
- lappend rv [string match "ERR*not an integer*" $bigerr]
- } {1 1}
- test {HINCRBY can detect overflows} {
- set e {}
- r hset hash n -9223372036854775484
- assert {[r hincrby hash n -1] == -9223372036854775485}
- catch {r hincrby hash n -10000} e
- set e
- } {*overflow*}
- test {HINCRBYFLOAT against non existing database key} {
- r del htest
- list [r hincrbyfloat htest foo 2.5]
- } {2.5}
- test {HINCRBYFLOAT against non existing hash key} {
- set rv {}
- r hdel smallhash tmp
- r hdel bighash tmp
- lappend rv [roundFloat [r hincrbyfloat smallhash tmp 2.5]]
- lappend rv [roundFloat [r hget smallhash tmp]]
- lappend rv [roundFloat [r hincrbyfloat bighash tmp 2.5]]
- lappend rv [roundFloat [r hget bighash tmp]]
- } {2.5 2.5 2.5 2.5}
- test {HINCRBYFLOAT against hash key created by hincrby itself} {
- set rv {}
- lappend rv [roundFloat [r hincrbyfloat smallhash tmp 3.5]]
- lappend rv [roundFloat [r hget smallhash tmp]]
- lappend rv [roundFloat [r hincrbyfloat bighash tmp 3.5]]
- lappend rv [roundFloat [r hget bighash tmp]]
- } {6 6 6 6}
- test {HINCRBYFLOAT against hash key originally set with HSET} {
- r hset smallhash tmp 100
- r hset bighash tmp 100
- list [roundFloat [r hincrbyfloat smallhash tmp 2.5]] \
- [roundFloat [r hincrbyfloat bighash tmp 2.5]]
- } {102.5 102.5}
- test {HINCRBYFLOAT over 32bit value} {
- r hset smallhash tmp 17179869184
- r hset bighash tmp 17179869184
- list [r hincrbyfloat smallhash tmp 1] \
- [r hincrbyfloat bighash tmp 1]
- } {17179869185 17179869185}
- test {HINCRBYFLOAT over 32bit value with over 32bit increment} {
- r hset smallhash tmp 17179869184
- r hset bighash tmp 17179869184
- list [r hincrbyfloat smallhash tmp 17179869184] \
- [r hincrbyfloat bighash tmp 17179869184]
- } {34359738368 34359738368}
- test {HINCRBYFLOAT fails against hash value with spaces (left)} {
- r hset smallhash str " 11"
- r hset bighash str " 11"
- catch {r hincrbyfloat smallhash str 1} smallerr
- catch {r hincrbyfloat smallhash str 1} bigerr
- set rv {}
- lappend rv [string match "ERR*not*float*" $smallerr]
- lappend rv [string match "ERR*not*float*" $bigerr]
- } {1 1}
- test {HINCRBYFLOAT fails against hash value with spaces (right)} {
- r hset smallhash str "11 "
- r hset bighash str "11 "
- catch {r hincrbyfloat smallhash str 1} smallerr
- catch {r hincrbyfloat smallhash str 1} bigerr
- set rv {}
- lappend rv [string match "ERR*not*float*" $smallerr]
- lappend rv [string match "ERR*not*float*" $bigerr]
- } {1 1}
- test {HSTRLEN against the small hash} {
- set err {}
- foreach k [array names smallhash *] {
- if {[string length $smallhash($k)] ne [r hstrlen smallhash $k]} {
- set err "[string length $smallhash($k)] != [r hstrlen smallhash $k]"
- break
- }
- }
- set _ $err
- } {}
- test {HSTRLEN against the big hash} {
- set err {}
- foreach k [array names bighash *] {
- if {[string length $bighash($k)] ne [r hstrlen bighash $k]} {
- set err "[string length $bighash($k)] != [r hstrlen bighash $k]"
- puts "HSTRLEN and logical length mismatch:"
- puts "key: $k"
- puts "Logical content: $bighash($k)"
- puts "Server content: [r hget bighash $k]"
- }
- }
- set _ $err
- } {}
- test {HSTRLEN against non existing field} {
- set rv {}
- lappend rv [r hstrlen smallhash __123123123__]
- lappend rv [r hstrlen bighash __123123123__]
- set _ $rv
- } {0 0}
- test {HSTRLEN corner cases} {
- set vals {
- -9223372036854775808 9223372036854775807 9223372036854775808
- {} 0 -1 x
- }
- foreach v $vals {
- r hmset smallhash field $v
- r hmset bighash field $v
- set len1 [string length $v]
- set len2 [r hstrlen smallhash field]
- set len3 [r hstrlen bighash field]
- assert {$len1 == $len2}
- assert {$len2 == $len3}
- }
- }
- test {Hash ziplist regression test for large keys} {
- r hset hash kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk a
- r hset hash kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk b
- r hget hash kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
- } {b}
- foreach size {10 512} {
- test "Hash fuzzing #1 - $size fields" {
- for {set times 0} {$times < 10} {incr times} {
- catch {unset hash}
- array set hash {}
- r del hash
- # Create
- for {set j 0} {$j < $size} {incr j} {
- set field [randomValue]
- set value [randomValue]
- r hset hash $field $value
- set hash($field) $value
- }
- # Verify
- foreach {k v} [array get hash] {
- assert_equal $v [r hget hash $k]
- }
- assert_equal [array size hash] [r hlen hash]
- }
- }
- test "Hash fuzzing #2 - $size fields" {
- for {set times 0} {$times < 10} {incr times} {
- catch {unset hash}
- array set hash {}
- r del hash
- # Create
- for {set j 0} {$j < $size} {incr j} {
- randpath {
- set field [randomValue]
- set value [randomValue]
- r hset hash $field $value
- set hash($field) $value
- } {
- set field [randomSignedInt 512]
- set value [randomSignedInt 512]
- r hset hash $field $value
- set hash($field) $value
- } {
- randpath {
- set field [randomValue]
- } {
- set field [randomSignedInt 512]
- }
- r hdel hash $field
- unset -nocomplain hash($field)
- }
- }
- # Verify
- foreach {k v} [array get hash] {
- assert_equal $v [r hget hash $k]
- }
- assert_equal [array size hash] [r hlen hash]
- }
- }
- }
- test {Stress test the hash ziplist -> hashtable encoding conversion} {
- r config set hash-max-ziplist-entries 32
- for {set j 0} {$j < 100} {incr j} {
- r del myhash
- for {set i 0} {$i < 64} {incr i} {
- r hset myhash [randomValue] [randomValue]
- }
- assert {[r object encoding myhash] eq {hashtable}}
- }
- }
- # The following test can only be executed if we don't use Valgrind, and if
- # we are using x86_64 architecture, because:
- #
- # 1) Valgrind has floating point limitations, no support for 80 bits math.
- # 2) Other archs may have the same limits.
- #
- # 1.23 cannot be represented correctly with 64 bit doubles, so we skip
- # the test, since we are only testing pretty printing here and is not
- # a bug if the program outputs things like 1.299999...
- if {!$::valgrind && [string match *x86_64* [exec uname -a]]} {
- test {Test HINCRBYFLOAT for correct float representation (issue #2846)} {
- r del myhash
- assert {[r hincrbyfloat myhash float 1.23] eq {1.23}}
- assert {[r hincrbyfloat myhash float 0.77] eq {2}}
- assert {[r hincrbyfloat myhash float -0.1] eq {1.9}}
- }
- }
- }
|