Skip to content

Commit

Permalink
Merge branch '43033-27' of git://github.com/samhemelryk/moodle
Browse files Browse the repository at this point in the history
  • Loading branch information
Damyon Wiese committed Dec 2, 2013
2 parents c619d3d + 1e9f4c9 commit ecfbb65
Show file tree
Hide file tree
Showing 7 changed files with 157 additions and 65 deletions.
1 change: 1 addition & 0 deletions cache/admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@

$PAGE->set_title($title);
$PAGE->set_heading($SITE->fullname);
/* @var core_cache_renderer $renderer */
$renderer = $PAGE->get_renderer('core_cache');

echo $renderer->header();
Expand Down
27 changes: 27 additions & 0 deletions cache/classes/definition.php
Original file line number Diff line number Diff line change
Expand Up @@ -963,4 +963,31 @@ protected function get_cache_identifier() {
public function has_required_identifiers() {
return (count($this->requireidentifiers) > 0);
}

/**
* Returns the possible sharing options that can be used with this defintion.
*
* @return int
*/
public function get_sharing_options() {
return $this->sharingoptions;
}

/**
* Returns the user entered sharing key for this definition.
*
* @return string
*/
public function get_user_input_sharing_key() {
return $this->userinputsharingkey;
}

/**
* Returns the user selected sharing option for this definition.
*
* @return int
*/
public function get_selected_sharing_option() {
return $this->selectedsharingoption;
}
}
9 changes: 2 additions & 7 deletions cache/classes/factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -235,14 +235,9 @@ public function create_cache_from_params($mode, $component, $area, array $identi
*/
public function create_cache(cache_definition $definition) {
$class = $definition->get_cache_class();
if ($this->is_initialising()) {
// Do nothing we just want the dummy store.
$stores = array();
} else {
$stores = cache_helper::get_cache_stores($definition);
}
$stores = cache_helper::get_stores_suitable_for_definition($definition);
if (count($stores) === 0) {
// Hmm no stores, better provide a dummy store to mimick functionality. The dev will be none the wiser.
// Hmm still no stores, better provide a dummy store to mimic functionality. The dev will be none the wiser.
$stores[] = $this->create_dummy_store($definition);
}
$loader = null;
Expand Down
75 changes: 68 additions & 7 deletions cache/classes/helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ public static function get_cache_stores(cache_definition $definition) {
*
* @param array $stores
* @param cache_definition $definition
* @return array
* @return cache_store[]
*/
protected static function initialise_cachestore_instances(array $stores, cache_definition $definition) {
$return = array();
Expand Down Expand Up @@ -382,34 +382,40 @@ protected static function ensure_ready_for_stats($store, $definition) {
/**
* Record a cache hit in the stats for the given store and definition.
*
* @internal
* @param string $store
* @param string $definition
* @param int $hits The number of hits to record (by default 1)
*/
public static function record_cache_hit($store, $definition) {
public static function record_cache_hit($store, $definition, $hits = 1) {
self::ensure_ready_for_stats($store, $definition);
self::$stats[$definition][$store]['hits']++;
self::$stats[$definition][$store]['hits'] += $hits;
}

/**
* Record a cache miss in the stats for the given store and definition.
*
* @internal
* @param string $store
* @param string $definition
* @param int $misses The number of misses to record (by default 1)
*/
public static function record_cache_miss($store, $definition) {
public static function record_cache_miss($store, $definition, $misses = 1) {
self::ensure_ready_for_stats($store, $definition);
self::$stats[$definition][$store]['misses']++;
self::$stats[$definition][$store]['misses'] += $misses;
}

/**
* Record a cache set in the stats for the given store and definition.
*
* @internal
* @param string $store
* @param string $definition
* @param int $sets The number of sets to record (by default 1)
*/
public static function record_cache_set($store, $definition) {
public static function record_cache_set($store, $definition, $sets = 1) {
self::ensure_ready_for_stats($store, $definition);
self::$stats[$definition][$store]['sets']++;
self::$stats[$definition][$store]['sets'] += $sets;
}

/**
Expand Down Expand Up @@ -672,4 +678,59 @@ public static function clean_old_session_data($output = false) {
}
}
}

/**
* Returns an array of stores that would meet the requirements for every definition.
*
* These stores would be 100% suitable to map as defaults for cache modes.
*
* @return array[] An array of stores, keys are the store names.
*/
public static function get_stores_suitable_for_mode_default() {
$factory = cache_factory::instance();
$config = $factory->create_config_instance();
$requirements = 0;
foreach ($config->get_definitions() as $definition) {
$definition = cache_definition::load($definition['component'].'/'.$definition['area'], $definition);
$requirements = $requirements | $definition->get_requirements_bin();
}
$stores = array();
foreach ($config->get_all_stores() as $name => $store) {
if (!empty($store['features']) && ($store['features'] & $requirements)) {
$stores[$name] = $store;
}
}
return $stores;
}

/**
* Returns stores suitable for use with a given definition.
*
* @param cache_definition $definition
* @return cache_store[]
*/
public static function get_stores_suitable_for_definition(cache_definition $definition) {
$factory = cache_factory::instance();
$stores = array();
if ($factory->is_initialising() || $factory->stores_disabled()) {
// No suitable stores here.
return $stores;
} else {
$stores = self::get_cache_stores($definition);
if (count($stores) === 0) {
// No suitable stores we found for the definition. We need to come up with a sensible default.
// If this has happened we can be sure that the user has mapped custom stores to either the
// mode of the definition. The first alternative to try is the system default for the mode.
// e.g. the default file store instance for application definitions.
$config = $factory->create_config_instance();
foreach ($config->get_stores($definition->get_mode()) as $name => $details) {
if (!empty($details['default'])) {
$stores[] = $factory->create_store_from_config($name, $details, $definition);
break;
}
}
}
}
return $stores;
}
}
42 changes: 35 additions & 7 deletions cache/classes/loaders.php
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,20 @@ public function get_many(array $keys, $strictness = IGNORE_MISSING) {
}
}

if ($this->perfdebug) {
$hits = 0;
$misses = 0;
foreach ($fullresult as $value) {
if ($value === false) {
$misses++;
} else {
$hits++;
}
}
cache_helper::record_cache_hit($this->storetype, $this->definition->get_id(), $hits);
cache_helper::record_cache_miss($this->storetype, $this->definition->get_id(), $misses);
}

// Return the result. Phew!
return $fullresult;
}
Expand Down Expand Up @@ -633,10 +647,11 @@ public function set_many(array $keyvaluearray) {
$this->static_acceleration_set($data[$key]['key'], $value);
}
}
if ($this->perfdebug) {
cache_helper::record_cache_set($this->storetype, $this->definition->get_id());
$successfullyset = $this->store->set_many($data);
if ($this->perfdebug && $successfullyset) {
cache_helper::record_cache_set($this->storetype, $this->definition->get_id(), $successfullyset);
}
return $this->store->set_many($data);
return $successfullyset;
}

/**
Expand Down Expand Up @@ -1937,7 +1952,19 @@ public function get_many(array $keys, $strictness = IGNORE_MISSING) {
if ($hasmissingkeys && $strictness === MUST_EXIST) {
throw new coding_exception('Requested key did not exist in any cache stores and could not be loaded.');
}

if ($this->perfdebug) {
$hits = 0;
$misses = 0;
foreach ($return as $value) {
if ($value === false) {
$misses++;
} else {
$hits++;
}
}
cache_helper::record_cache_hit($this->storetype, $this->get_definition()->get_id(), $hits);
cache_helper::record_cache_miss($this->storetype, $this->get_definition()->get_id(), $misses);
}
return $return;

}
Expand Down Expand Up @@ -2011,10 +2038,11 @@ public function set_many(array $keyvaluearray) {
'value' => $value
);
}
if ($this->perfdebug) {
cache_helper::record_cache_set($this->storetype, $definitionid);
$successfullyset = $this->get_store()->set_many($data);
if ($this->perfdebug && $successfullyset) {
cache_helper::record_cache_set($this->storetype, $definitionid, $successfullyset);
}
return $this->get_store()->set_many($data);
return $successfullyset;
}

/**
Expand Down
67 changes: 23 additions & 44 deletions cache/locallib.php
Original file line number Diff line number Diff line change
Expand Up @@ -778,63 +778,36 @@ public static function get_store_plugin_summaries() {
* @return array
*/
public static function get_definition_summaries() {
$instance = cache_config::instance();
$definitions = $instance->get_definitions();

$factory = cache_factory::instance();
$config = $factory->create_config_instance();
$storenames = array();
foreach ($instance->get_all_stores() as $key => $store) {
foreach ($config->get_all_stores() as $key => $store) {
if (!empty($store['default'])) {
$storenames[$key] = new lang_string('store_'.$key, 'cache');
}
}

$modemappings = array();
foreach ($instance->get_mode_mappings() as $mapping) {
$mode = $mapping['mode'];
if (!array_key_exists($mode, $modemappings)) {
$modemappings[$mode] = array();
}
if (array_key_exists($mapping['store'], $storenames)) {
$modemappings[$mode][] = $storenames[$mapping['store']];
} else {
$modemappings[$mode][] = $mapping['store'];
$storenames[$store['name']] = $store['name'];
}
}

$definitionmappings = array();
foreach ($instance->get_definition_mappings() as $mapping) {
$definition = $mapping['definition'];
if (!array_key_exists($definition, $definitionmappings)) {
$definitionmappings[$definition] = array();
}
if (array_key_exists($mapping['store'], $storenames)) {
$definitionmappings[$definition][] = $storenames[$mapping['store']];
} else {
$definitionmappings[$definition][] = $mapping['store'];
}
/* @var cache_definition[] $definitions */
$definitions = array();
foreach ($config->get_definitions() as $key => $definition) {
$definitions[$key] = cache_definition::load($definition['component'].'/'.$definition['area'], $definition);
}

$return = array();

foreach ($definitions as $id => $definition) {

$mappings = array();
if (array_key_exists($id, $definitionmappings)) {
$mappings = $definitionmappings[$id];
} else if (empty($definition['mappingsonly'])) {
$mappings = $modemappings[$definition['mode']];
foreach (cache_helper::get_stores_suitable_for_definition($definition) as $store) {
$mappings[] = $storenames[$store->my_name()];
}

$return[$id] = array(
'id' => $id,
'name' => cache_helper::get_definition_name($definition),
'mode' => $definition['mode'],
'component' => $definition['component'],
'area' => $definition['area'],
'name' => $definition->get_name(),
'mode' => $definition->get_mode(),
'component' => $definition->get_component(),
'area' => $definition->get_area(),
'mappings' => $mappings,
'sharingoptions' => self::get_definition_sharing_options($definition['sharingoptions'], false),
'selectedsharingoption' => self::get_definition_sharing_options($definition['selectedsharingoption'], true),
'userinputsharingkey' => $definition['userinputsharingkey']
'sharingoptions' => self::get_definition_sharing_options($definition->get_sharing_options(), false),
'selectedsharingoption' => self::get_definition_sharing_options($definition->get_selected_sharing_option(), true),
'userinputsharingkey' => $definition->get_user_input_sharing_key()
);
}
return $return;
Expand Down Expand Up @@ -1126,7 +1099,10 @@ public static function get_definition_store_options($component, $area) {
* @return array An array containing sub-arrays, one for each mode.
*/
public static function get_default_mode_stores() {
global $OUTPUT;
$instance = cache_config::instance();
$adequatestores = cache_helper::get_stores_suitable_for_mode_default();
$icon = new pix_icon('i/warning', new lang_string('inadequatestoreformapping', 'cache'));
$storenames = array();
foreach ($instance->get_all_stores() as $key => $store) {
if (!empty($store['default'])) {
Expand All @@ -1149,6 +1125,9 @@ public static function get_default_mode_stores() {
} else {
$modemappings[$mode][$mapping['store']] = $mapping['store'];
}
if (!array_key_exists($mapping['store'], $adequatestores)) {
$modemappings[$mode][$mapping['store']] = $modemappings[$mode][$mapping['store']].' '.$OUTPUT->render($icon);
}
}
return $modemappings;
}
Expand Down
1 change: 1 addition & 0 deletions lang/en/cache.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
$string['ex_unmetstorerequirements'] = 'You are unable to use this store at the present time. Please refer to the documentation to determine its requirements.';
$string['gethit'] = 'Get - Hit';
$string['getmiss'] = 'Get - Miss';
$string['inadequatestoreformapping'] = 'This store doesn\'t meet the requirements for all known definitions. Definitions for which this store is inadequate will be given the original default store instead of the selected store.';
$string['invalidlock'] = 'Invalid lock';
$string['invalidplugin'] = 'Invalid plugin';
$string['invalidstore'] = 'Invalid cache store provided';
Expand Down

0 comments on commit ecfbb65

Please sign in to comment.