Some micro-optimisations for Config

This commit is contained in:
Hamish Friedlander 2013-03-04 09:25:23 +13:00
parent 80bd38e1e9
commit a6f1a200b6
2 changed files with 53 additions and 30 deletions

View File

@ -493,7 +493,7 @@ class Config {
*/
public function get($class, $name, $sourceOptions = 0, &$result = null, $suppress = null) {
// Have we got a cached value? Use it if so
$key = sha1($class.$name.$sourceOptions);
$key = $class.$name.$sourceOptions;
if (($result = $this->cache->get($key)) === false) {
$tags = array();
@ -599,6 +599,13 @@ class Config_LRU {
public function __construct() {
$this->cache = new SplFixedArray(self::SIZE);
// Pre-fill with stdClass instances. By reusing we avoid object-thrashing
for ($i = 0; $i < self::SIZE; $i++) {
$this->cache[$i] = new stdClass();
$this->cache[$i]->key = null;
}
$this->indexing = array();
}
@ -614,7 +621,7 @@ class Config_LRU {
if (!($i--)) $i = self::SIZE-1;
$item = $this->cache[$i];
if (!$item) { $replacing = null; break; }
if ($item->key === null) { $replacing = null; break; }
else if ($item->c <= $target) { $replacing = $item; break; }
}
while ($i != $stop);
@ -622,8 +629,8 @@ class Config_LRU {
if ($replacing) unset($this->indexing[$replacing->key]);
$this->indexing[$key] = $this->i = $i;
$this->cache[$i] = $obj = new stdClass();
$obj = $this->cache[$i];
$obj->key = $key;
$obj->value = $val;
$obj->tags = $tags;
@ -653,14 +660,14 @@ class Config_LRU {
public function clean($tag = null) {
if ($tag) {
foreach ($this->cache as $i => $v) {
if ($v && in_array($tag, $v->tags)) {
if ($v->key !== null && in_array($tag, $v->tags)) {
unset($this->indexing[$v->key]);
$this->cache[$i] = null;
$this->cache[$i]->key = null;
}
}
}
else {
$this->cache = new SplFixedArray(self::SIZE);
for ($i = 0; $i < self::SIZE; $i++) $this->cache[$i]->key = null;
$this->indexing = array();
}
}

View File

@ -23,9 +23,7 @@ class SS_ConfigStaticManifest {
protected $statics;
static protected $initial_classes = array(
'Object', 'ViewableData', 'Injector', 'Director',
'RequestHandler', 'Controller', 'ContentController',
'DataObject', 'SiteTree', 'Extension', 'DataExtension', 'Hierarchy', 'Versioned'
'Object', 'ViewableData', 'Injector', 'Director'
);
/**
@ -64,7 +62,10 @@ class SS_ConfigStaticManifest {
if (!isset($this->statics[$class])) {
if (isset($this->index[$class])) {
$info = $this->index[$class];
$this->statics[$class] = $this->cache->load($this->key.'_'.sha1($class));
if ($details = $this->cache->load($this->key.'_'.$info['base'])) {
$this->statics += $details;
}
if (!isset($this->statics[$class])) {
$this->handleFile(null, $info['path'], null);
@ -75,16 +76,16 @@ class SS_ConfigStaticManifest {
}
}
$statics = $this->statics;
if (isset($this->statics[$class][$name])) {
$static = $this->statics[$class][$name];
if (isset($statics[$class]) && $statics[$class] && array_key_exists($name, $statics[$class])) {
if ($statics[$class][$name]['access'] != T_PRIVATE) {
if ($static['access'] != T_PRIVATE) {
Deprecation::notice('3.1.0', "Config static $class::\$$name must be marked as private", Deprecation::SCOPE_GLOBAL);
// Don't warn more than once per static
$this->statics[$class][$name]['access'] = T_PRIVATE;
$static['access'] = T_PRIVATE;
}
return $statics[$class][$name]['value'];
return $static['value'];
}
return $default;
@ -106,22 +107,37 @@ class SS_ConfigStaticManifest {
$finder->find($this->base);
$index = array('$statics' => array());
foreach ($this->statics as $class => $details) {
$this->cache->save($details, $this->key.'_'.sha1($class));
$index[$class] = array(
'path' => $details['path'],
'mtime' => filemtime($details['path'])
);
if (in_array($class, self::$initial_classes)) {
$index['$statics'][$class] = $details;
}
}
if($cache) {
$index = array('$statics' => array());
$bases = array();
foreach ($this->statics as $class => $details) {
if (in_array($class, self::$initial_classes)) {
$index['$statics'][$class] = $details;
}
else {
$base = $class;
do {
$parent = get_parent_class($base);
}
while ($parent != 'Object' && $parent != 'ViewableData' && $parent && ($base = $parent));
$base = sha1($base);
$bases[$base][$class] = $details;
$index[$class] = array(
'base' => $base,
'path' => $details['path'],
'mtime' => filemtime($details['path']),
);
}
}
foreach ($bases as $base => $details) {
$this->cache->save($details, $this->key.'_'.$base);
}
$this->cache->save($index, $this->key);
}
}