/** * Removes items from the cache by conditions & garbage collector. * @param array conditions * @return void */ public function clean(array $conditions) { if (!empty($conditions[Cache::ALL])) { $this->memcache->flush(); } elseif ($this->journal) { foreach ($this->journal->clean($conditions) as $entry) { $this->memcache->delete($entry, 0); } } }
/** * Removes items from the cache by conditions & garbage collector. * @param array conditions * @return void */ public function clean(array $conds) { $all = !empty($conds[Cache::ALL]); $collector = empty($conds); // cleaning using file iterator if ($all || $collector) { $now = time(); foreach (Nette\Utils\Finder::find('*')->from($this->dir)->childFirst() as $entry) { $path = (string) $entry; if ($entry->isDir()) { // collector: remove empty dirs @rmdir($path); // @ - removing dirs is not necessary continue; } if ($all) { $this->delete($path); } else { // collector $meta = $this->readMetaAndLock($path, LOCK_SH); if (!$meta) { continue; } if (!empty($meta[self::META_EXPIRE]) && $meta[self::META_EXPIRE] < $now) { $this->delete($path, $meta[self::HANDLE]); continue; } flock($meta[self::HANDLE], LOCK_UN); fclose($meta[self::HANDLE]); } } if ($this->journal) { $this->journal->clean($conds); } return; } // cleaning using journal if ($this->journal) { foreach ($this->journal->clean($conds) as $file) { $this->delete($file); } } }
/** * Removes items from the cache by conditions & garbage collector. * * @param array $conds * * @return void */ public function clean(array $conds) { // cleaning using file iterator if (!empty($conds[Cache::ALL])) { if ($keys = $this->client->send('keys', [self::NS_NETTE . ':*'])) { $this->client->send('del', $keys); } if ($this->journal) { $this->journal->clean($conds); } return; } // cleaning using journal if ($this->journal) { if ($keys = $this->journal->clean($conds, $this)) { $this->client->send('del', $keys); } } }
/** * Writes item into the cache. * * @param string key * @param mixed data * @param array dependencies * * @return void */ public function write($key, $data, array $dp) { $meta = array(self::META_TIME => microtime()); if (isset($dp[Cache::EXPIRATION])) { if (empty($dp[Cache::SLIDING])) { $meta[self::META_EXPIRE] = $dp[Cache::EXPIRATION] + time(); // absolute time } else { $meta[self::META_DELTA] = (int) $dp[Cache::EXPIRATION]; // sliding time } } if (isset($dp[Cache::ITEMS])) { foreach ((array) $dp[Cache::ITEMS] as $item) { $depFile = $this->getCacheFile($item); $m = $this->readMetaAndLock($depFile, LOCK_SH); $meta[self::META_ITEMS][$depFile] = $m[self::META_TIME]; // may be NULL unset($m); } } if (isset($dp[Cache::CALLBACKS])) { $meta[self::META_CALLBACKS] = $dp[Cache::CALLBACKS]; } if (!isset($this->locks[$key])) { $this->lock($key); if (!isset($this->locks[$key])) { return; } } $handle = $this->locks[$key]; unset($this->locks[$key]); $cacheFile = $this->getCacheFile($key); if (isset($dp[Cache::TAGS]) || isset($dp[Cache::PRIORITY])) { if (!$this->journal) { throw new Nette\InvalidStateException('CacheJournal has not been provided.'); } $this->journal->write($cacheFile, $dp); } ftruncate($handle, 0); if (!is_string($data)) { $data = serialize($data); $meta[self::META_SERIALIZED] = true; } $head = serialize($meta) . '?>'; $head = '<?php //netteCache[01]' . str_pad((string) strlen($head), 6, '0', STR_PAD_LEFT) . $head; $headLen = strlen($head); $dataLen = strlen($data); do { if (fwrite($handle, str_repeat("", $headLen), $headLen) !== $headLen) { break; } if (fwrite($handle, $data, $dataLen) !== $dataLen) { break; } fseek($handle, 0); if (fwrite($handle, $head, $headLen) !== $headLen) { break; } flock($handle, LOCK_UN); fclose($handle); return; } while (false); $this->delete($cacheFile, $handle); }