Better handling of cached file map

This commit is contained in:
Pavel Shevaev 2025-04-17 11:38:51 +03:00
parent 7b6d342469
commit c4ca9831f1
3 changed files with 50 additions and 34 deletions

View File

@ -289,7 +289,11 @@ class ConfigCacheFileMap
function update(array $added, array $removed)
{
foreach($added as $file)
$this->file2deps[$file] = [];
{
//TODO: are we sure about this check?
if(isset($this->file2deps[$file]))
$this->file2deps[$file] = [];
}
foreach($removed as $file)
unset($this->file2deps[$file]);
}
@ -361,6 +365,8 @@ class ConfigCacheUpdateParams
function splitFilesByChunks(int $max_workers, bool $sort = true) : array
{
$flat = $this->affected_files->getFlatArray();
if(!$flat)
return array();
if($sort)
usort($flat, fn($a, $b) => $a[1] <=> $b[1]);

View File

@ -75,13 +75,19 @@ class ConfigManager
}
function getFileMap() : ConfigCacheFileMap
{
return $this->_getFileMap(null);
}
private function _getFileMap(?ConfigDirFiles $files = null) : ConfigCacheFileMap
{
if($this->file_map === null)
{
$map = $this->_tryLoadMap();
if($map === null)
$map = $this->_makeMap($this->scanFiles(extension: '.js'));
$map = self::_makeMap($files ?? $this->scanFiles(extension: '.js'));
$this->file_map = $map;
$this->_saveFileMap();
}
return $this->file_map;
}
@ -103,7 +109,7 @@ class ConfigManager
$added_files = [];
$removed_files = [];
$fs_cache_map = $this->_checkFileMap(
$this->_checkFileMap(
$update_mode,
$input_files,
$added_files,
@ -113,7 +119,6 @@ class ConfigManager
$affected_files = $this->_getAffectedFiles(
$update_mode,
$result_bundle_file,
$fs_cache_map,
$input_files,
$removed_files
);
@ -121,6 +126,8 @@ class ConfigManager
//NOTE: at this poine taking into account only config files
$affected_files->filter(fn($file) => str_ends_with($file, '.conf.js'));
config_log("Affected files: {$affected_files->count()}");
$update_params = new ConfigCacheUpdateParams(
globals: $this->globals,
affected_files: $affected_files,
@ -131,6 +138,8 @@ class ConfigManager
$this->cache->clear();
$fs_cache_map = $this->getFileMap();
//TODO: traverse all affected files and update file map
foreach($affected_files as $file)
{
@ -141,39 +150,27 @@ class ConfigManager
if($affected_files->count() > 0 || $added_files || $removed_files)
{
$fs_cache_map->update($added_files, $removed_files);
$this->_saveMap($fs_cache_map);
$this->_saveFileMap();
}
return $update_result;
}
private function _checkFileMap(ConfigUpdateMode $update_mode, ConfigDirFiles $input_files, array &$added_files, array &$removed_files) : ConfigCacheFileMap
private function _checkFileMap(ConfigUpdateMode $update_mode, ConfigDirFiles $input_files, array &$added_files, array &$removed_files)
{
$fs_cache_map = $this->file_map;
//NOTE: if there's no map so far we need to create one
if($fs_cache_map === null)
{
//let's re-use the input files
if($update_mode === ConfigUpdateMode::Full || $update_mode === ConfigUpdateMode::RelativeToBundle)
$tmp_files = $input_files;
else
$tmp_files = $this->scanFiles(extension: '.js');
$fs_cache_map = $this->_makeMap($tmp_files);
$this->file_map = $fs_cache_map;
}
$fs_cache_map = $this->_getFileMap($update_mode != ConfigUpdateMode::ChangedOnly ? $input_files : null);
if($update_mode === ConfigUpdateMode::Full || $update_mode === ConfigUpdateMode::RelativeToBundle)
{
list($added_files, $removed_files) = $fs_cache_map->compare($input_files->getAllFiles());
config_log("File map added: ".count($added_files).", removed: ".count($removed_files));
}
return $fs_cache_map;
}
private function _getAffectedFiles(ConfigUpdateMode $update_mode, ?string $result_bundle_file, ConfigCacheFileMap $fs_cache_map, ConfigDirFiles $input_files, array $removed_files) : ConfigDirFiles
private function _getAffectedFiles(ConfigUpdateMode $update_mode, ?string $result_bundle_file, ConfigDirFiles $input_files, array $removed_files) : ConfigDirFiles
{
$fs_cache_map = $this->getFileMap();
$affected_files = null;
if($update_mode === ConfigUpdateMode::Full)
@ -185,7 +182,7 @@ class ConfigManager
if($result_bundle_file === null)
throw new Exception("result_bundle_file argument is required");
$affected_files = $this->newDirFiles();
$affected_files = ConfigDirFiles::makeFor($this);
foreach($input_files->getMap() as $base_dir => $files)
{
@ -217,17 +214,26 @@ class ConfigManager
}
}
}
else
throw new Exception("Unknown update mode: {$update_mode->value}");
else if($update_mode === ConfigUpdateMode::ChangedOnly)
{
$affected_files = ConfigDirFiles::makeFor($this);
foreach($input_files as $file)
{
$affected_files->addFile($file, unique: true);
if(!str_ends_with($file, '.conf.js'))
{
$affected_by_file = $fs_cache_map->getAffectedFiles($file);
foreach($affected_by_file as $dep)
$affected_files->addFile($dep, unique: true);
}
}
}
return $affected_files;
}
function newDirFiles() : ConfigDirFiles
{
return new ConfigDirFiles([], $this->globals->base_dirs);
}
function parseFile(string $file) : ConfigParseResult
{
return config_parse($this->globals->base_dirs, $file);
@ -250,18 +256,17 @@ class ConfigManager
return ConfigCacheFileMap::unserialize(ensure_read($this->_getMapPath()));
}
private function _makeMap(ConfigDirFiles $files) : ConfigCacheFileMap
private static function _makeMap(ConfigDirFiles $files) : ConfigCacheFileMap
{
config_log("Creating file map");
$map = new ConfigCacheFileMap();
$map->update($files->getAllFiles(), []);
$this->_saveMap($map);
return $map;
}
private function _saveMap(ConfigCacheFileMap $map)
private function _saveFileMap()
{
ensure_write($this->_getMapPath(), ConfigCacheFileMap::serialize($map));
ensure_write($this->_getMapPath(), ConfigCacheFileMap::serialize($this->getFileMap()));
}
}

View File

@ -22,6 +22,11 @@ class ConfigDirFiles implements \ArrayAccess, \Countable, \Iterator
$this->base_dirs = $base_dirs;
}
static function makeFor(ConfigManager $mgr) : ConfigDirFiles
{
return new ConfigDirFiles([], $mgr->getGlobals()->base_dirs);
}
function clear()
{
$this->base_dir2files = array();