Skip to content

Commit

Permalink
Merge branch '40903-25' of git://github.com/samhemelryk/moodle into M…
Browse files Browse the repository at this point in the history
…OODLE_25_STABLE
  • Loading branch information
stronk7 committed Sep 25, 2013
2 parents b8cf62b + de760ea commit 1cf52db
Show file tree
Hide file tree
Showing 11 changed files with 457 additions and 196 deletions.
13 changes: 6 additions & 7 deletions cache/README.md
Expand Up @@ -24,8 +24,8 @@ A definition:
'overrideclassfile' => null, // Optional
'datasource' => null, // Optional
'datasourcefile' => null, // Optional
'persistent' => false, // Optional
'persistentmaxsize' => false, // Optional
'staticacceleration' => false, // Optional
'staticaccelerationsize' => false, // Optional
'ttl' => 0, // Optional
'mappingsonly' => false // Optional
'invalidationevents' => array( // Optional
Expand Down Expand Up @@ -144,8 +144,8 @@ The following optional settings can also be defined:
* overrideclassfile - Included if required when using the overrideclass param.
* datasource - If provided this class will be used as a data source for the definition. It must implement the cache_data_source interface.
* datasourcefile - Included if required when using the datasource param.
* persistent - If set to true the loader will be stored when first created and provided to subsequent requests. More on this later.
* persistentmaxsize - If set to an int this will be the maximum number of items stored in the persistent cache.
* staticacceleration - Any data passing through the cache will be held onto to make subsequent requests for it faster.
* staticaccelerationsize - If set to an int this will be the maximum number of items stored in the static acceleration array.
* ttl - Can be used to set a ttl value for data being set for this cache.
* mappingsonly - This definition can only be used if there is a store mapping for it. More on this later.
* invalidationevents - An array of events that should trigger this cache to invalidate.
Expand All @@ -154,11 +154,10 @@ The following optional settings can also be defined:

It's important to note that internally the definition is also aware of the component. This is picked up when the definition is read, based upon the location of the caches.php file.

The persistent option.
As noted the persistent option causes the loader generated for this definition to be stored when first created. Subsequent requests for this definition will be given the original loader instance.
The staticacceleration option.
Data passed to or retrieved from the loader and its chained loaders gets cached by the instance.
This option should be used when you know you will require the loader several times and perhaps in different areas of code.
Because it caches key=>value data it avoids the need to re-fetch things from stores after the first request. Its good for performance, bad for memory.
Memory use can be controlled by setting the staticaccelerationsize option.
It should be used sparingly.

The mappingsonly option.
Expand Down
102 changes: 74 additions & 28 deletions cache/classes/definition.php
Expand Up @@ -75,19 +75,14 @@
* [string] A class to use as the data loader for this definition.
* Any class used here must inherit the cache_data_loader interface.
* + datasourcefile
* [string] Suplements the above setting indicated the file containing the class to be used. This file is included when
* [string] Supplements the above setting indicating the file containing the class to be used. This file is included when
* required.
* + persistent
* [bool] This setting does two important things. First it tells the cache API to only instantiate the cache structure for
* this definition once, further requests will be given the original instance.
* Second the cache loader will keep an array of the items set and retrieved to the cache during the request.
* This has several advantages including better performance without needing to start passing the cache instance between
* function calls, the downside is that the cache instance + the items used stay within memory.
* Consider using this setting when you know that there are going to be many calls to the cache for the same information
* or when you are converting existing code to the cache and need to access the cache within functions but don't want
* to add it as an argument to the function.
* + persistentmaxsize
* [int] This supplements the above setting by limiting the number of items in the caches persistent array of items.
* + staticacceleration
* The cache loader will keep an array of the items set and retrieved to the cache during the request.
* Consider using this setting when you know that there are going to be many calls to the cache for the same information.
* Requests for data in this array will be ultra fast, but it will cost memory.
* + staticaccelerationsize
* [int] This supplements the above setting by limiting the number of items in the static acceleration array.
* Tweaking this setting lower will allow you to minimise the memory implications above while hopefully still managing to
* offset calls to the cache store.
* + ttl
Expand Down Expand Up @@ -253,16 +248,16 @@ class cache_definition {
protected $datasourceaggregate = null;

/**
* Set to true if the definitions cache should be persistent
* Set to true if the cache should hold onto items passing through it to speed up subsequent requests.
* @var bool
*/
protected $persistent = false;
protected $staticacceleration = false;

/**
* The persistent item array max size.
* The maximum number of items that static acceleration cache should hold onto.
* @var int
*/
protected $persistentmaxsize = false;
protected $staticaccelerationsize = false;

/**
* The TTL for data in this cache. Please don't use this, instead use event driven invalidation.
Expand Down Expand Up @@ -363,8 +358,8 @@ public static function load($id, array $definition, $datasourceaggregate = null)
$overrideclassfile = null;
$datasource = null;
$datasourcefile = null;
$persistent = false;
$persistentmaxsize = false;
$staticacceleration = false;
$staticaccelerationsize = false;
$ttl = 0;
$mappingsonly = false;
$invalidationevents = array();
Expand Down Expand Up @@ -419,10 +414,18 @@ public static function load($id, array $definition, $datasourceaggregate = null)
}

if (array_key_exists('persistent', $definition)) {
$persistent = (bool)$definition['persistent'];
// Ahhh this is the legacy persistent option.
$staticacceleration = (bool)$definition['persistent'];
}
if (array_key_exists('staticacceleration', $definition)) {
$staticacceleration = (bool)$definition['staticacceleration'];
}
if (array_key_exists('persistentmaxsize', $definition)) {
$persistentmaxsize = (int)$definition['persistentmaxsize'];
// Ahhh this is the legacy persistentmaxsize option.
$staticaccelerationsize = (int)$definition['persistentmaxsize'];
}
if (array_key_exists('staticaccelerationsize', $definition)) {
$staticaccelerationsize = (int)$definition['staticaccelerationsize'];
}
if (array_key_exists('ttl', $definition)) {
$ttl = (int)$definition['ttl'];
Expand Down Expand Up @@ -518,8 +521,8 @@ public static function load($id, array $definition, $datasourceaggregate = null)
$cachedefinition->datasource = $datasource;
$cachedefinition->datasourcefile = $datasourcefile;
$cachedefinition->datasourceaggregate = $datasourceaggregate;
$cachedefinition->persistent = $persistent;
$cachedefinition->persistentmaxsize = $persistentmaxsize;
$cachedefinition->staticacceleration = $staticacceleration;
$cachedefinition->staticaccelerationsize = $staticaccelerationsize;
$cachedefinition->ttl = $ttl;
$cachedefinition->mappingsonly = $mappingsonly;
$cachedefinition->invalidationevents = $invalidationevents;
Expand All @@ -543,7 +546,8 @@ public static function load($id, array $definition, $datasourceaggregate = null)
* - simplekeys : Set to true if the keys you will use are a-zA-Z0-9_
* - simpledata : Set to true if the type of the data you are going to store is scalar, or an array of scalar vars
* - overrideclass : The class to use as the loader.
* - persistent : If set to true the cache will persist construction requests.
* - staticacceleration : If set to true the cache will hold onto data passing through it.
* - staticaccelerationsize : Set it to an int to limit the size of the staticacceleration cache.
* @return cache_application|cache_session|cache_request
*/
public static function load_adhoc($mode, $component, $area, array $options = array()) {
Expand All @@ -560,7 +564,14 @@ public static function load_adhoc($mode, $component, $area, array $options = arr
$definition['simpledata'] = $options['simpledata'];
}
if (!empty($options['persistent'])) {
$definition['persistent'] = $options['persistent'];
// Ahhh this is the legacy persistent option.
$definition['staticacceleration'] = (bool)$options['persistent'];
}
if (!empty($options['staticacceleration'])) {
$definition['staticacceleration'] = (bool)$options['staticacceleration'];
}
if (!empty($options['staticaccelerationsize'])) {
$definition['staticaccelerationsize'] = (int)$options['staticaccelerationsize'];
}
if (!empty($options['overrideclass'])) {
$definition['overrideclass'] = $options['overrideclass'];
Expand Down Expand Up @@ -788,18 +799,53 @@ public function get_requirements_bin() {

/**
* Returns true if this definitions cache should be made persistent.
*
* Please call {@link cache_definition::use_static_acceleration()} instead.
*
* @deprecated since 2.5.3
* @return bool
*/
public function should_be_persistent() {
return $this->persistent || $this->mode === cache_store::MODE_SESSION;
debugging('Please upgrade your code to use cache_definition::use_static_acceleration', DEBUG_DEVELOPER);
return $this->use_static_acceleration();
}

/**
* Returns true if we should hold onto the data flowing through the cache.
*
* If set to true data flowing through the cache will be stored in a static variable
* to make subsequent requests for the data much faster.
*
* @return bool
*/
public function use_static_acceleration() {
if ($this->mode === cache_store::MODE_REQUEST) {
// Request caches should never use static acceleration - it just doesn't make sense.
return false;
}
return $this->staticacceleration || $this->mode === cache_store::MODE_SESSION;
}

/**
* Returns the max size for the persistent item array in the cache.
* Returns the max size for the static acceleration array.
*
* Please call {@link cache_definition::get_static_acceleration_size()} instead.
*
* @see cache_definition::get_static_acceleration_size()
* @deprecated since 2.5.3
* @return int
*/
public function get_persistent_max_size() {
return $this->persistentmaxsize;
debugging('Please upgrade your code to call cache_definition::get_static_acceleration_size', DEBUG_DEVELOPER);
return $this->get_static_acceleration_size();
}

/**
* Returns the max size for the static acceleration array.
* @return int
*/
public function get_static_acceleration_size() {
return $this->staticaccelerationsize;
}

/**
Expand Down Expand Up @@ -916,4 +962,4 @@ protected function get_cache_identifier() {
public function has_required_identifiers() {
return (count($this->requireidentifiers) > 0);
}
}
}
17 changes: 9 additions & 8 deletions cache/classes/dummystore.php
Expand Up @@ -46,14 +46,15 @@ class cachestore_dummy extends cache_store {
protected $name;

/**
* Gets set to true if this store is going to persist data.
* This happens when the definition doesn't require it as the loader will not be persisting information and something has to.
* Gets set to true if this store is going to store data.
* This happens when the definition doesn't require static acceleration as the loader will not be storing information and
* something has to.
* @var bool
*/
protected $persist = false;

/**
* The persistent store array
* The stored data array
* @var array
*/
protected $store = array();
Expand Down Expand Up @@ -106,13 +107,13 @@ public static function get_supported_modes(array $configuration = array()) {
* @param cache_definition $definition
*/
public function initialise(cache_definition $definition) {
// If the definition isn't persistent then we need to be persistent here.
// If the definition isn't using static acceleration then we need to be store data here.
// The reasoning behind this is that:
// - If the definition is persistent then the cache loader is going to
// store things in its persistent cache.
// - If the definition is not persistent then the cache loader won't try to store anything
// - If the definition is using static acceleration then the cache loader is going to
// store things in its static array.
// - If the definition is not using static acceleration then the cache loader won't try to store anything
// and we will need to store it here in order to make sure it is accessible.
$this->persist = !$definition->should_be_persistent();
$this->persist = !$definition->use_static_acceleration();
}

/**
Expand Down
39 changes: 29 additions & 10 deletions cache/classes/factory.php
Expand Up @@ -150,16 +150,26 @@ protected function __construct() {
*/
public static function reset() {
$factory = self::instance();
$factory->cachesfromdefinitions = array();
$factory->cachesfromparams = array();
$factory->stores = array();
$factory->reset_cache_instances();
$factory->configs = array();
$factory->definitions = array();
$factory->lockplugins = array(); // MUST be null in order to force its regeneration.
// Reset the state to uninitialised.
$factory->state = self::STATE_UNINITIALISED;
}

/**
* Resets the stores, clearing the array of created stores.
*
* Cache objects still held onto by the code that initialised them will remain as is
* however all future requests for a cache/store will lead to a new instance being re-initialised.
*/
public function reset_cache_instances() {
$this->cachesfromdefinitions = array();
$this->cachesfromparams = array();
$this->stores = array();
}

/**
* Creates a cache object given the parameters for a definition.
*
Expand All @@ -181,9 +191,8 @@ public function create_cache_from_definition($component, $area, array $identifie
$definition = $this->create_definition($component, $area, $aggregate);
$definition->set_identifiers($identifiers);
$cache = $this->create_cache($definition, $identifiers);
if ($definition->should_be_persistent()) {
$this->cachesfromdefinitions[$definitionname] = $cache;
}
// Loaders are always held onto to speed up subsequent requests.
$this->cachesfromdefinitions[$definitionname] = $cache;
return $cache;
}

Expand All @@ -199,7 +208,8 @@ public function create_cache_from_definition($component, $area, array $identifie
* @param array $options An array of options, available options are:
* - simplekeys : Set to true if the keys you will use are a-zA-Z0-9_
* - simpledata : Set to true if the type of the data you are going to store is scalar, or an array of scalar vars
* - persistent : If set to true the cache will persist construction requests.
* - staticacceleration : If set to true the cache will hold onto data passing through it.
* - staticaccelerationsize : The maximum number of items to hold onto for acceleration purposes.
* @return cache_application|cache_session|cache_request
*/
public function create_cache_from_params($mode, $component, $area, array $identifiers = array(), array $options = array()) {
Expand All @@ -210,9 +220,7 @@ public function create_cache_from_params($mode, $component, $area, array $identi
$definition = cache_definition::load_adhoc($mode, $component, $area, $options);
$definition->set_identifiers($identifiers);
$cache = $this->create_cache($definition, $identifiers);
if ($definition->should_be_persistent()) {
$this->cachesfromparams[$key] = $cache;
}
$this->cachesfromparams[$key] = $cache;
return $cache;
}

Expand Down Expand Up @@ -297,6 +305,15 @@ public function get_store_instances_in_use(cache_definition $definition) {
return $this->definitionstores[$id];
}

/**
* Returns the cache instances that have been used within this request.
* @since 2.5.3
* @return array
*/
public function get_caches_in_use() {
return $this->cachesfromdefinitions;
}

/**
* Creates a cache config instance with the ability to write if required.
*
Expand Down Expand Up @@ -585,7 +602,9 @@ public function stores_disabled() {
* </code>
*/
public static function disable_stores() {
// First reset to clear any static acceleration array.
$factory = self::instance();
$factory->reset_cache_instances();
$factory->set_state(self::STATE_STORES_DISABLED);
}
}

0 comments on commit 1cf52db

Please sign in to comment.