@@ -54,18 +54,19 @@ public function getCache() {
5454
5555 public function get ($ key ) {
5656 $ result = $ this ->getCache ()->get ($ this ->getPrefix () . $ key );
57- if ($ result === false && ! $ this -> getCache ()-> exists ( $ this -> getPrefix () . $ key ) ) {
57+ if ($ result === false ) {
5858 return null ;
59- } else {
60- return json_decode ($ result , true );
6159 }
60+
61+ return self ::decodeValue ($ result );
6262 }
6363
6464 public function set ($ key , $ value , $ ttl = 0 ) {
65+ $ value = self ::encodeValue ($ value );
6566 if ($ ttl > 0 ) {
66- return $ this ->getCache ()->setex ($ this ->getPrefix () . $ key , $ ttl , json_encode ( $ value) );
67+ return $ this ->getCache ()->setex ($ this ->getPrefix () . $ key , $ ttl , $ value );
6768 } else {
68- return $ this ->getCache ()->set ($ this ->getPrefix () . $ key , json_encode ( $ value) );
69+ return $ this ->getCache ()->set ($ this ->getPrefix () . $ key , $ value );
6970 }
7071 }
7172
@@ -82,6 +83,7 @@ public function remove($key) {
8283 }
8384
8485 public function clear ($ prefix = '' ) {
86+ // TODO: this is slow and would fail with Redis cluster
8587 $ prefix = $ this ->getPrefix () . $ prefix . '* ' ;
8688 $ keys = $ this ->getCache ()->keys ($ prefix );
8789 $ deleted = $ this ->getCache ()->del ($ keys );
@@ -98,17 +100,14 @@ public function clear($prefix = '') {
98100 * @return bool
99101 */
100102 public function add ($ key , $ value , $ ttl = 0 ) {
101- // don't encode ints for inc/dec
102- if (!is_int ($ value )) {
103- $ value = json_encode ($ value );
104- }
103+ $ value = self ::encodeValue ($ value );
105104
106105 $ args = ['nx ' ];
107106 if ($ ttl !== 0 && is_int ($ ttl )) {
108107 $ args ['ex ' ] = $ ttl ;
109108 }
110109
111- return $ this ->getCache ()->set ($ this ->getPrefix () . $ key , ( string ) $ value , $ args );
110+ return $ this ->getCache ()->set ($ this ->getPrefix () . $ key , $ value , $ args );
112111 }
113112
114113 /**
@@ -130,10 +129,17 @@ public function inc($key, $step = 1) {
130129 * @return int | bool
131130 */
132131 public function dec ($ key , $ step = 1 ) {
133- if (!$ this ->hasKey ($ key )) {
134- return false ;
135- }
136- return $ this ->getCache ()->decrBy ($ this ->getPrefix () . $ key , $ step );
132+ $ res = $ this ->getCache ()->eval (
133+ 'if redis.call("exists", KEYS[1]) == 1 then
134+ return redis.call("decrby", KEYS[1], ARGV[1])
135+ else
136+ return "NEX"
137+ end ' ,
138+ [$ this ->getPrefix () . $ key , $ step ],
139+ 1
140+ );
141+
142+ return ($ res === 'NEX ' ) ? false : $ res ;
137143 }
138144
139145 /**
@@ -145,18 +151,19 @@ public function dec($key, $step = 1) {
145151 * @return bool
146152 */
147153 public function cas ($ key , $ old , $ new ) {
148- if (!is_int ($ new )) {
149- $ new = json_encode ($ new );
150- }
151- $ this ->getCache ()->watch ($ this ->getPrefix () . $ key );
152- if ($ this ->get ($ key ) === $ old ) {
153- $ result = $ this ->getCache ()->multi ()
154- ->set ($ this ->getPrefix () . $ key , $ new )
155- ->exec ();
156- return $ result !== false ;
157- }
158- $ this ->getCache ()->unwatch ();
159- return false ;
154+ $ old = self ::encodeValue ($ old );
155+ $ new = self ::encodeValue ($ new );
156+
157+ return $ this ->getCache ()->eval (
158+ 'if redis.call("get", KEYS[1]) == ARGV[1] then
159+ redis.call("set", KEYS[1], ARGV[2])
160+ return 1
161+ else
162+ return 0
163+ end ' ,
164+ [$ this ->getPrefix () . $ key , $ old , $ new ],
165+ 1
166+ ) > 0 ;
160167 }
161168
162169 /**
@@ -167,15 +174,17 @@ public function cas($key, $old, $new) {
167174 * @return bool
168175 */
169176 public function cad ($ key , $ old ) {
170- $ this ->getCache ()->watch ($ this ->getPrefix () . $ key );
171- if ($ this ->get ($ key ) === $ old ) {
172- $ result = $ this ->getCache ()->multi ()
173- ->unlink ($ this ->getPrefix () . $ key )
174- ->exec ();
175- return $ result !== false ;
176- }
177- $ this ->getCache ()->unwatch ();
178- return false ;
177+ $ old = self ::encodeValue ($ old );
178+
179+ return $ this ->getCache ()->eval (
180+ 'if redis.call("get", KEYS[1]) == ARGV[1] then
181+ return redis.call("del", KEYS[1])
182+ else
183+ return 0
184+ end ' ,
185+ [$ this ->getPrefix () . $ key , $ old ],
186+ 1
187+ ) > 0 ;
179188 }
180189
181190 public function setTTL ($ key , $ ttl ) {
@@ -185,4 +194,12 @@ public function setTTL($key, $ttl) {
185194 public static function isAvailable (): bool {
186195 return \OC ::$ server ->getGetRedisFactory ()->isAvailable ();
187196 }
197+
198+ protected static function encodeValue ($ value ) {
199+ return is_int ($ value ) ? (string ) $ value : json_encode ($ value );
200+ }
201+
202+ protected static function decodeValue ($ value ) {
203+ return is_numeric ($ value ) ? (int ) $ value : json_decode ($ value , true );
204+ }
188205}
0 commit comments