Differences Between: [Versions 310 and 402] [Versions 311 and 402] [Versions 39 and 402] [Versions 400 and 402]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * Extra information generated during the analysis by calculable elements. 19 * 20 * @package core_analytics 21 * @copyright 2019 David Monllao {@link http://www.davidmonllao.com} 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 namespace core_analytics; 26 27 defined('MOODLE_INTERNAL') || die(); 28 29 /** 30 * Extra information generated during the analysis by calculable elements. 31 * 32 * The main purpose of this request cache is to allow calculable elements to 33 * store data during their calculations for further use at a later stage efficiently. 34 * 35 * @package core_analytics 36 * @copyright 2019 David Monllao {@link http://www.davidmonllao.com} 37 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 38 */ 39 class calculation_info { 40 41 /** 42 * @var array 43 */ 44 private $info = []; 45 46 /** 47 * @var mixed[] 48 */ 49 private $samplesinfo = []; 50 51 /** 52 * Adds info related to the current calculation for later use when generating insights. 53 * 54 * Note that the data in $info array is reused across multiple samples, if you want to add data just for this 55 * sample you can use the sample id as key. 56 * 57 * We store two different arrays so objects that appear multiple times for different samples 58 * appear just once in memory. 59 * 60 * @param int $sampleid The sample id this data is associated with 61 * @param array $info The data. Indexed by an id unique across the site. E.g. an activity id. 62 * @return null 63 */ 64 public function add_shared(int $sampleid, array $info) { 65 66 // We can safely overwrite the existing keys because the provided info is supposed to be unique 67 // for the indicator. 68 $this->info = $info + $this->info; 69 70 // We also need to store the association between the info provided and the sample. 71 $this->samplesinfo[$sampleid] = array_keys($info); 72 } 73 74 /** 75 * Stores in MUC the previously added data and it associates it to the provided $calculable. 76 * 77 * @param \core_analytics\calculable $calculable 78 * @param \core_analytics\local\time_splitting\base $timesplitting 79 * @param int $rangeindex 80 * @return null 81 */ 82 public function save(\core_analytics\calculable $calculable, \core_analytics\local\time_splitting\base $timesplitting, 83 int $rangeindex) { 84 85 $calculableclass = get_class($calculable); 86 $cache = \cache::make('core', 'calculablesinfo'); 87 88 foreach ($this->info as $key => $value) { 89 $datakey = self::get_data_key($calculableclass, $key); 90 91 // We do not overwrite existing data. 92 if (!$cache->has($datakey)) { 93 $cache->set($datakey, $value); 94 } 95 } 96 97 foreach ($this->samplesinfo as $sampleid => $infokeys) { 98 $uniquesampleid = $timesplitting->append_rangeindex($sampleid, $rangeindex); 99 $samplekey = self::get_sample_key($uniquesampleid); 100 101 // Update the cached data adding the new indicator data. 102 $cacheddata = $cache->get($samplekey) ?: []; 103 $cacheddata[$calculableclass] = $infokeys; 104 $cache->set($samplekey, $cacheddata); 105 } 106 107 // Empty the in-memory arrays now that it is in the cache. 108 $this->info = []; 109 $this->samplesinfo = []; 110 } 111 112 /** 113 * Pulls the info related to the provided records out from the cache. 114 * 115 * Note that this function purges 'calculablesinfo' cache. 116 * 117 * @param \stdClass[] $predictionrecords 118 * @return array|false 119 */ 120 public static function pull_info(array $predictionrecords) { 121 122 $cache = \cache::make('core', 'calculablesinfo'); 123 124 foreach ($predictionrecords as $uniquesampleid => $predictionrecord) { 125 126 $sampleid = $predictionrecord->sampleid; 127 128 $sampleinfo = $cache->get(self::get_sample_key($uniquesampleid)); 129 130 // MUC returns (or should return) copies of the data and we want a single copy of it so 131 // we store the data here and reference it from each sample. Samples data should not be 132 // changed afterwards. 133 $data = []; 134 135 if ($sampleinfo) { 136 foreach ($sampleinfo as $calculableclass => $infokeys) { 137 138 foreach ($infokeys as $infokey) { 139 140 // We don't need to retrieve data back from MUC if we already have it. 141 if (!isset($data[$calculableclass][$infokey])) { 142 $datakey = self::get_data_key($calculableclass, $infokey); 143 $data[$calculableclass][$infokey] = $cache->get($datakey); 144 } 145 146 $samplesdatakey = $calculableclass . ':extradata'; 147 $samplesdata[$sampleid][$samplesdatakey][$infokey] = & $data[$calculableclass][$infokey]; 148 } 149 } 150 } 151 } 152 153 // Free memory ASAP. We can replace the purge call by a delete_many if we are interested on allowing 154 // multiple calls to pull_info passing in different $sampleids. 155 $cache->purge(); 156 157 if (empty($samplesdata)) { 158 return false; 159 } 160 161 return $samplesdata; 162 } 163 164 /** 165 * Gets the key used to store data. 166 * 167 * @param string $calculableclass 168 * @param string|int $key 169 * @return string 170 */ 171 private static function get_data_key(string $calculableclass, $key): string { 172 return 'data:' . $calculableclass . ':' . $key; 173 } 174 175 /** 176 * Gets the key used to store samples. 177 * 178 * @param string $uniquesampleid 179 * @return string 180 */ 181 private static function get_sample_key(string $uniquesampleid): string { 182 return 'sample:' . $uniquesampleid; 183 } 184 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body