Ehcache more like mehcache
[lhc/web/wiklou.git] / includes / objectcache / DBABagOStuff.php
index 36ced49..a81b5c5 100644 (file)
@@ -111,9 +111,10 @@ class DBABagOStuff extends BagOStuff {
 
        /**
         * @param $key string
+        * @param $casToken[optional] mixed
         * @return mixed
         */
-       public function get( $key ) {
+       public function get( $key, &$casToken = null ) {
                wfProfileIn( __METHOD__ );
                wfDebug( __METHOD__ . "($key)\n" );
 
@@ -124,6 +125,7 @@ class DBABagOStuff extends BagOStuff {
                }
 
                $val = dba_fetch( $key, $handle );
+               $casToken = $val;
                list( $val, $expiry ) = $this->decode( $val );
 
                # Must close ASAP because locks are held
@@ -139,6 +141,7 @@ class DBABagOStuff extends BagOStuff {
                }
 
                wfProfileOut( __METHOD__ );
+
                return $val;
        }
 
@@ -167,6 +170,41 @@ class DBABagOStuff extends BagOStuff {
                return $ret;
        }
 
+       /**
+        * @param $casToken mixed
+        * @param $key string
+        * @param $value mixed
+        * @param $exptime int
+        * @return bool
+        */
+       public function cas( $casToken, $key, $value, $exptime = 0 ) {
+               wfProfileIn( __METHOD__ );
+               wfDebug( __METHOD__ . "($key)\n" );
+
+               $blob = $this->encode( $value, $exptime );
+
+               $handle = $this->getWriter();
+               if ( !$handle ) {
+                       wfProfileOut( __METHOD__ );
+                       return false;
+               }
+
+               // DBA is locked to any other write connection, so we can safely
+               // compare the current & previous value before saving new value
+               $val = dba_fetch( $key, $handle );
+               if ( $casToken !== $val ) {
+                       dba_close( $handle );
+                       wfProfileOut( __METHOD__ );
+                       return false;
+               }
+
+               $ret = dba_replace( $key, $blob, $handle );
+               dba_close( $handle );
+
+               wfProfileOut( __METHOD__ );
+               return $ret;
+       }
+
        /**
         * @param $key string
         * @param $time int
@@ -211,7 +249,7 @@ class DBABagOStuff extends BagOStuff {
 
                # Insert failed, check to see if it failed due to an expired key
                if ( !$ret ) {
-                       list( $value, $expiry ) = $this->decode( dba_fetch( $key, $handle ) );
+                       list( , $expiry ) = $this->decode( dba_fetch( $key, $handle ) );
 
                        if ( $expiry && $expiry < time() ) {
                                # Yes expired, delete and try again
@@ -264,23 +302,4 @@ class DBABagOStuff extends BagOStuff {
 
                return ( $value === false ) ? false : (int)$value;
        }
-
-       function keys() {
-               $reader = $this->getReader();
-               $k1 = dba_firstkey( $reader );
-
-               if ( !$k1 ) {
-                       return array();
-               }
-
-               $result[] = $k1;
-
-               $key = dba_nextkey( $reader );
-               while ( $key ) {
-                       $result[] = $key;
-                       $key = dba_nextkey( $reader );
-               }
-
-               return $result;
-       }
 }