Merge "add lbzip2 output processor for exports"
[lhc/web/wiklou.git] / includes / libs / objectcache / WinCacheBagOStuff.php
index 9c6c907..0ca3e4a 100644 (file)
  */
 class WinCacheBagOStuff extends BagOStuff {
        protected function doGet( $key, $flags = 0 ) {
-               $val = wincache_ucache_get( $key );
-               if ( is_string( $val ) ) {
-                       $val = unserialize( $val );
+               $blob = wincache_ucache_get( $key );
+
+               return is_string( $blob ) ? unserialize( $blob ) : false;
+       }
+
+       protected function getWithToken( $key, &$casToken, $flags = 0 ) {
+               $casToken = null;
+
+               $blob = wincache_ucache_get( $key );
+               if ( !is_string( $blob ) ) {
+                       return false;
+               }
+
+               $value = unserialize( $blob );
+               if ( $value === false ) {
+                       return false;
+               }
+
+               $casToken = $blob; // don't bother hashing this
+
+               return $value;
+       }
+
+       protected function cas( $casToken, $key, $value, $exptime = 0, $flags = 0 ) {
+               if ( !wincache_lock( $key ) ) { // optimize with FIFO lock
+                       return false;
+               }
+
+               $curCasToken = null; // passed by reference
+               $this->getWithToken( $key, $curCasToken, self::READ_LATEST );
+               if ( $casToken === $curCasToken ) {
+                       $success = $this->set( $key, $value, $exptime, $flags );
+               } else {
+                       $this->logger->info(
+                               __METHOD__ . ' failed due to race condition for {key}.',
+                               [ 'key' => $key ]
+                       );
+
+                       $success = false; // mismatched or failed
                }
 
-               return $val;
+               wincache_unlock( $key );
+
+               return $success;
        }
 
        public function set( $key, $value, $expire = 0, $flags = 0 ) {
                $result = wincache_ucache_set( $key, serialize( $value ), $expire );
 
-               /* wincache_ucache_set returns an empty array on success if $value
-                * was an array, bool otherwise */
-               return ( is_array( $result ) && $result === [] ) || $result;
+               return ( $result === [] || $result === true );
        }
 
-       public function delete( $key ) {
+       public function add( $key, $value, $exptime = 0, $flags = 0 ) {
+               $result = wincache_ucache_add( $key, serialize( $value ), $exptime );
+
+               return ( $result === [] || $result === true );
+       }
+
+       public function delete( $key, $flags = 0 ) {
                wincache_ucache_delete( $key );
 
                return true;
        }
 
        public function merge( $key, callable $callback, $exptime = 0, $attempts = 10, $flags = 0 ) {
-               if ( wincache_lock( $key ) ) { // optimize with FIFO lock
-                       $ok = $this->mergeViaLock( $key, $callback, $exptime, $attempts, $flags );
-                       wincache_unlock( $key );
-               } else {
-                       $ok = false;
-               }
-
-               return $ok;
+               return $this->mergeViaCas( $key, $callback, $exptime, $attempts, $flags );
        }
 
        /**
@@ -97,4 +132,29 @@ class WinCacheBagOStuff extends BagOStuff {
 
                return $keyspace . ':' . implode( ':', $args );
        }
+
+       /**
+        * Increase stored value of $key by $value while preserving its original TTL
+        * @param string $key Key to increase
+        * @param int $value Value to add to $key (Default 1)
+        * @return int|bool New value or false on failure
+        */
+       public function incr( $key, $value = 1 ) {
+               if ( !wincache_lock( $key ) ) { // optimize with FIFO lock
+                       return false;
+               }
+
+               $n = $this->doGet( $key );
+               if ( $this->isInteger( $n ) ) {
+                       $n = max( $n + (int)$value, 0 );
+                       $oldTTL = wincache_ucache_info( false, $key )["ucache_entries"][1]["ttl_seconds"];
+                       $this->set( $key, $n, $oldTTL );
+               } else {
+                       $n = false;
+               }
+
+               wincache_unlock( $key );
+
+               return $n;
+       }
 }