Upgrade to KH 3.1.3.1

This commit is contained in:
Deon George
2011-05-13 16:00:25 +10:00
parent 8013aadc4c
commit 6d256839fc
675 changed files with 22771 additions and 24111 deletions

View File

@@ -15,6 +15,7 @@ Currently this module supports the following cache methods.
5. SQLite (Supports tags)
6. File
7. Xcache
8. Wincache
Planned support
---------------

View File

@@ -0,0 +1,3 @@
<?php defined('SYSPATH') or die('No direct script access.');
class Cache_Wincache extends Kohana_Cache_Wincache {}

View File

@@ -67,8 +67,8 @@
* * Kohana 3.0.x
* * PHP 5.2.4 or greater
*
* @package Kohana
* @category Cache
* @package Kohana/Cache
* @category Base
* @version 2.0
* @author Kohana Team
* @copyright (c) 2009-2010 Kohana Team
@@ -138,7 +138,7 @@ abstract class Kohana_Cache {
}
/**
* @var Kohana_Config
* @var Config
*/
protected $_config;
@@ -253,4 +253,4 @@ abstract class Kohana_Cache {
return str_replace(array('/', '\\', ' '), '_', $id);
}
}
// End Kohana_Cache
// End Kohana_Cache

View File

@@ -30,8 +30,8 @@
* * PHP 5.2.4 or greater
* * APC PHP extension
*
* @package Kohana
* @category Cache
* @package Kohana/Cache
* @category Base
* @author Kohana Team
* @copyright (c) 2009-2010 Kohana Team
* @license http://kohanaphp.com/license
@@ -71,7 +71,9 @@ class Kohana_Cache_Apc extends Cache {
*/
public function get($id, $default = NULL)
{
return (($data = apc_fetch($this->_sanitize_id($id))) === FALSE) ? $default : $data;
$data = apc_fetch($this->_sanitize_id($id), $success);
return $success ? $data : $default;
}
/**
@@ -130,4 +132,4 @@ class Kohana_Cache_Apc extends Cache {
{
return apc_clear_cache('user');
}
}
}

View File

@@ -30,8 +30,8 @@
* * PHP 5.2.4 or greater
* * Eaccelerator PHP extension
*
* @package Kohana
* @category Cache
* @package Kohana/Cache
* @category Base
* @author Kohana Team
* @copyright (c) 2009-2010 Kohana Team
* @license http://kohanaphp.com/license
@@ -130,4 +130,4 @@ class Kohana_Cache_Eaccelerator extends Cache {
{
return eaccelerator_clean();
}
}
}

View File

@@ -1,3 +1,11 @@
<?php defined('SYSPATH') or die('No direct script access.');
class Kohana_Cache_Exception extends Kohana_Exception {}
/**
* Kohana Cache Exception
*
* @package Kohana/Cache
* @category Base
* @author Kohana Team
* @copyright (c) 2009-2010 Kohana Team
* @license http://kohanaphp.com/license
*/
class Kohana_Cache_Exception extends Kohana_Exception {}

View File

@@ -32,20 +32,14 @@
* * Kohana 3.0.x
* * PHP 5.2.4 or greater
*
* @package Kohana
* @category Cache
* @package Kohana/Cache
* @category Base
* @author Kohana Team
* @copyright (c) 2009-2010 Kohana Team
* @license http://kohanaphp.com/license
*/
class Kohana_Cache_File extends Cache implements Kohana_Cache_GarbageCollect {
// !!! NOTICE !!!
// THIS CONSTANT IS USED BY THE FILE CACHE CLASS
// INTERNALLY. USE THE CONFIGURATION FILE TO
// REDEFINE THE CACHE DIRECTORY.
const CACHE_DIR = 'cache/.kohana_cache';
/**
* Creates a hashed filename based on the string. This is used
* to create shorter unique IDs for each cache filename.
@@ -80,17 +74,18 @@ class Kohana_Cache_File extends Cache implements Kohana_Cache_GarbageCollect {
try
{
$directory = Arr::get($this->_config, 'cache_dir', APPPATH.Cache_File::CACHE_DIR);
$this->_cache_dir = new RecursiveDirectoryIterator($directory);
$directory = Arr::get($this->_config, 'cache_dir', Kohana::$cache_dir);
$this->_cache_dir = new SplFileInfo($directory);
}
// PHP < 5.3 exception handle
catch (ErrorException $e)
{
$this->_cache_dir = $this->_make_directory($directory, 0777, TRUE);
}
// PHP >= 5.3 exception handle
catch (UnexpectedValueException $e)
{
if ( ! mkdir($directory, 0777, TRUE))
{
throw new Kohana_Cache_Exception('Failed to create the defined cache directory : :directory', array(':directory' => $directory));
}
chmod($directory, 0777);
$this->_cache_dir = new RecursiveDirectoryIterator($directory);
$this->_cache_dir = $this->_make_directory($directory, 0777, TRUE);
}
// If the defined directory is a file, get outta here
@@ -138,7 +133,7 @@ class Kohana_Cache_File extends Cache implements Kohana_Cache_GarbageCollect {
$file = new SplFileInfo($directory.$filename);
// If file does not exist
if ( ! $file->getRealPath())
if ( ! $file->isFile())
{
// Return default value
return $default;
@@ -233,7 +228,7 @@ class Kohana_Cache_File extends Cache implements Kohana_Cache_GarbageCollect {
$type = gettype($data);
// Serialize the data
$data = json_encode((object) array(
$data = json_encode( (object) array(
'payload' => ($type === 'string') ? $data : serialize($data),
'expiry' => time() + $lifetime,
'type' => $type
@@ -366,7 +361,7 @@ class Kohana_Cache_File extends Cache implements Kohana_Cache_GarbageCollect {
}
}
// Else, is directory
else if ($file->isDir())
elseif ($file->isDir())
{
// Create new DirectoryIterator
$files = new DirectoryIterator($file->getPathname());
@@ -378,7 +373,7 @@ class Kohana_Cache_File extends Cache implements Kohana_Cache_GarbageCollect {
$name = $files->getFilename();
// If the name is not a dot
if ($name != '.' and $name != '..')
if ($name != '.' AND $name != '..' AND substr($file->getFilename(), 0, 1) == '.')
{
// Create new file resource
$fp = new SplFileInfo($files->getRealPath());
@@ -442,4 +437,27 @@ class Kohana_Cache_File extends Cache implements Kohana_Cache_GarbageCollect {
{
return $this->_cache_dir->getRealPath().DIRECTORY_SEPARATOR.$filename[0].$filename[1].DIRECTORY_SEPARATOR;
}
/**
* Makes the cache directory if it doesn't exist. Simply a wrapper for
* `mkdir` to ensure DRY principles
*
* @see http://php.net/manual/en/function.mkdir.php
* @param string directory
* @param string mode
* @param string recursive
* @param string context
* @return SplFileInfo
* @throws Kohana_Cache_Exception
*/
protected function _make_directory($directory, $mode = 0777, $recursive = FALSE, $context = NULL)
{
if ( ! mkdir($directory, $mode, $recursive, $context))
{
throw new Kohana_Cache_Exception('Failed to create the defined cache directory : :directory', array(':directory' => $directory));
}
chmod($directory, $mode);
return new SplFileInfo($directory);;
}
}

View File

@@ -4,8 +4,8 @@
* of their own, such as [Cache_File] and [Cache_Sqlite]. Memory based
* cache systems clean their own caches periodically.
*
* @package Kohana
* @category Cache
* @package Kohana/Cache
* @category Base
* @version 2.0
* @author Kohana Team
* @copyright (c) 2009-2010 Kohana Team
@@ -20,4 +20,4 @@ interface Kohana_Cache_GarbageCollect {
* @return void
*/
public function garbage_collect();
}
}

