File: hash.tcl

package info (click to toggle)
redis 5%3A8.0.2-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 22,304 kB
  • sloc: ansic: 216,903; tcl: 51,562; sh: 4,625; perl: 4,214; cpp: 3,568; python: 2,954; makefile: 2,055; ruby: 639; javascript: 30; csh: 7
file content (144 lines) | stat: -rw-r--r-- 6,260 bytes parent folder | download
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
set testmodule [file normalize tests/modules/hash.so]

start_server {tags {"modules"}} {
    r module load $testmodule

    test {Module hash set} {
        r set k mystring
        assert_error "WRONGTYPE*" {r hash.set k "" hello world}
        r del k
        # "" = count updates and deletes of existing fields only
        assert_equal 0 [r hash.set k "" squirrel yes]
        # "a" = COUNT_ALL = count inserted, modified and deleted fields
        assert_equal 2 [r hash.set k "a" banana no sushi whynot]
        # "n" = NX = only add fields not already existing in the hash
        # "x" = XX = only replace the value for existing fields
        assert_equal 0 [r hash.set k "n" squirrel hoho what nothing]
        assert_equal 1 [r hash.set k "na" squirrel hoho something nice]
        assert_equal 0 [r hash.set k "xa" new stuff not inserted]
        assert_equal 1 [r hash.set k "x" squirrel ofcourse]
        assert_equal 1 [r hash.set k "" sushi :delete: none :delete:]
        r hgetall k
    } {squirrel ofcourse banana no what nothing something nice}

    test {Module hash - set (override) NX expired field successfully} {
        r debug set-active-expire 0
        r del H1 H2
        r hash.set H1 "n" f1 v1
        r hpexpire H1 1 FIELDS 1 f1
        r hash.set H2 "n" f1 v1 f2 v2
        r hpexpire H2 1 FIELDS 1 f1
        after 5
        assert_equal 0 [r hash.set H1 "n" f1 xx]
        assert_equal "f1 xx" [r hgetall H1]
        assert_equal 0 [r hash.set H2 "n" f1 yy]
        assert_equal "f1 f2 v2 yy" [lsort [r hgetall H2]]
        r debug set-active-expire 1
    } {OK} {needs:debug}

    test {Module hash - set XX of expired field gets failed as expected} {
        r debug set-active-expire 0
        r del H1 H2
        r hash.set H1 "n" f1 v1
        r hpexpire H1 1 FIELDS 1 f1
        r hash.set H2 "n" f1 v1 f2 v2
        r hpexpire H2 1 FIELDS 1 f1
        after 5

        # expected to fail on condition XX. hgetall should return empty list
        r hash.set H1 "x" f1 xx
        assert_equal "" [lsort [r hgetall H1]]
        # But expired field was not lazy deleted
        assert_equal 1 [r hlen H1]

        # expected to fail on condition XX. hgetall should return list without expired f1
        r hash.set H2 "x" f1 yy
        assert_equal "f2 v2" [lsort [r hgetall H2]]
        # But expired field was not lazy deleted
        assert_equal 2 [r hlen H2]

        r debug set-active-expire 1
    } {OK} {needs:debug}

    test {Module hash - test open key with REDISMODULE_OPEN_KEY_ACCESS_EXPIRED to scan expired fields} {
        r debug set-active-expire 0
        r del H1
        r hash.set H1 "n" f1 v1 f2 v2 f3 v3
        r hpexpire H1 1 FIELDS 2 f1 f2
        after 10
        # Scan expired fields with flag REDISMODULE_OPEN_KEY_ACCESS_EXPIRED
        assert_equal "f1 f2 f3 v1 v2 v3" [lsort [r hash.hscan_expired H1]]
        # Get expired field with flag REDISMODULE_OPEN_KEY_ACCESS_EXPIRED
        assert_equal {v1} [r hash.hget_expired H1 f1]
        # Verify we can get the TTL of the expired field as well
        set now [expr [clock seconds]*1000]
        assert_range [r hash.hget_expire H1 f2] [expr {$now-1000}] [expr {$now+1000}]        
        # Verify key doesn't exist on normal access without the flag
        assert_equal 0 [r hexists H1 f1]
        assert_equal 0 [r hexists H1 f2]
        # Scan again expired fields with flag REDISMODULE_OPEN_KEY_ACCESS_EXPIRED
        assert_equal "f3 v3" [lsort [r hash.hscan_expired H1]]
        r debug set-active-expire 1
    }

    test {Module hash - test open key with REDISMODULE_OPEN_KEY_ACCESS_EXPIRED to scan expired key} {
        r debug set-active-expire 0
        r del H1
        r hash.set H1 "n" f1 v1 f2 v2 f3 v3
        r pexpire H1 5
        after 10
        # Scan expired fields with flag REDISMODULE_OPEN_KEY_ACCESS_EXPIRED
        assert_equal "f1 f2 f3 v1 v2 v3" [lsort [r hash.hscan_expired H1]]
        # Get expired field with flag REDISMODULE_OPEN_KEY_ACCESS_EXPIRED
        assert_equal {v1} [r hash.hget_expired H1 f1]
        # Verify key doesn't exist on normal access without the flag
        assert_equal 0 [r exists H1]
        r debug set-active-expire 1
    }
    
    test {Module hash - Read field expiration time} {
        r del H1
        r hash.set H1 "n" f1 v1 f2 v2 f3 v3 f4 v4
        r hexpire H1 10   FIELDS 1 f1
        r hexpire H1 100  FIELDS 1 f2
        r hexpire H1 1000 FIELDS 1 f3        
        
        # Validate that the expiration times for fields f1, f2, and f3 are correct
        set nowMsec [expr [clock seconds]*1000]
        assert_range [r hash.hget_expire H1 f1] [expr {$nowMsec+9000}] [expr {$nowMsec+11000}]
        assert_range [r hash.hget_expire H1 f2] [expr {$nowMsec+90000}] [expr {$nowMsec+110000}]
        assert_range [r hash.hget_expire H1 f3] [expr {$nowMsec+900000}] [expr {$nowMsec+1100000}]
        
        # Assert that field f4 and f5_not_exist have no expiration (should return -1)
        assert_equal [r hash.hget_expire H1 f4] -1  
        assert_equal [r hash.hget_expire H1 f5_not_exist] -1
        
        # Assert that variadic version of hget_expire works as well
        assert_equal [r hash.hget_two_expire H1 f1 f2] [list [r hash.hget_expire H1 f1] [r hash.hget_expire H1 f2]]        
    }
    
    test {Module hash - Read minimum expiration time} {
        r del H1
        r hash.set H1 "n" f1 v1 f2 v2 f3 v3 f4 v4
        r hexpire H1 100   FIELDS 1 f1
        r hexpire H1 10    FIELDS 1 f2
        r hexpire H1 1000  FIELDS 1 f3        
        
        # Validate that the minimum expiration time is correct
        set nowMsec [expr [clock seconds]*1000]
        assert_range [r hash.hget_min_expire H1] [expr {$nowMsec+9000}] [expr {$nowMsec+11000}]
        assert_equal [r hash.hget_min_expire H1] [r hash.hget_expire H1 f2]
        
        # Assert error if key not found
        assert_error {*key not found*} {r hash.hget_min_expire non_exist_hash}
        
        # Assert return -1 if no expiration (=REDISMODULE_NO_EXPIRE)
        r del H2
        r hash.set H2 "n" f1 v1
        assert_equal [r hash.hget_min_expire H2] -1
    }

    test "Unload the module - hash" {
        assert_equal {OK} [r module unload hash]
    }
}