Make room for preloadFileStat() call in FileBackend::doOperationsInternal
authorAaron Schulz <aschulz@wikimedia.org>
Sat, 19 Apr 2014 00:02:19 +0000 (17:02 -0700)
committerAaron Schulz <aschulz@wikimedia.org>
Sat, 19 Apr 2014 00:02:19 +0000 (17:02 -0700)
Change-Id: I60f71155abcf7f69423639b10ec301ac192df728

includes/filebackend/FileBackendStore.php
includes/libs/ProcessCacheLRU.php

index 2fd1bf6..e0b5224 100644 (file)
@@ -1102,6 +1102,10 @@ abstract class FileBackendStore extends FileBackend {
                        $paths = array_merge( $paths, $op->storagePathsRead() );
                        $paths = array_merge( $paths, $op->storagePathsChanged() );
                }
+
+               // Enlarge the cache to fit the stat entries of these files
+               $this->cheapCache->resize( max( 2 * count( $paths ), self::CACHE_CHEAP_SIZE ) );
+
                // Load from the persistent container caches
                $this->primeContainerCache( $paths );
                // Get the latest stat info for all the files (having locked them)
@@ -1115,6 +1119,9 @@ abstract class FileBackendStore extends FileBackend {
                $status->merge( $subStatus );
                $status->success = $subStatus->success; // not done in merge()
 
+               // Shrink the stat cache back to normal size
+               $this->cheapCache->resize( self::CACHE_CHEAP_SIZE );
+
                return $status;
        }
 
index f2d9f42..f988207 100644 (file)
@@ -38,10 +38,7 @@ class ProcessCacheLRU {
         * @throws UnexpectedValueException When $maxCacheKeys is not an int or =< 0.
         */
        public function __construct( $maxKeys ) {
-               if ( !is_int( $maxKeys ) || $maxKeys < 1 ) {
-                       throw new UnexpectedValueException( __METHOD__ . " must be given an integer >= 1" );
-               }
-               $this->maxCacheKeys = $maxKeys;
+               $this->resize( $maxKeys );
        }
 
        /**
@@ -119,6 +116,25 @@ class ProcessCacheLRU {
                }
        }
 
+       /**
+        * Resize the maximum number of cache entries, removing older entries as needed
+        *
+        * @param $maxKeys integer
+        * @return void
+        */
+       public function resize( $maxKeys ) {
+               if ( !is_int( $maxKeys ) || $maxKeys < 1 ) {
+                       throw new UnexpectedValueException( __METHOD__ . " must be given an integer >= 1" );
+               }
+               $this->maxCacheKeys = $maxKeys;
+               while ( count( $this->cache ) > $this->maxCacheKeys ) {
+                       reset( $this->cache );
+                       $evictKey = key( $this->cache );
+                       unset( $this->cache[$evictKey] );
+                       unset( $this->cacheTimes[$evictKey] );
+               }
+       }
+
        /**
         * Push an entry to the top of the cache
         *