Improving handling of file map cache

This commit is contained in:
Pavel Shevaev 2025-04-16 19:17:29 +03:00
parent 1b25beb4ed
commit 7b6d342469
3 changed files with 51 additions and 15 deletions

View File

@ -268,19 +268,30 @@ class ConfigCacheFileMap
return array_keys($this->file2deps[$file]); return array_keys($this->file2deps[$file]);
} }
function update(array $files) function differs(array $files) : bool
{
$this_files = array_keys($this->file2deps);
return count($files) !== count($this_files) ||
count(array_intersect($files, $this_files)) != count($this_files);
}
function compare(array $files) : array
{ {
$this_files = array_keys($this->file2deps); $this_files = array_keys($this->file2deps);
$added = array_diff($files, $this_files); $added = array_diff($files, $this_files);
$removed = array_diff($this_files, $files); $removed = array_diff($this_files, $files);
return [$added, $removed];
}
function update(array $added, array $removed)
{
foreach($added as $file) foreach($added as $file)
$this->file2deps[$file] = []; $this->file2deps[$file] = [];
foreach($removed as $file) foreach($removed as $file)
unset($this->file2deps[$file]); unset($this->file2deps[$file]);
return [$added, $removed];
} }
function updateDepsForEntry(ConfigCacheEntry $entry) function updateDepsForEntry(ConfigCacheEntry $entry)

View File

