MDL-68329 cache: Improve cache performance footer info

This commit is contained in:
Brendan Heywood
2020-04-28 10:08:28 +10:00
parent 9df4a4de18
commit 9f4bb48e40
6 changed files with 265 additions and 105 deletions
+32 -7
View File
@@ -361,20 +361,23 @@ class cache_helper {
/**
* Ensure that the stats array is ready to collect information for the given store and definition.
* @param string $store
* @param string $storeclass
* @param string $definition A string that identifies the definition.
* @param int $mode One of cache_store::MODE_*. Since 2.9.
*/
protected static function ensure_ready_for_stats($store, $definition, $mode = cache_store::MODE_APPLICATION) {
protected static function ensure_ready_for_stats($store, $storeclass, $definition, $mode = cache_store::MODE_APPLICATION) {
// This function is performance-sensitive, so exit as quickly as possible
// if we do not need to do anything.
if (isset(self::$stats[$definition]['stores'][$store])) {
return;
}
if (!array_key_exists($definition, self::$stats)) {
self::$stats[$definition] = array(
'mode' => $mode,
'stores' => array(
$store => array(
'class' => $storeclass,
'hits' => 0,
'misses' => 0,
'sets' => 0,
@@ -383,6 +386,7 @@ class cache_helper {
);
} else if (!array_key_exists($store, self::$stats[$definition]['stores'])) {
self::$stats[$definition]['stores'][$store] = array(
'class' => $storeclass,
'hits' => 0,
'misses' => 0,
'sets' => 0,
@@ -418,15 +422,22 @@ class cache_helper {
* In Moodle 2.9 the $definition argument changed from accepting only a string to accepting a string or a
* cache_definition instance. It is preferable to pass a cache definition instance.
*
* In Moodle 3.9 the first argument changed to also accept a cache_store.
*
* @internal
* @param cache_definition $store
* @param string|cache_store $store
* @param cache_definition $definition You used to be able to pass a string here, however that is deprecated please pass the
* actual cache_definition object now.
* @param int $hits The number of hits to record (by default 1)
*/
public static function record_cache_hit($store, $definition, $hits = 1) {
$storeclass = '';
if ($store instanceof cache_store) {
$storeclass = get_class($store);
$store = $store->my_name();
}
list($definitionstr, $mode) = self::get_definition_stat_id_and_mode($definition);
self::ensure_ready_for_stats($store, $definitionstr, $mode);
self::ensure_ready_for_stats($store, $storeclass, $definitionstr, $mode);
self::$stats[$definitionstr]['stores'][$store]['hits'] += $hits;
}
@@ -436,15 +447,22 @@ class cache_helper {
* In Moodle 2.9 the $definition argument changed from accepting only a string to accepting a string or a
* cache_definition instance. It is preferable to pass a cache definition instance.
*
* In Moodle 3.9 the first argument changed to also accept a cache_store.
*
* @internal
* @param string $store
* @param string|cache_store $store
* @param cache_definition $definition You used to be able to pass a string here, however that is deprecated please pass the
* actual cache_definition object now.
* @param int $misses The number of misses to record (by default 1)
*/
public static function record_cache_miss($store, $definition, $misses = 1) {
$storeclass = '';
if ($store instanceof cache_store) {
$storeclass = get_class($store);
$store = $store->my_name();
}
list($definitionstr, $mode) = self::get_definition_stat_id_and_mode($definition);
self::ensure_ready_for_stats($store, $definitionstr, $mode);
self::ensure_ready_for_stats($store, $storeclass, $definitionstr, $mode);
self::$stats[$definitionstr]['stores'][$store]['misses'] += $misses;
}
@@ -454,15 +472,22 @@ class cache_helper {
* In Moodle 2.9 the $definition argument changed from accepting only a string to accepting a string or a
* cache_definition instance. It is preferable to pass a cache definition instance.
*
* In Moodle 3.9 the first argument changed to also accept a cache_store.
*
* @internal
* @param string $store
* @param string|cache_store $store
* @param cache_definition $definition You used to be able to pass a string here, however that is deprecated please pass the
* actual cache_definition object now.
* @param int $sets The number of sets to record (by default 1)
*/
public static function record_cache_set($store, $definition, $sets = 1) {
$storeclass = '';
if ($store instanceof cache_store) {
$storeclass = get_class($store);
$store = $store->my_name();
}
list($definitionstr, $mode) = self::get_definition_stat_id_and_mode($definition);
self::ensure_ready_for_stats($store, $definitionstr, $mode);
self::ensure_ready_for_stats($store, $storeclass, $definitionstr, $mode);
self::$stats[$definitionstr]['stores'][$store]['sets'] += $sets;
}
+14 -14
View File
@@ -414,7 +414,7 @@ class cache implements cache_loader {
$setaftervalidation = false;
if ($result === false) {
if ($this->perfdebug) {
cache_helper::record_cache_miss($this->storetype, $this->definition);
cache_helper::record_cache_miss($this->store, $this->definition);
}
if ($this->loader !== false) {
// We must pass the original (unparsed) key to the next loader in the chain.
@@ -426,7 +426,7 @@ class cache implements cache_loader {
}
$setaftervalidation = ($result !== false);
} else if ($this->perfdebug) {
cache_helper::record_cache_hit($this->storetype, $this->definition);
cache_helper::record_cache_hit($this->store, $this->definition);
}
// 5. Validate strictness.
if ($strictness === MUST_EXIST && $result === false) {
@@ -580,8 +580,8 @@ class cache implements cache_loader {
$hits++;
}
}
cache_helper::record_cache_hit($this->storetype, $this->definition, $hits);
cache_helper::record_cache_miss($this->storetype, $this->definition, $misses);
cache_helper::record_cache_hit($this->store, $this->definition, $hits);
cache_helper::record_cache_miss($this->store, $this->definition, $misses);
}
// Return the result. Phew!
@@ -607,7 +607,7 @@ class cache implements cache_loader {
*/
public function set($key, $data) {
if ($this->perfdebug) {
cache_helper::record_cache_set($this->storetype, $this->definition);
cache_helper::record_cache_set($this->store, $this->definition);
}
if ($this->loader !== false) {
// We have a loader available set it there as well.
@@ -762,7 +762,7 @@ class cache implements cache_loader {
}
$successfullyset = $this->store->set_many($data);
if ($this->perfdebug && $successfullyset) {
cache_helper::record_cache_set($this->storetype, $this->definition, $successfullyset);
cache_helper::record_cache_set($this->store, $this->definition, $successfullyset);
}
return $successfullyset;
}
@@ -1112,7 +1112,7 @@ class cache implements cache_loader {
}
if ($result !== false) {
if ($this->perfdebug) {
cache_helper::record_cache_hit('** static acceleration **', $this->definition);
cache_helper::record_cache_hit(cache_store::STATIC_ACCEL, $this->definition);
}
if ($this->staticaccelerationsize > 1 && $this->staticaccelerationcount > 1) {
// Check to see if this is the last item on the static acceleration keys array.
@@ -1126,7 +1126,7 @@ class cache implements cache_loader {
return $result;
} else {
if ($this->perfdebug) {
cache_helper::record_cache_miss('** static acceleration **', $this->definition);
cache_helper::record_cache_miss(cache_store::STATIC_ACCEL, $this->definition);
}
return false;
}
@@ -1830,7 +1830,7 @@ class cache_session extends cache {
// 4. Load if from the loader/datasource if we don't already have it.
if ($result === false) {
if ($this->perfdebug) {
cache_helper::record_cache_miss($this->storetype, $this->get_definition());
cache_helper::record_cache_miss($this->get_store(), $this->get_definition());
}
if ($this->get_loader() !== false) {
// We must pass the original (unparsed) key to the next loader in the chain.
@@ -1845,7 +1845,7 @@ class cache_session extends cache {
$this->set($key, $result);
}
} else if ($this->perfdebug) {
cache_helper::record_cache_hit($this->storetype, $this->get_definition());
cache_helper::record_cache_hit($this->get_store(), $this->get_definition());
}
// 5. Validate strictness.
if ($strictness === MUST_EXIST && $result === false) {
@@ -1889,7 +1889,7 @@ class cache_session extends cache {
$loader->set($key, $data);
}
if ($this->perfdebug) {
cache_helper::record_cache_set($this->storetype, $this->get_definition());
cache_helper::record_cache_set($this->get_store(), $this->get_definition());
}
if (is_object($data) && $data instanceof cacheable_object) {
$data = new cache_cached_object($data);
@@ -2019,8 +2019,8 @@ class cache_session extends cache {
$hits++;
}
}
cache_helper::record_cache_hit($this->storetype, $this->get_definition(), $hits);
cache_helper::record_cache_miss($this->storetype, $this->get_definition(), $misses);
cache_helper::record_cache_hit($this->get_store(), $this->get_definition(), $hits);
cache_helper::record_cache_miss($this->get_store(), $this->get_definition(), $misses);
}
return $return;
@@ -2097,7 +2097,7 @@ class cache_session extends cache {
}
$successfullyset = $this->get_store()->set_many($data);
if ($this->perfdebug && $successfullyset) {
cache_helper::record_cache_set($this->storetype, $this->get_definition(), $successfullyset);
cache_helper::record_cache_set($this->store, $this->get_definition(), $successfullyset);
}
return $successfullyset;
}
+4
View File
@@ -144,6 +144,10 @@ abstract class cache_store implements cache_store_interface {
* Request caches. Static caches really.
*/
const MODE_REQUEST = 4;
/**
* Static caches.
*/
const STATIC_ACCEL = '** static accel. **';
/**
* Constructs an instance of the cache store.
+65 -65
View File
@@ -2092,15 +2092,15 @@ class core_cache_testcase extends advanced_testcase {
$this->assertFalse($request->get('missMe'));
$endstats = cache_helper::get_stats();
$this->assertEquals(2, $endstats[$applicationid]['stores']['cachestore_file']['misses']);
$this->assertEquals(0, $endstats[$applicationid]['stores']['cachestore_file']['hits']);
$this->assertEquals(0, $endstats[$applicationid]['stores']['cachestore_file']['sets']);
$this->assertEquals(3, $endstats[$sessionid]['stores']['cachestore_session']['misses']);
$this->assertEquals(0, $endstats[$sessionid]['stores']['cachestore_session']['hits']);
$this->assertEquals(1, $endstats[$sessionid]['stores']['cachestore_session']['sets']);
$this->assertEquals(4, $endstats[$requestid]['stores']['cachestore_static']['misses']);
$this->assertEquals(0, $endstats[$requestid]['stores']['cachestore_static']['hits']);
$this->assertEquals(0, $endstats[$requestid]['stores']['cachestore_static']['sets']);
$this->assertEquals(2, $endstats[$applicationid]['stores']['default_application']['misses']);
$this->assertEquals(0, $endstats[$applicationid]['stores']['default_application']['hits']);
$this->assertEquals(0, $endstats[$applicationid]['stores']['default_application']['sets']);
$this->assertEquals(3, $endstats[$sessionid]['stores']['default_session']['misses']);
$this->assertEquals(0, $endstats[$sessionid]['stores']['default_session']['hits']);
$this->assertEquals(1, $endstats[$sessionid]['stores']['default_session']['sets']);
$this->assertEquals(4, $endstats[$requestid]['stores']['default_request']['misses']);
$this->assertEquals(0, $endstats[$requestid]['stores']['default_request']['hits']);
$this->assertEquals(0, $endstats[$requestid]['stores']['default_request']['sets']);
$startstats = cache_helper::get_stats();
@@ -2116,24 +2116,24 @@ class core_cache_testcase extends advanced_testcase {
$this->assertTrue($request->set('setMe4', 4));
$endstats = cache_helper::get_stats();
$this->assertEquals(0, $endstats[$applicationid]['stores']['cachestore_file']['misses'] -
$startstats[$applicationid]['stores']['cachestore_file']['misses']);
$this->assertEquals(0, $endstats[$applicationid]['stores']['cachestore_file']['hits'] -
$startstats[$applicationid]['stores']['cachestore_file']['hits']);
$this->assertEquals(2, $endstats[$applicationid]['stores']['cachestore_file']['sets'] -
$startstats[$applicationid]['stores']['cachestore_file']['sets']);
$this->assertEquals(0, $endstats[$sessionid]['stores']['cachestore_session']['misses'] -
$startstats[$sessionid]['stores']['cachestore_session']['misses']);
$this->assertEquals(0, $endstats[$sessionid]['stores']['cachestore_session']['hits'] -
$startstats[$sessionid]['stores']['cachestore_session']['hits']);
$this->assertEquals(3, $endstats[$sessionid]['stores']['cachestore_session']['sets'] -
$startstats[$sessionid]['stores']['cachestore_session']['sets']);
$this->assertEquals(0, $endstats[$requestid]['stores']['cachestore_static']['misses'] -
$startstats[$requestid]['stores']['cachestore_static']['misses']);
$this->assertEquals(0, $endstats[$requestid]['stores']['cachestore_static']['hits'] -
$startstats[$requestid]['stores']['cachestore_static']['hits']);
$this->assertEquals(4, $endstats[$requestid]['stores']['cachestore_static']['sets'] -
$startstats[$requestid]['stores']['cachestore_static']['sets']);
$this->assertEquals(0, $endstats[$applicationid]['stores']['default_application']['misses'] -
$startstats[$applicationid]['stores']['default_application']['misses']);
$this->assertEquals(0, $endstats[$applicationid]['stores']['default_application']['hits'] -
$startstats[$applicationid]['stores']['default_application']['hits']);
$this->assertEquals(2, $endstats[$applicationid]['stores']['default_application']['sets'] -
$startstats[$applicationid]['stores']['default_application']['sets']);
$this->assertEquals(0, $endstats[$sessionid]['stores']['default_session']['misses'] -
$startstats[$sessionid]['stores']['default_session']['misses']);
$this->assertEquals(0, $endstats[$sessionid]['stores']['default_session']['hits'] -
$startstats[$sessionid]['stores']['default_session']['hits']);
$this->assertEquals(3, $endstats[$sessionid]['stores']['default_session']['sets'] -
$startstats[$sessionid]['stores']['default_session']['sets']);
$this->assertEquals(0, $endstats[$requestid]['stores']['default_request']['misses'] -
$startstats[$requestid]['stores']['default_request']['misses']);
$this->assertEquals(0, $endstats[$requestid]['stores']['default_request']['hits'] -
$startstats[$requestid]['stores']['default_request']['hits']);
$this->assertEquals(4, $endstats[$requestid]['stores']['default_request']['sets'] -
$startstats[$requestid]['stores']['default_request']['sets']);
$startstats = cache_helper::get_stats();
@@ -2149,24 +2149,24 @@ class core_cache_testcase extends advanced_testcase {
$this->assertEquals($request->get('setMe4'), 4);
$endstats = cache_helper::get_stats();
$this->assertEquals(0, $endstats[$applicationid]['stores']['cachestore_file']['misses'] -
$startstats[$applicationid]['stores']['cachestore_file']['misses']);
$this->assertEquals(2, $endstats[$applicationid]['stores']['cachestore_file']['hits'] -
$startstats[$applicationid]['stores']['cachestore_file']['hits']);
$this->assertEquals(0, $endstats[$applicationid]['stores']['cachestore_file']['sets'] -
$startstats[$applicationid]['stores']['cachestore_file']['sets']);
$this->assertEquals(0, $endstats[$sessionid]['stores']['cachestore_session']['misses'] -
$startstats[$sessionid]['stores']['cachestore_session']['misses']);
$this->assertEquals(3, $endstats[$sessionid]['stores']['cachestore_session']['hits'] -
$startstats[$sessionid]['stores']['cachestore_session']['hits']);
$this->assertEquals(0, $endstats[$sessionid]['stores']['cachestore_session']['sets'] -
$startstats[$sessionid]['stores']['cachestore_session']['sets']);
$this->assertEquals(0, $endstats[$requestid]['stores']['cachestore_static']['misses'] -
$startstats[$requestid]['stores']['cachestore_static']['misses']);
$this->assertEquals(4, $endstats[$requestid]['stores']['cachestore_static']['hits'] -
$startstats[$requestid]['stores']['cachestore_static']['hits']);
$this->assertEquals(0, $endstats[$requestid]['stores']['cachestore_static']['sets'] -
$startstats[$requestid]['stores']['cachestore_static']['sets']);
$this->assertEquals(0, $endstats[$applicationid]['stores']['default_application']['misses'] -
$startstats[$applicationid]['stores']['default_application']['misses']);
$this->assertEquals(2, $endstats[$applicationid]['stores']['default_application']['hits'] -
$startstats[$applicationid]['stores']['default_application']['hits']);
$this->assertEquals(0, $endstats[$applicationid]['stores']['default_application']['sets'] -
$startstats[$applicationid]['stores']['default_application']['sets']);
$this->assertEquals(0, $endstats[$sessionid]['stores']['default_session']['misses'] -
$startstats[$sessionid]['stores']['default_session']['misses']);
$this->assertEquals(3, $endstats[$sessionid]['stores']['default_session']['hits'] -
$startstats[$sessionid]['stores']['default_session']['hits']);
$this->assertEquals(0, $endstats[$sessionid]['stores']['default_session']['sets'] -
$startstats[$sessionid]['stores']['default_session']['sets']);
$this->assertEquals(0, $endstats[$requestid]['stores']['default_request']['misses'] -
$startstats[$requestid]['stores']['default_request']['misses']);
$this->assertEquals(4, $endstats[$requestid]['stores']['default_request']['hits'] -
$startstats[$requestid]['stores']['default_request']['hits']);
$this->assertEquals(0, $endstats[$requestid]['stores']['default_request']['sets'] -
$startstats[$requestid]['stores']['default_request']['sets']);
$startstats = cache_helper::get_stats();
@@ -2176,24 +2176,24 @@ class core_cache_testcase extends advanced_testcase {
$request->get_many(array('setMe1', 'setMe2', 'setMe3', 'setMe4'));
$endstats = cache_helper::get_stats();
$this->assertEquals(0, $endstats[$applicationid]['stores']['cachestore_file']['misses'] -
$startstats[$applicationid]['stores']['cachestore_file']['misses']);
$this->assertEquals(2, $endstats[$applicationid]['stores']['cachestore_file']['hits'] -
$startstats[$applicationid]['stores']['cachestore_file']['hits']);
$this->assertEquals(0, $endstats[$applicationid]['stores']['cachestore_file']['sets'] -
$startstats[$applicationid]['stores']['cachestore_file']['sets']);
$this->assertEquals(0, $endstats[$sessionid]['stores']['cachestore_session']['misses'] -
$startstats[$sessionid]['stores']['cachestore_session']['misses']);
$this->assertEquals(3, $endstats[$sessionid]['stores']['cachestore_session']['hits'] -
$startstats[$sessionid]['stores']['cachestore_session']['hits']);
$this->assertEquals(0, $endstats[$sessionid]['stores']['cachestore_session']['sets'] -
$startstats[$sessionid]['stores']['cachestore_session']['sets']);
$this->assertEquals(0, $endstats[$requestid]['stores']['cachestore_static']['misses'] -
$startstats[$requestid]['stores']['cachestore_static']['misses']);
$this->assertEquals(4, $endstats[$requestid]['stores']['cachestore_static']['hits'] -
$startstats[$requestid]['stores']['cachestore_static']['hits']);
$this->assertEquals(0, $endstats[$requestid]['stores']['cachestore_static']['sets'] -
$startstats[$requestid]['stores']['cachestore_static']['sets']);
$this->assertEquals(0, $endstats[$applicationid]['stores']['default_application']['misses'] -
$startstats[$applicationid]['stores']['default_application']['misses']);
$this->assertEquals(2, $endstats[$applicationid]['stores']['default_application']['hits'] -
$startstats[$applicationid]['stores']['default_application']['hits']);
$this->assertEquals(0, $endstats[$applicationid]['stores']['default_application']['sets'] -
$startstats[$applicationid]['stores']['default_application']['sets']);
$this->assertEquals(0, $endstats[$sessionid]['stores']['default_session']['misses'] -
$startstats[$sessionid]['stores']['default_session']['misses']);
$this->assertEquals(3, $endstats[$sessionid]['stores']['default_session']['hits'] -
$startstats[$sessionid]['stores']['default_session']['hits']);
$this->assertEquals(0, $endstats[$sessionid]['stores']['default_session']['sets'] -
$startstats[$sessionid]['stores']['default_session']['sets']);
$this->assertEquals(0, $endstats[$requestid]['stores']['default_request']['misses'] -
$startstats[$requestid]['stores']['default_request']['misses']);
$this->assertEquals(4, $endstats[$requestid]['stores']['default_request']['hits'] -
$startstats[$requestid]['stores']['default_request']['hits']);
$this->assertEquals(0, $endstats[$requestid]['stores']['default_request']['sets'] -
$startstats[$requestid]['stores']['default_request']['sets']);
}
public function test_static_cache() {
@@ -2225,8 +2225,8 @@ class core_cache_testcase extends advanced_testcase {
// Check that the static acceleration worked, even on empty arrays and the number 0.
$endstats = cache_helper::get_stats();
$this->assertEquals(0, $endstats[$applicationid]['stores']['** static acceleration **']['misses']);
$this->assertEquals(3, $endstats[$applicationid]['stores']['** static acceleration **']['hits']);
$this->assertEquals(0, $endstats[$applicationid]['stores']['** static accel. **']['misses']);
$this->assertEquals(3, $endstats[$applicationid]['stores']['** static accel. **']['hits']);
}
public function test_performance_debug_off() {
+3
View File
@@ -1,6 +1,9 @@
This files describes API changes in /cache/stores/* - cache store plugins.
Information provided here is intended especially for developers.
=== 3.9 ===
* The record_cache_hit/miss/set methods now take a cache_store instead of a cache_definition object
=== 3.8 ===
* The Redis cache store can now make use of the Zstandard compression algorithm (see MDL-66428).
+147 -19
View File
@@ -9546,37 +9546,83 @@ function get_performance_info() {
}
$info['html'] .= '</ul>';
$html = '';
if ($stats = cache_helper::get_stats()) {
$html = '<ul class="cachesused list-unstyled ml-1 row">';
$html .= '<li class="cache-stats-heading font-weight-bold">Caches used (hits/misses/sets)</li>';
$html .= '</ul><ul class="cachesused list-unstyled ml-1">';
$table = new html_table();
$table->attributes['class'] = 'cachesused table table-dark table-sm w-auto table-striped';
$table->head = ['Mode', 'Cache item', 'Static', 'H', 'M', get_string('mappingprimary', 'cache'), 'H', 'M', 'S'];
$table->data = [];
$table->align = ['left', 'left', 'left', 'right', 'right', 'left', 'right', 'right', 'right'];
$text = 'Caches used (hits/misses/sets): ';
$hits = 0;
$misses = 0;
$sets = 0;
$maxstores = 0;
// We want to align static caches into their own column.
$hasstatic = false;
foreach ($stats as $definition => $details) {
$numstores = count($details['stores']);
$first = key($details['stores']);
if ($first !== cache_store::STATIC_ACCEL) {
$numstores++; // Add a blank space for the missing static store.
}
$maxstores = max($maxstores, $numstores);
}
$storec = 0;
while ($storec++ < ($maxstores - 2)) {
if ($storec == ($maxstores - 2)) {
$table->head[] = get_string('mappingfinal', 'cache');
} else {
$table->head[] = "Store $storec";
}
$table->align[] = 'left';
$table->align[] = 'right';
$table->align[] = 'right';
$table->align[] = 'right';
$table->head[] = 'H';
$table->head[] = 'M';
$table->head[] = 'S';
}
ksort($stats);
foreach ($stats as $definition => $details) {
switch ($details['mode']) {
case cache_store::MODE_APPLICATION:
$modeclass = 'application';
$mode = ' <span title="application cache">[a]</span>';
$mode = ' <span title="application cache">App</span>';
break;
case cache_store::MODE_SESSION:
$modeclass = 'session';
$mode = ' <span title="session cache">[s]</span>';
$mode = ' <span title="session cache">Ses</span>';
break;
case cache_store::MODE_REQUEST:
$modeclass = 'request';
$mode = ' <span title="request cache">[r]</span>';
$mode = ' <span title="request cache">Req</span>';
break;
}
$html .= '<li class="d-inline-flex"><ul class="cache-definition-stats list-unstyled ml-1 mb-1 cache-mode-'.$modeclass.' card d-inline-block">';
$html .= '<li class="cache-definition-stats-heading p-t-1 card-header bg-dark bg-inverse font-weight-bold">' .
$definition . $mode.'</li>';
$row = [$mode, $definition];
$text .= "$definition {";
$storec = 0;
foreach ($details['stores'] as $store => $data) {
$hits += $data['hits'];
if ($storec == 0 && $store !== cache_store::STATIC_ACCEL) {
$row[] = '';
$row[] = '';
$row[] = '';
$storec++;
}
$hits += $data['hits'];
$misses += $data['misses'];
$sets += $data['sets'];
$sets += $data['sets'];
if ($data['hits'] == 0 and $data['misses'] > 0) {
$cachestoreclass = 'nohits text-danger';
} else if ($data['hits'] < $data['misses']) {
@@ -9585,18 +9631,100 @@ function get_performance_info() {
$cachestoreclass = 'hihits text-success';
}
$text .= "$store($data[hits]/$data[misses]/$data[sets]) ";
$html .= "<li class=\"cache-store-stats $cachestoreclass p-x-1\">" .
"$store: $data[hits] / $data[misses] / $data[sets]</li>";
// This makes boxes of same sizes.
if (count($details['stores']) == 1) {
$html .= "<li class=\"cache-store-stats $cachestoreclass p-x-1\">&nbsp;</li>";
$cell = new html_table_cell($store);
$cell->attributes = ['class' => $cachestoreclass];
$row[] = $cell;
$cell = new html_table_cell($data['hits']);
$cell->attributes = ['class' => $cachestoreclass];
$row[] = $cell;
$cell = new html_table_cell($data['misses']);
$cell->attributes = ['class' => $cachestoreclass];
$row[] = $cell;
if ($store !== cache_store::STATIC_ACCEL) {
// The static cache is never set.
$cell = new html_table_cell($data['sets']);
$cell->attributes = ['class' => $cachestoreclass];
$row[] = $cell;
}
$storec++;
}
while ($storec++ < $maxstores) {
$row[] = '';
$row[] = '';
$row[] = '';
$row[] = '';
}
$html .= '</ul></li>';
$text .= '} ';
$table->data[] = $row;
}
$html .= '</ul> ';
$html .= "<div class='cache-total-stats row'>Total: $hits / $misses / $sets</div>";
$html .= html_writer::table($table);
// Now lets also show sub totals for each cache store.
$storetotals = [];
$storetotal = ['hits' => 0, 'misses' => 0, 'sets' => 0];
foreach ($stats as $definition => $details) {
foreach ($details['stores'] as $store => $data) {
if (!array_key_exists($store, $storetotals)) {
$storetotals[$store] = ['hits' => 0, 'misses' => 0, 'sets' => 0];
}
$storetotals[$store]['class'] = $data['class'];
$storetotals[$store]['hits'] += $data['hits'];
$storetotals[$store]['misses'] += $data['misses'];
$storetotals[$store]['sets'] += $data['sets'];
$storetotal['hits'] += $data['hits'];
$storetotal['misses'] += $data['misses'];
$storetotal['sets'] += $data['sets'];
}
}
$table = new html_table();
$table->attributes['class'] = 'cachesused table table-dark table-sm w-auto table-striped';
$table->head = [get_string('storename', 'cache'), get_string('type_cachestore', 'plugin'), 'H', 'M', 'S'];
$table->data = [];
$table->align = ['left', 'left', 'right', 'right', 'right'];
ksort($storetotals);
foreach ($storetotals as $store => $data) {
$row = [];
if ($data['hits'] == 0 and $data['misses'] > 0) {
$cachestoreclass = 'nohits text-danger';
} else if ($data['hits'] < $data['misses']) {
$cachestoreclass = 'lowhits text-warning';
} else {
$cachestoreclass = 'hihits text-success';
}
$cell = new html_table_cell($store);
$cell->attributes = ['class' => $cachestoreclass];
$row[] = $cell;
$cell = new html_table_cell($data['class']);
$cell->attributes = ['class' => $cachestoreclass];
$row[] = $cell;
$cell = new html_table_cell($data['hits']);
$cell->attributes = ['class' => $cachestoreclass];
$row[] = $cell;
$cell = new html_table_cell($data['misses']);
$cell->attributes = ['class' => $cachestoreclass];
$row[] = $cell;
$cell = new html_table_cell($data['sets']);
$cell->attributes = ['class' => $cachestoreclass];
$row[] = $cell;
$table->data[] = $row;
}
$row = [
get_string('total'),
'',
$storetotal['hits'],
$storetotal['misses'],
$storetotal['sets'],
];
$table->data[] = $row;
$html .= html_writer::table($table);
$info['cachesused'] = "$hits / $misses / $sets";
$info['html'] .= $html;
$info['txt'] .= $text.'. ';