namespace = $namespace; $this->cache = $cache; // It is only used internally therefore no injection required as it improves // performance on long lists as seen in #1 $this->internalCache = CacheFactory::getInstance()->newFixedInMemoryLruCache( 500 ); } /** * @since 1.0 * * @return boolean */ public function canUse() { return $this->usageState; } /** * Specifies whether the instance can be generally used or not * * @since 1.0 * * @param boolean $usageState */ public function setUsageState( $usageState ) { $this->usageState = (bool)$usageState; } /** * Specifies the expiry / time to live for stored containers in seconds * * @since 1.0 * * @param integer $expiry */ public function setExpiryInSeconds( $expiry ) { $this->expiry = $expiry; } /** * @since 1.0 * * @param string $prefix */ public function setNamespacePrefix( $prefix ) { $this->namespacePrefix = $prefix; } /** * @since 1.0 * * @param string $id * * @return boolean */ public function exists( $id ) { return $this->cache->contains( $this->getKey( $id ) ); } /** * @since 1.0 * * @return array */ public function getStats() { return $this->cache->getStats() + array( 'internalCache' => $this->internalCache->getStats() ); } /** * @since 1.0 * * @param string $id * * @return Container */ public function read( $id ) { $id = $this->getKey( $id ); // If possible use the raw data from the internal cache // without unserialization if ( $this->internalCache->contains( $id ) ) { $data = $this->internalCache->fetch( $id ); } elseif ( $this->cache->contains( $id ) ) { $data = unserialize( $this->cache->fetch( $id ) ); $this->internalCache->save( $id, $data ); } else { $data = array(); } $container = new Container( $id, (array)$data ); $container->setExpiryInSeconds( $this->expiry ); return $container; } /** * @since 1.0 * * @param Container $container */ public function save( Container $container ) { $this->internalCache->save( $container->getId(), $container->getData(), $container->getExpiry() ); $this->cache->save( $container->getId(), serialize( $container->getData() ), $container->getExpiry() ); unset( $container ); } /** * @since 1.0 * * @param string $id */ public function delete( $id ) { $container = $this->read( $id ); foreach ( $container->getLinkedList() as $lid ) { $this->cache->delete( $this->getKey( $lid ) ); } $this->cache->delete( $this->getKey( $id ) ); $this->internalCache->delete( $this->getKey( $id ) ); } /** * @since 1.0 */ public function drop() { // After using the internal list for several production runs it seems // difficult to keep track of ids especially when using long lists and // not to increase overhead which can easily produced by 50K+ entries // which would require to split the internal list // // Using an appropriate expiry seems more efficient } private function getKey( $id ) { if ( !is_string( $id ) ) { throw new InvalidArgumentException( "Expected the id to be a string" ); } return $this->namespacePrefix . ':' . $this->namespace . ':' . $id; } }