@ -15,7 +15,6 @@ class ConfigGlobals
public ?string $worker_init_fn = null; public ?string $worker_init_fn = null;
public string $base_class = '\ConfBase'; public string $base_class = '\ConfBase';
public string $build_dir; public string $build_dir;
public ?ConfigCacheFileMap $file_map;
function __construct(array $base_dirs, string $build_dir, ?string $worker_init_fn = null) function __construct(array $base_dirs, string $build_dir, ?string $worker_init_fn = null)
{ {
@ -38,9 +37,9 @@ class ConfigGlobals
enum ConfigUpdateMode : int enum ConfigUpdateMode : int
{ {
case ChangedOnly = 1; case Full = 1;
case RelativeToBundle = 2; case RelativeToBundle = 2;
case Full = 3; case ChangedOnly = 3;
} }
class ConfigManager class ConfigManager
@ -49,6 +48,7 @@ class ConfigManager
private int $workers_num; private int $workers_num;
private ConfigCache $cache; private ConfigCache $cache;
private ?ConfigCacheFileMap $file_map;
function __construct(ConfigGlobals $globals, int $workers_num) function __construct(ConfigGlobals $globals, int $workers_num)
{ {
@ -56,6 +56,7 @@ class ConfigManager
$this->workers_num = $workers_num; $this->workers_num = $workers_num;
$this->cache = new ConfigCache($globals); $this->cache = new ConfigCache($globals);
$this->file_map = null;
} }
function getGlobals() : ConfigGlobals function getGlobals() : ConfigGlobals
@ -73,6 +74,18 @@ class ConfigManager
return [$this->globals->base_dirs, ['.js']]; return [$this->globals->base_dirs, ['.js']];
} }
function getFileMap() : ConfigCacheFileMap
{
if($this->file_map === null)
{
$map = $this->_tryLoadMap();
if($map === null)
$map = $this->_makeMap($this->scanFiles(extension: '.js'));
$this->file_map = $map;
}
return $this->file_map;
}
function updateCache( function updateCache(
ConfigUpdateMode $update_mode, ConfigUpdateMode $update_mode,
ConfigDirFiles $input_files = null, ConfigDirFiles $input_files = null,
@ -80,6 +93,8 @@ class ConfigManager
bool $verbose = false bool $verbose = false
) : ConfigCacheUpdateResult ) : ConfigCacheUpdateResult
{ {
config_log("Updating cache, mode {$update_mode->value}...");
if($input_files === null && $update_mode === ConfigUpdateMode::ChangedOnly) if($input_files === null && $update_mode === ConfigUpdateMode::ChangedOnly)
throw new Exception("input_files argument is required for ChangedOnly mode"); throw new Exception("input_files argument is required for ChangedOnly mode");
@ -124,32 +139,33 @@ class ConfigManager
} }
if($affected_files->count() > 0 || $added_files || $removed_files) if($affected_files->count() > 0 || $added_files || $removed_files)
{
$fs_cache_map->update($added_files, $removed_files);
$this->_saveMap($fs_cache_map); $this->_saveMap($fs_cache_map);
}
return $update_result; 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) : ConfigCacheFileMap
{ {
//TODO: do we need to check if cache stale somehow? $fs_cache_map = $this->file_map;
$fs_cache_map = $this->_tryLoadMap();
//NOTE: if there's no map so far we need to create one //NOTE: if there's no map so far we need to create one
if($fs_cache_map === null) if($fs_cache_map === null)
{ {
$fs_cache_map = new ConfigCacheFileMap();
//let's re-use the input files //let's re-use the input files
if($update_mode === ConfigUpdateMode::Full || $update_mode === ConfigUpdateMode::RelativeToBundle) if($update_mode === ConfigUpdateMode::Full || $update_mode === ConfigUpdateMode::RelativeToBundle)
$tmp_files = $input_files; $tmp_files = $input_files;
else else
$tmp_files = $this->scanFiles(extension: '.js'); $tmp_files = $this->scanFiles(extension: '.js');
$fs_cache_map->update($tmp_files->getAllFiles()); $fs_cache_map = $this->_makeMap($tmp_files);
$this->file_map = $fs_cache_map;
} }
if($update_mode === ConfigUpdateMode::Full || $update_mode === ConfigUpdateMode::RelativeToBundle) if($update_mode === ConfigUpdateMode::Full || $update_mode === ConfigUpdateMode::RelativeToBundle)
{ {
list($added_files, $removed_files) = $fs_cache_map->update($input_files->getAllFiles()); list($added_files, $removed_files) = $fs_cache_map->compare($input_files->getAllFiles());
config_log("File map added: ".count($added_files).", removed: ".count($removed_files)); config_log("File map added: ".count($added_files).", removed: ".count($removed_files));
} }
@ -193,7 +209,7 @@ class ConfigManager
{ {
$affected_by_file = $fs_cache_map->getAffectedFiles($file); $affected_by_file = $fs_cache_map->getAffectedFiles($file);
foreach($affected_by_file as $dep) foreach($affected_by_file as $dep)
$affected_files->add(config_map_base_dir($this->globals->base_dirs, $dep), $dep, unique: true); $affected_files->addFile($dep, unique: true);
} }
else else
{ {
@ -234,6 +250,15 @@ class ConfigManager
return ConfigCacheFileMap::unserialize(ensure_read($this->_getMapPath())); return ConfigCacheFileMap::unserialize(ensure_read($this->_getMapPath()));
} }
private 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 _saveMap(ConfigCacheFileMap $map)
{ {
ensure_write($this->_getMapPath(), ConfigCacheFileMap::serialize($map)); ensure_write($this->_getMapPath(), ConfigCacheFileMap::serialize($map));

View File

@ -12,8 +12,8 @@ class ConfigPackParams
public ?int $version = null; public ?int $version = null;
public bool $debug = false; public bool $debug = false;
public const string EXTRA_FMT3_CHUNK_SIZE = "EXTRA_FMT3_CHUNK_SIZE"; public const EXTRA_FMT3_CHUNK_SIZE = "EXTRA_FMT3_CHUNK_SIZE";
public const string EXTRA_FMT3_COMPRESSION_LEVEL = "EXTRA_FMT3_COMPRESSION_LEVEL"; public const EXTRA_FMT3_COMPRESSION_LEVEL = "EXTRA_FMT3_COMPRESSION_LEVEL";
public array $extras = array(); public array $extras = array();
function __construct( function __construct(