View File

@@ -24,6 +24,7 @@
* 'timeout' => 1,
* 'retry_interval' => 15,
* 'status' => TRUE,
* 'instant_death' => TRUE,
* 'failure_callback' => array('className', 'classMethod')
* ),
* // Second memcache server
@@ -72,8 +73,8 @@
* * Memcache (plus Memcached-tags for native tagging support)
* * Zlib
*
* @package Kohana
* @category Cache
* @package Kohana/Cache
* @category Base
* @version 2.0
* @author Kohana Team
* @copyright (c) 2009-2010 Kohana Team
@@ -98,6 +99,13 @@ class Kohana_Cache_Memcache extends Cache {
*/
protected $_flags;
/**
* The default configuration for the memcached server
*
* @var array
*/
protected $_default_config = array();
/**
* Constructs the memcache Kohana_Cache object
*
@@ -127,22 +135,23 @@ class Kohana_Cache_Memcache extends Cache {
}
// Setup default server configuration
$config = array(
'host' => 'localhost',
'port' => 11211,
'persistent' => FALSE,
'weight' => 1,
'timeout' => 1,
'retry_interval' => 15,
'status' => TRUE,
'failure_callback' => array($this, '_failed_request'),
$this->_default_config = array(
'host' => 'localhost',
'port' => 11211,
'persistent' => FALSE,
'weight' => 1,
'timeout' => 1,
'retry_interval' => 15,
'status' => TRUE,
'instant_death' => TRUE,
'failure_callback' => array($this, '_failed_request'),
);
// Add the memcache servers to the pool
foreach ($servers as $server)
{
// Merge the defined config with defaults
$server += $config;
$server += $this->_default_config;
if ( ! $this->_memcache->addServer($server['host'], $server['port'], $server['persistent'], $server['weight'], $server['timeout'], $server['retry_interval'], $server['status'], $server['failure_callback']))
{
@@ -276,7 +285,7 @@ class Kohana_Cache_Memcache extends Cache {
* @return void|boolean
* @since 3.0.8
*/
protected function _failed_request($hostname, $port)
public function _failed_request($hostname, $port)
{
if ( ! $this->_config['instant_death'])
return;
@@ -287,8 +296,12 @@ class Kohana_Cache_Memcache extends Cache {
// Get host settings from configuration
foreach ($this->_config['servers'] as $server)
{
// Merge the defaults, since they won't always be set
$server += $this->_default_config;
// We're looking at the failed server
if ($hostname == $server['host'] and $port == $server['port'])
{
// Server to disable, since it failed
$host = $server;
continue;
}
@@ -303,7 +316,7 @@ class Kohana_Cache_Memcache extends Cache {
$host['port'],
$host['timeout'],
$host['retry_interval'],
FALSE,
FALSE, // Server is offline
array($this, '_failed_request'
));
}

View File

@@ -2,8 +2,8 @@
/**
* See [Kohana_Cache_Memcache]
*
* @package Kohana
* @category Cache
* @package Kohana/Cache
* @category Base
* @version 2.0
* @author Kohana Team
* @copyright (c) 2009-2010 Kohana Team
@@ -11,7 +11,7 @@
*/
class Kohana_Cache_MemcacheTag extends Cache_Memcache implements Kohana_Cache_Tagging {
/**
/**
* Constructs the memcache object
*
* @param array configuration
@@ -19,12 +19,12 @@ class Kohana_Cache_MemcacheTag extends Cache_Memcache implements Kohana_Cache_Ta
*/
protected function __construct(array $config)
{
parent::__construct($config);
if ( ! method_exists($this->_memcache, 'tag_add'))
{
throw new Kohana_Cache_Exception('Memcached-tags PHP plugin not present. Please see http://code.google.com/p/memcached-tags/ for more information');
}
parent::__construct($config);
}
/**
@@ -73,4 +73,4 @@ class Kohana_Cache_MemcacheTag extends Cache_Memcache implements Kohana_Cache_Ta
{
throw new Kohana_Cache_Exception('Memcached-tags does not support finding by tag');
}
}
}

View File

@@ -4,8 +4,8 @@
*
* Requires SQLite3 and PDO
*
* @package Kohana
* @category Cache
* @package Kohana/Cache
* @category Base
* @author Kohana Team
* @copyright (c) 2009-2010 Kohana Team
* @license http://kohanaphp.com/license
@@ -195,16 +195,16 @@ class Kohana_Cache_Sqlite extends Cache implements Kohana_Cache_Tagging, Kohana_
$data = serialize($data);
// Normalise tags
$tags = (NULL === $tags) ? NULL : '<'.implode('>,<', $tags).'>';
$tags = (NULL === $tags) ? NULL : ('<'.implode('>,<', $tags).'>');
// Setup lifetime
if ($lifetime === NULL)
{
$lifetime = (0 === Arr::get('default_expire', NULL)) ? 0 : Arr::get($this->_config, 'default_expire', Cache::DEFAULT_EXPIRE) + time();
$lifetime = (0 === Arr::get('default_expire', NULL)) ? 0 : (Arr::get($this->_config, 'default_expire', Cache::DEFAULT_EXPIRE) + time());
}
else
{
$lifetime = (0 === $lifetime) ? 0 : $lifetime + time();
$lifetime = (0 === $lifetime) ? 0 : ($lifetime + time());
}
// Prepare statement
@@ -333,4 +333,4 @@ class Kohana_Cache_Sqlite extends Cache implements Kohana_Cache_Tagging, Kohana_
return (bool) $statement->fetchAll();
}
}
}

View File

@@ -2,8 +2,8 @@
/**
* Kohana Cache Tagging Interface
*
* @package Kohana
* @category Cache
* @package Kohana/Cache
* @category Base
* @author Kohana Team
* @copyright (c) 2009-2010 Kohana Team
* @license http://kohanaphp.com/license
@@ -39,4 +39,4 @@ interface Kohana_Cache_Tagging {
* @return array
*/
public function find($tag);
}
}

View File

@@ -0,0 +1,140 @@
<?php defined('SYSPATH') or die('No direct script access.');
/**
* [Kohana Cache](api/Kohana_Cache) Wincache driver. Provides an opcode based
* driver for the Kohana Cache library.
*
* ### Configuration example
*
* Below is an example of an _wincache_ server configuration.
*
* return array(
* 'wincache' => array( // Driver group
* 'driver' => 'wincache', // using wincache driver
* ),
* )
*
* In cases where only one cache group is required, if the group is named `default` there is
* no need to pass the group name when instantiating a cache instance.
*
* #### General cache group configuration settings
*
* Below are the settings available to all types of cache driver.
*
* Name | Required | Description
* -------------- | -------- | ---------------------------------------------------------------
* driver | __YES__ | (_string_) The driver type to use
*
* ### System requirements
*
* * Windows XP SP3 with IIS 5.1 and » FastCGI Extension
* * Windows Server 2003 with IIS 6.0 and » FastCGI Extension
* * Windows Vista SP1 with IIS 7.0 and FastCGI Module
* * Windows Server 2008 with IIS 7.0 and FastCGI Module
* * Windows 7 with IIS 7.5 and FastCGI Module
* * Windows Server 2008 R2 with IIS 7.5 and FastCGI Module
* * PHP 5.2.X, Non-thread-safe build
* * PHP 5.3 X86, Non-thread-safe VC9 build
*
* @package Kohana/Cache
* @category Base
* @author Kohana Team
* @copyright (c) 2009-2010 Kohana Team
* @license http://kohanaphp.com/license
*/
class Kohana_Cache_Wincache extends Cache {
/**
* Check for existence of the wincache extension This method cannot be invoked externally. The driver must
* be instantiated using the `Cache::instance()` method.
*
* @param array configuration
* @throws Kohana_Cache_Exception
*/
protected function __construct(array $config)
{
if ( ! extension_loaded('wincache'))
{
throw new Kohana_Cache_Exception('PHP wincache extension is not available.');
}
parent::__construct($config);
}
/**
* Retrieve a cached value entry by id.
*
* // Retrieve cache entry from wincache group
* $data = Cache::instance('wincache')->get('foo');
*
* // Retrieve cache entry from wincache group and return 'bar' if miss
* $data = Cache::instance('wincache')->get('foo', 'bar');
*
* @param string id of cache to entry
* @param string default value to return if cache miss
* @return mixed
* @throws Kohana_Cache_Exception
*/
public function get($id, $default = NULL)
{
$data = wincache_ucache_get($this->_sanitize_id($id), $success);
return $success ? $data : $default;
}
/**
* Set a value to cache with id and lifetime
*
* $data = 'bar';
*
* // Set 'bar' to 'foo' in wincache group, using default expiry
* Cache::instance('wincache')->set('foo', $data);
*
* // Set 'bar' to 'foo' in wincache group for 30 seconds
* Cache::instance('wincache')->set('foo', $data, 30);
*
* @param string id of cache entry
* @param string data to set to cache
* @param integer lifetime in seconds
* @return boolean
*/
public function set($id, $data, $lifetime = NULL)
{
if ($lifetime === NULL)
{
$lifetime = Arr::get($this->_config, 'default_expire', Cache::DEFAULT_EXPIRE);
}
return wincache_ucache_set($this->_sanitize_id($id), $data, $lifetime);
}
/**
* Delete a cache entry based on id
*
* // Delete 'foo' entry from the wincache group
* Cache::instance('wincache')->delete('foo');
*
* @param string id to remove from cache
* @return boolean
*/
public function delete($id)
{
return wincache_ucache_delete($this->_sanitize_id($id));
}
/**
* Delete all cache entries.
*
* Beware of using this method when
* using shared memory cache systems, as it will wipe every
* entry within the system for all clients.
*
* // Delete all cache entries in the wincache group
* Cache::instance('wincache')->delete_all();
*
* @return boolean
*/
public function delete_all()
{
return wincache_ucache_clear();
}
}

View File

@@ -46,6 +46,11 @@ return array
'driver' => 'apc',
'default_expire' => 3600,
),
'wincache' => array
(
'driver' => 'wincache',
'default_expire' => 3600,
),
'sqlite' => array
(
'driver' => 'sqlite',

View File

@@ -0,0 +1,23 @@
<?php defined('SYSPATH') or die('No direct script access.');
return array(
// Leave this alone
'modules' => array(
// This should be the path to this modules userguide pages, without the 'guide/'. Ex: '/guide/modulename/' would be 'modulename'
'cache' => array(
// Whether this modules userguide pages should be shown
'enabled' => TRUE,
// The name that should show up on the userguide index page
'name' => 'Cache',
// A short description of this module, shown on the index page
'description' => 'Common interface for caching engines.',
// Copyright message, shown in the footer for this module
'copyright' => '&copy; 20082010 Kohana Team',
)
)
);

View File

View File

@@ -0,0 +1,3 @@
## [Cache]()
- [Configuration](config)
- [Usage](usage)

View File

@@ -0,0 +1,219 @@
# Kohana Cache usage
[Kohana_Cache] provides a simple interface allowing getting, setting and deleting of cached values. Two interfaces included in _Kohana Cache_ additionally provide _tagging_ and _garbage collection_ where they are supported by the respective drivers.
## Getting a new cache instance
Creating a new _Kohana Cache_ instance is simple, however it must be done using the [Cache::instance] method, rather than the traditional `new` constructor.
// Create a new instance of cache using the default group
$cache = Cache::instance();
The default group will use whatever is set to [Cache::$default] and must have a corresponding [configuration](cache.config) definition for that group.
To create a cache instance using a group other than the _default_, simply provide the group name as an argument.
// Create a new instance of the memcache group
$memcache = Cache::instance('memcache');
If there is a cache instance already instantiated then you can get it directly from the class member.
[!!] Beware that this can cause issues if you do not test for the instance before trying to access it.
// Check for the existance of the cache driver
if (isset(Cache::$instances['memcache']))
{
// Get the existing cache instance directly (faster)
$memcache = Cache::$instances['memcache'];
}
else
{
// Get the cache driver instance (slower)
$memcache = Cache::instance('memcache');
}
## Setting and getting variables to and from cache
The cache library supports scalar and object values, utilising object serialization where required (or not supported by the caching engine). This means that the majority or objects can be cached without any modification.
[!!] Serialisation does not work with resource handles, such as filesystem, curl or socket resources.
### Setting a value to cache
Setting a value to cache using the [Cache::set] method can be done in one of two ways; either using the Cache instance interface, which is good for atomic operations; or getting an instance and using that for multiple operations.
The first example demonstrates how to quickly load and set a value to the default cache instance.
// Create a cachable object
$object = new stdClass;
// Set a property
$object->foo = 'bar';
// Cache the object using default group (quick interface) with default time (3600 seconds)
Cache::instance()->set('foo', $object);
If multiple cache operations are required, it is best to assign an instance of Cache to a variable and use that as below.
// Set the object using a defined group for a defined time period (30 seconds)
$memcache = Cache::instance('memcache');
$memcache->set('foo', $object, 30);
#### Setting a value with tags
Certain cache drivers support setting values with tags. To set a value to cache with tags using the following interface.
// Get a cache instance that supports tags
$memcache = Cache::instance('memcachetag');
// Test for tagging interface
if ($memcache instanceof Kohana_Cache_Tagging)
{
// Set a value with some tags for 30 seconds
$memcache->set('foo', $object, 30, array('snafu', 'stfu', 'fubar'));
}
// Otherwise set without tags
else
{
// Set a value for 30 seconds
$memcache->set('foo', $object, 30);
}
It is possible to implement custom tagging solutions onto existing or new cache drivers by implementing the [Kohana_Cache_Tagging] interface. Kohana_Cache only applies the interface to drivers that support tagging natively as standard.
### Getting a value from cache
Getting variables back from cache is achieved using the [Cache::get] method using a single key to identify the cache entry.
// Retrieve a value from cache (quickly)
$object = Cache::instance()->get('foo');
In cases where the requested key is not available or the entry has expired, a default value will be returned (__NULL__ by default). It is possible to define the default value as the key is requested.
// If the cache key is available (with default value set to FALSE)
if ($object = Cache::instance()->get('foo', FALSE))
{
// Do something
}
else
{
// Do something else
}
#### Getting values from cache using tags
It is possible to retrieve values from cache grouped by tag, using the [Cache::find] method with drivers that support tagging.
[!!] The __Memcachetag__ driver does not support the `Cache::find($tag)` interface and will throw an exception.
// Get an instance of cache
$cache = Cache::instance('memcachetag');
// Wrap in a try/catch statement to gracefully handle memcachetag
try
{
// Find values based on tag
return $cache->find('snafu');
}
catch (Kohana_Cache_Exception $e)
{
// Handle gracefully
return FALSE;
}
### Deleting values from cache
Deleting variables is very similar to the getting and setting methods already described. Deleting operations are split into three categories:
- __Delete value by key__. Deletes a cached value by the associated key.
- __Delete all values__. Deletes all caches values stored in the cache instance.
- __Delete values by tag__. Deletes all values that have the supplied tag. This is only supported by Memcached-Tag and Sqlite.
#### Delete value by key
To delete a specific value by its associated key:
// If the cache entry for 'foo' is deleted
if (Cache::instance()->delete('foo'))
{
// Cache entry successfully deleted, do something
}
By default a `TRUE` value will be returned. However a `FALSE` value will be returned in instances where the key did not exist in the cache.
#### Delete all values
To delete all values in a specific instance:
// If all cache items where deleted successfully
if (Cache::instance()->delete_all())
{
// Do something
}
It is also possible to delete all cache items in every instance:
// For each cache instance
foreach (Cache::$instances as $group => $instance)
{
if ($instance->delete_all())
{
var_dump('instance : '.$group.' has been flushed!');
}
}
#### Delete values by tag
Some of the caching drivers support deleting by tag. This will remove all the cached values that are associated with a specific tag. Below is an example of how to robustly handle deletion by tag.
// Get cache instance
$cache = Cache::instance();
// Check for tagging interface
if ($cache instanceof Kohana_Cache_Tagging)
{
// Delete all entries by the tag 'snafu'
$cache->delete_tag('snafu');
}
#### Garbage Collection
Garbage Collection (GC) is the cleaning of expired cache entries. For the most part, caching engines will take care of garbage collection internally. However a few of the file based systems do not handle this task and in these circumstances it would be prudent to garbage collect at a predetermined frequency. If no garbage collection is executed, the resource storing the cache entries will eventually fill and become unusable.
When not automated, garbage collection is the responsibility of the developer. It is prudent to have a GC probability value that dictates how likely the garbage collection routing will be run. An example of such a system is demonstrated below.
// Get a cache instance
$cache_file = Cache::instance('file');
// Set a GC probability of 10%
$gc = 10;
// If the GC probability is a hit
if (rand(0,99) <= $gc and $cache_file instanceof Kohana_Cache_GarbageCollect)
{
// Garbage Collect
$cache_file->garbage_collect();
}
# Interfaces
Kohana Cache comes with two interfaces that are implemented where the drivers support them:
- __[Kohana_Cache_Tagging] for tagging support on cache entries__
- [Cache_MemcacheTag]
- [Cache_Sqlite]
- __[Kohana_Cache_GarbageCollect] for garbage collection with drivers without native support__
- [Cache_File]
- [Cache_Sqlite]
When using interface specific caching features, ensure that code checks for the required interface before using the methods supplied. The following example checks whether the garbage collection interface is available before calling the `garbage_collect` method.
// Create a cache instance
$cache = Cache::instance();
// Test for Garbage Collection
if ($cache instanceof Kohana_Cache_GarbageCollect)
{
// Collect garbage
$cache->garbage_collect();
}

View File

@@ -1,4 +0,0 @@
1. **Cache**
- [About](cache.about)
- [Configuration](cache.config)
- [Usage](cache.usage)