Compare commits
7 Commits
Author | SHA1 | Date |
---|---|---|
|
6fe8a0dff5 | |
|
fd49e48a57 | |
|
77a63241ff | |
|
458b72e367 | |
|
a15f4f935e | |
|
07d69c4a02 | |
|
4bd731aa25 |
|
@ -1,3 +1,6 @@
|
||||||
|
## v5.10.0
|
||||||
|
- Added fmt3 bundle format - basically, fmt1 with chunk-based lz4 compression
|
||||||
|
|
||||||
## v4.0.2
|
## v4.0.2
|
||||||
- Improving exception message
|
- Improving exception message
|
||||||
|
|
||||||
|
@ -7,4 +10,4 @@
|
||||||
## v4.0.0
|
## v4.0.0
|
||||||
- Adding initial binary format 2 support: no more lookups by CRC28 strids
|
- Adding initial binary format 2 support: no more lookups by CRC28 strids
|
||||||
- Removed misc obsolete stuff
|
- Removed misc obsolete stuff
|
||||||
- Adding PHP type hints
|
- Adding PHP type hints
|
||||||
|
|
|
@ -154,7 +154,7 @@ class ConfigFetchParams
|
||||||
public bool $verbose = false;
|
public bool $verbose = false;
|
||||||
public ?int $max_workers = null;
|
public ?int $max_workers = null;
|
||||||
public bool $touch_files_with_includes = true;
|
public bool $touch_files_with_includes = true;
|
||||||
public bool $check_junk = false;
|
public bool $check_junk = true;
|
||||||
|
|
||||||
function __construct(ConfigGlobals $globals, ConfigScanResult $scanned,
|
function __construct(ConfigGlobals $globals, ConfigScanResult $scanned,
|
||||||
bool $force_stale = false, bool $verbose = false, ?int $max_workers = null)
|
bool $force_stale = false, bool $verbose = false, ?int $max_workers = null)
|
||||||
|
@ -272,11 +272,11 @@ function _config_cache_fetch(ConfigFetchParams $params) : ConfigFetchResult
|
||||||
|
|
||||||
if(!$serial)
|
if(!$serial)
|
||||||
{
|
{
|
||||||
//NOTE: in case of any result error try serial processing
|
//NOTE: in case result unserialize error try serial processing
|
||||||
if(array_search(false, $results_by_job, true/*strict*/) !== false)
|
if(array_search(false, $results_by_job, true/*strict*/) !== false)
|
||||||
{
|
{
|
||||||
if($params->verbose)
|
if($params->verbose)
|
||||||
config_log("Result error detected, trying serial processing...");
|
config_log("Corrupted result, trying serial processing...");
|
||||||
$results_by_job = _config_worker_run_procs($params, $jobs, true);
|
$results_by_job = _config_worker_run_procs($params, $jobs, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
345
pack.inc.php
345
pack.inc.php
|
@ -12,8 +12,19 @@ class ConfigPackParams
|
||||||
public ?int $version = null;
|
public ?int $version = null;
|
||||||
public bool $debug = false;
|
public bool $debug = false;
|
||||||
|
|
||||||
function __construct(array $cache_entries, int $version, bool $use_lz4 = false,
|
public const string EXTRA_FMT3_CHUNK_SIZE = "EXTRA_FMT3_CHUNK_SIZE";
|
||||||
bool $use_config_refs = false, int $binary_format = 1, bool $debug = false)
|
public const string EXTRA_FMT3_COMPRESSION_LEVEL = "EXTRA_FMT3_COMPRESSION_LEVEL";
|
||||||
|
public array $extras = array();
|
||||||
|
|
||||||
|
function __construct(
|
||||||
|
array $cache_entries,
|
||||||
|
int $version,
|
||||||
|
bool $use_lz4 = false,
|
||||||
|
bool $use_config_refs = false,
|
||||||
|
int $binary_format = 1,
|
||||||
|
bool $debug = false,
|
||||||
|
array $extras = array()
|
||||||
|
)
|
||||||
{
|
{
|
||||||
$this->cache_entries = $cache_entries;
|
$this->cache_entries = $cache_entries;
|
||||||
$this->use_lz4 = $use_lz4;
|
$this->use_lz4 = $use_lz4;
|
||||||
|
@ -21,6 +32,7 @@ class ConfigPackParams
|
||||||
$this->binary_format = $binary_format;
|
$this->binary_format = $binary_format;
|
||||||
$this->version = $version;
|
$this->version = $version;
|
||||||
$this->debug = $debug;
|
$this->debug = $debug;
|
||||||
|
$this->extras = $extras;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +57,18 @@ function config_pack_bundle(ConfigPackParams $params) : string
|
||||||
$params->cache_entries,
|
$params->cache_entries,
|
||||||
$params->use_lz4,
|
$params->use_lz4,
|
||||||
$params->use_config_refs,
|
$params->use_config_refs,
|
||||||
$params->version
|
$params->version,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if($params->binary_format == 3)
|
||||||
|
{
|
||||||
|
$packed_data = _config_pack_bundle_fmt3(
|
||||||
|
$params->cache_entries,
|
||||||
|
$params->use_lz4,
|
||||||
|
$params->use_config_refs,
|
||||||
|
$params->version,
|
||||||
|
$params->extras[ConfigPackParams::EXTRA_FMT3_CHUNK_SIZE],
|
||||||
|
$params->extras[ConfigPackParams::EXTRA_FMT3_COMPRESSION_LEVEL],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -61,6 +84,35 @@ function config_pack_bundle(ConfigPackParams $params) : string
|
||||||
return $packed_data;
|
return $packed_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function config_patch_bundle(ConfigPackParams $params, string $packed_data) : string
|
||||||
|
{
|
||||||
|
$t = microtime(true);
|
||||||
|
|
||||||
|
$patched_data = null;
|
||||||
|
|
||||||
|
if($params->binary_format == 2)
|
||||||
|
{
|
||||||
|
$patched_data = _config_patch_bundle_fmt2(
|
||||||
|
$packed_data,
|
||||||
|
$params->cache_entries,
|
||||||
|
$params->use_lz4,
|
||||||
|
$params->use_config_refs,
|
||||||
|
$params->version,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new Exception("Unknown binary format: {$params->binary_format}");
|
||||||
|
|
||||||
|
if($params->debug)
|
||||||
|
config_log("Patched entries: " . sizeof($params->cache_entries) . ", total: " .
|
||||||
|
kb($patched_data) . ", format: {$params->binary_format}, lz4: " .
|
||||||
|
var_export($params->use_lz4, true) . ", refs: " . var_export($params->use_config_refs, true) .
|
||||||
|
", CRC: " . crc32($patched_data) .
|
||||||
|
", " . round(microtime(true) - $t,2) . " sec.");
|
||||||
|
|
||||||
|
return $patched_data;
|
||||||
|
}
|
||||||
|
|
||||||
//NOTE: strids are stored as CRCs, potential collision may happen (error will be raised during build)
|
//NOTE: strids are stored as CRCs, potential collision may happen (error will be raised during build)
|
||||||
function _config_pack_bundle_fmt1(
|
function _config_pack_bundle_fmt1(
|
||||||
array $cache_entries,
|
array $cache_entries,
|
||||||
|
@ -118,12 +170,14 @@ function _config_pack_bundle_fmt1(
|
||||||
return $packed_data;
|
return $packed_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
//NOTE: strids are stored as lookup strings
|
//NOTE: strids are stored as lookup strings, and actually an array of lookup string indices
|
||||||
|
// (each path item separated by '/' is stored as an array item)
|
||||||
function _config_pack_bundle_fmt2(
|
function _config_pack_bundle_fmt2(
|
||||||
array $cache_entries,
|
array $cache_entries,
|
||||||
bool $use_lz4,
|
bool $use_lz4,
|
||||||
bool $use_config_refs,
|
bool $use_config_refs,
|
||||||
int $version) : string
|
int $version,
|
||||||
|
) : string
|
||||||
{
|
{
|
||||||
$MAP = array();
|
$MAP = array();
|
||||||
$STRIDMAP = array();
|
$STRIDMAP = array();
|
||||||
|
@ -139,20 +193,8 @@ function _config_pack_bundle_fmt2(
|
||||||
$payloads[] = array($payloads_offset, $payload, $format, $payload_size);
|
$payloads[] = array($payloads_offset, $payload, $format, $payload_size);
|
||||||
$payloads_offset += $payload_size;
|
$payloads_offset += $payload_size;
|
||||||
|
|
||||||
$strids_indices = array();
|
$strids_indices = _config_encode_strid_as_indices($entry->strid, $STRIDMAP, $STRIDLIST);
|
||||||
$strid_parts = explode('/', ltrim($entry->strid, '@'));
|
|
||||||
foreach($strid_parts as $strid_part)
|
|
||||||
{
|
|
||||||
if(!isset($STRIDMAP[$strid_part]))
|
|
||||||
{
|
|
||||||
$strid_index = count($STRIDLIST);
|
|
||||||
$STRIDLIST[] = $strid_part;
|
|
||||||
$STRIDMAP[$strid_part] = $strid_index;
|
|
||||||
$strids_indices[] = $strid_index;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
$strids_indices[] = $STRIDMAP[$strid_part];
|
|
||||||
}
|
|
||||||
$strids[] = $strids_indices;
|
$strids[] = $strids_indices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,6 +234,184 @@ function _config_pack_bundle_fmt2(
|
||||||
return $packed_data;
|
return $packed_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//NOTE: Much like fmt1, but configs entries are grouped into sizeable chuncks, with each chunk lz4-compressed.
|
||||||
|
// This reduces overall bundle size when there are many small configs entries.
|
||||||
|
function _config_pack_bundle_fmt3(
|
||||||
|
array $cache_entries,
|
||||||
|
bool $use_lz4,
|
||||||
|
bool $use_config_refs,
|
||||||
|
int $version,
|
||||||
|
int $chunk_size,
|
||||||
|
int $compression_level) : string
|
||||||
|
{
|
||||||
|
if(!$use_lz4)
|
||||||
|
throw new Exception("Config bundle FMT3 is only available with LZ4 enabled");
|
||||||
|
|
||||||
|
if($compression_level < 0 || $compression_level > 12)
|
||||||
|
throw new Exception("LZ4 compression level must be in range [0, 12]");
|
||||||
|
|
||||||
|
$MAP = array();
|
||||||
|
$STRIDMAP = array();
|
||||||
|
|
||||||
|
$header = array();
|
||||||
|
$payloads_offset = 0;
|
||||||
|
$max_chunk_size = 0;
|
||||||
|
$chunk_offset = 0;
|
||||||
|
$payloads_bundle = '';
|
||||||
|
$payloads_buffer = '';
|
||||||
|
$count_entries = count($cache_entries);
|
||||||
|
foreach($cache_entries as $idx => $entry)
|
||||||
|
{
|
||||||
|
list($format, $payload) = _config_get_payload($entry, $use_lz4, $use_config_refs);
|
||||||
|
$payload_size = strlen($payload);
|
||||||
|
$payloads_buffer .= $payload;
|
||||||
|
|
||||||
|
if(isset($MAP[$entry->id]))
|
||||||
|
throw new Exception("Duplicating config id for '{$entry->strid}' conflicts with '{$MAP[$entry->id]}'");
|
||||||
|
$MAP[$entry->id] = $entry->strid;
|
||||||
|
|
||||||
|
$strid_crc = crc32($entry->strid);
|
||||||
|
if(isset($STRIDMAP[$strid_crc]))
|
||||||
|
throw new Exception("Duplicating config str id crc for '{$entry->strid}' conflicts with '{$STRIDMAP[$strid_crc]}'");
|
||||||
|
$STRIDMAP[$strid_crc] = $entry->strid;
|
||||||
|
|
||||||
|
$header[] = array(
|
||||||
|
$format,
|
||||||
|
$entry->id,
|
||||||
|
crc32($entry->strid),
|
||||||
|
$entry->class_id,
|
||||||
|
$chunk_offset,
|
||||||
|
$payloads_offset,
|
||||||
|
$payload_size
|
||||||
|
);
|
||||||
|
|
||||||
|
$payloads_offset += $payload_size;
|
||||||
|
|
||||||
|
if($payloads_offset >= $chunk_size || $idx == ($count_entries - 1))
|
||||||
|
{
|
||||||
|
if($payloads_offset > $max_chunk_size)
|
||||||
|
$max_chunk_size = $payloads_offset;
|
||||||
|
$payloads_offset = 0;
|
||||||
|
$lz4_data = lz4_compress($payloads_buffer, $compression_level);
|
||||||
|
$payloads_bundle .= pack("V", strlen($lz4_data));
|
||||||
|
$payloads_bundle .= $lz4_data;
|
||||||
|
$chunk_offset = strlen($payloads_bundle);
|
||||||
|
$payloads_buffer = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$header_msgpack = config_msgpack_pack($header);
|
||||||
|
|
||||||
|
$packed_data =
|
||||||
|
pack("C", 3) .
|
||||||
|
pack("V", $version) .
|
||||||
|
pack("V", strlen($header_msgpack)) .
|
||||||
|
pack("V", $max_chunk_size) .
|
||||||
|
$header_msgpack .
|
||||||
|
$payloads_bundle;
|
||||||
|
|
||||||
|
return $packed_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _config_encode_strid_as_indices(string $strid, array &$STRIDMAP, array &$STRIDLIST) : array
|
||||||
|
{
|
||||||
|
$strids_indices = array();
|
||||||
|
$strid_parts = explode('/', ltrim($strid, '@'));
|
||||||
|
foreach($strid_parts as $strid_part)
|
||||||
|
{
|
||||||
|
if(!isset($STRIDMAP[$strid_part]))
|
||||||
|
{
|
||||||
|
$strid_index = count($STRIDLIST);
|
||||||
|
$STRIDLIST[] = $strid_part;
|
||||||
|
$STRIDMAP[$strid_part] = $strid_index;
|
||||||
|
$strids_indices[] = $strid_index;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
$strids_indices[] = $STRIDMAP[$strid_part];
|
||||||
|
}
|
||||||
|
return $strids_indices;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _config_patch_bundle_fmt2(
|
||||||
|
string $packed_data,
|
||||||
|
array $patch_entries,
|
||||||
|
bool $use_lz4,
|
||||||
|
bool $use_config_refs,
|
||||||
|
int $version,
|
||||||
|
) : string
|
||||||
|
{
|
||||||
|
list($strids, $header, $_, $payloads_bundle) =
|
||||||
|
_config_unpack_bundle_fmt2(packed_data: $packed_data, unpack_entries: false);
|
||||||
|
|
||||||
|
$stridmap = array_flip($strids);
|
||||||
|
|
||||||
|
foreach($patch_entries as $idx => $patch_entry)
|
||||||
|
{
|
||||||
|
list($patch_format, $patch_payload) = _config_get_payload($patch_entry, $use_lz4, $use_config_refs);
|
||||||
|
|
||||||
|
$header_found = array_filter($header, fn($item) => $item[1] == $patch_entry->id);
|
||||||
|
|
||||||
|
if($header_found)
|
||||||
|
{
|
||||||
|
$header_idx = key($header_found);
|
||||||
|
$header_entry = current($header_found);
|
||||||
|
|
||||||
|
$current_offset = $header_entry[4];
|
||||||
|
$current_size = $header_entry[5];
|
||||||
|
if($current_size >= strlen($patch_payload))
|
||||||
|
{
|
||||||
|
//let's do the inline patching
|
||||||
|
$payloads_bundle = substr_replace($payloads_bundle, $patch_payload, $current_offset, strlen($patch_payload));
|
||||||
|
|
||||||
|
$header_entry[0] = $patch_format;
|
||||||
|
$header_entry[5] = strlen($patch_payload);
|
||||||
|
$header[$header_idx] = $header_entry;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//let's add it to the end
|
||||||
|
$header_entry[0] = $patch_format;
|
||||||
|
$header_entry[4] = strlen($payloads_bundle);
|
||||||
|
$header_entry[5] = strlen($patch_payload);
|
||||||
|
$header[$header_idx] = $header_entry;
|
||||||
|
|
||||||
|
$payloads_bundle .= $patch_payload;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//let's add new entry it to the end
|
||||||
|
$strid_indices = _config_encode_strid_as_indices($patch_entry->strid, $stridmap, $strids);
|
||||||
|
|
||||||
|
$header_entry = array(
|
||||||
|
$patch_format,
|
||||||
|
$patch_entry->id,
|
||||||
|
$strid_indices,
|
||||||
|
$patch_entry->class_id,
|
||||||
|
strlen($payloads_bundle),
|
||||||
|
strlen($patch_payload),
|
||||||
|
);
|
||||||
|
|
||||||
|
$header[] = $header_entry;
|
||||||
|
$payloads_bundle .= $patch_payload;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$strids_msgpack = config_msgpack_pack($strids);
|
||||||
|
$header_msgpack = config_msgpack_pack($header);
|
||||||
|
|
||||||
|
$patched_data =
|
||||||
|
pack("C", 2) .
|
||||||
|
pack("V", $version) .
|
||||||
|
pack("V", strlen($strids_msgpack)) .
|
||||||
|
pack("V", strlen($header_msgpack)) .
|
||||||
|
$strids_msgpack .
|
||||||
|
$header_msgpack .
|
||||||
|
$payloads_bundle;
|
||||||
|
|
||||||
|
return $patched_data;
|
||||||
|
}
|
||||||
|
|
||||||
//format: [[class_id, [data]], ...[class_id, [data]]]
|
//format: [[class_id, [data]], ...[class_id, [data]]]
|
||||||
function config_unpack_bundle(string $packed_data) : array
|
function config_unpack_bundle(string $packed_data) : array
|
||||||
{
|
{
|
||||||
|
@ -204,7 +424,12 @@ function config_unpack_bundle(string $packed_data) : array
|
||||||
}
|
}
|
||||||
else if($info['format'] === 2)
|
else if($info['format'] === 2)
|
||||||
{
|
{
|
||||||
return _config_unpack_bundle_fmt2($packed_data);
|
list($_, $_, $entries) = _config_unpack_bundle_fmt2($packed_data);
|
||||||
|
return $entries;
|
||||||
|
}
|
||||||
|
else if($info['format'] === 3)
|
||||||
|
{
|
||||||
|
return _config_unpack_bundle_fmt3($packed_data);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw new Exception("Unknown format: {$info['format']}");
|
throw new Exception("Unknown format: {$info['format']}");
|
||||||
|
@ -237,7 +462,7 @@ function _config_unpack_bundle_fmt1(string $packed_data) : array
|
||||||
return $entries;
|
return $entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _config_unpack_bundle_fmt2(string $packed_data) : array
|
function _config_unpack_bundle_fmt2(string $packed_data, bool $unpack_entries = true) : array
|
||||||
{
|
{
|
||||||
$packed_info = substr($packed_data, 0, 1+4+4+4);
|
$packed_info = substr($packed_data, 0, 1+4+4+4);
|
||||||
|
|
||||||
|
@ -255,16 +480,80 @@ function _config_unpack_bundle_fmt2(string $packed_data) : array
|
||||||
$payloads_bundle = substr($packed_data, 1+4+4+4+$info['strids_len']+$info['header_len']);
|
$payloads_bundle = substr($packed_data, 1+4+4+4+$info['strids_len']+$info['header_len']);
|
||||||
|
|
||||||
$entries = array();
|
$entries = array();
|
||||||
foreach($header as $item)
|
|
||||||
|
if($unpack_entries)
|
||||||
{
|
{
|
||||||
list($format, $id, $strid_crc, $class_id, $offset, $size) = $item;
|
foreach($header as $item)
|
||||||
|
{
|
||||||
|
list($format, $id, $strid_crc, $class_id, $offset, $size) = $item;
|
||||||
|
|
||||||
$payload = substr($payloads_bundle, $offset, $size);
|
$payload = substr($payloads_bundle, $offset, $size);
|
||||||
|
|
||||||
$entries[$id] = array($class_id, _config_unpack_payload($format, $payload));
|
$entries[$id] = array($class_id, _config_unpack_payload($format, $payload));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $entries;
|
return array($strids, $header, $entries, $unpack_entries ? null : $payloads_bundle);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _config_unpack_bundle_fmt3(string $packed_data): array
|
||||||
|
{
|
||||||
|
if(ord($packed_data[0]) !== 3)
|
||||||
|
{
|
||||||
|
throw new Exception("Invalid config bundle format");
|
||||||
|
}
|
||||||
|
|
||||||
|
$offset = 1;
|
||||||
|
$version = unpack("V", substr($packed_data, $offset, 4))[1];
|
||||||
|
$offset += 4;
|
||||||
|
$header_len = unpack("V", substr($packed_data, $offset, 4))[1];
|
||||||
|
$offset += 4;
|
||||||
|
$max_chunk_size = unpack("V", substr($packed_data, $offset, 4))[1];
|
||||||
|
$offset += 4;
|
||||||
|
|
||||||
|
$header_msgpack = substr($packed_data, $offset, $header_len);
|
||||||
|
$offset += $header_len;
|
||||||
|
|
||||||
|
$header = config_msgpack_unpack($header_msgpack);
|
||||||
|
|
||||||
|
$cache_entries = [];
|
||||||
|
$chunk_offset = 0;
|
||||||
|
$chunk_buffer = '';
|
||||||
|
$chunk_id = -1;
|
||||||
|
|
||||||
|
foreach ($header as $entry_data)
|
||||||
|
{
|
||||||
|
list($format, $id, $strid_crc, $class_id, $entry_chunk_offset, $payload_offset_within_chunk, $payload_size) = $entry_data;
|
||||||
|
|
||||||
|
if($entry_chunk_offset !== $chunk_id)
|
||||||
|
{
|
||||||
|
if($chunk_offset !== -1)
|
||||||
|
{
|
||||||
|
$lz4_chunk_size = unpack("V", substr($packed_data, $offset, 4))[1];
|
||||||
|
$offset+=4;
|
||||||
|
$lz4_chunk_data = substr($packed_data, $offset, $lz4_chunk_size);
|
||||||
|
$chunk_buffer = lz4_uncompress($lz4_chunk_data);
|
||||||
|
$offset += $lz4_chunk_size;
|
||||||
|
$chunk_offset = $offset;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$lz4_chunk_size = unpack("V", substr($packed_data, $chunk_offset, 4))[1];
|
||||||
|
$chunk_offset += 4;
|
||||||
|
$lz4_chunk_data = substr($packed_data, $chunk_offset, $lz4_chunk_size);
|
||||||
|
$chunk_buffer = lz4_uncompress($lz4_chunk_data);
|
||||||
|
$chunk_offset += $lz4_chunk_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
$chunk_id = $entry_chunk_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
$payload = substr($chunk_buffer, $payload_offset_within_chunk, $payload_size);
|
||||||
|
|
||||||
|
$cache_entries[$id] = array($class_id, _config_unpack_payload($format, $payload));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $cache_entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
//format: [format_id, payload_data]
|
//format: [format_id, payload_data]
|
||||||
|
@ -312,6 +601,7 @@ function config_pack_and_write_bundle(
|
||||||
int $version,
|
int $version,
|
||||||
bool $use_lz4 = true,
|
bool $use_lz4 = true,
|
||||||
int $binary_format = 1,
|
int $binary_format = 1,
|
||||||
|
bool $debug = false
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
$cache_entries = array();
|
$cache_entries = array();
|
||||||
|
@ -336,7 +626,8 @@ function config_pack_and_write_bundle(
|
||||||
cache_entries: $cache_entries,
|
cache_entries: $cache_entries,
|
||||||
use_lz4: $use_lz4,
|
use_lz4: $use_lz4,
|
||||||
binary_format: $binary_format,
|
binary_format: $binary_format,
|
||||||
version: $version
|
version: $version,
|
||||||
|
debug: $debug
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
108
scan.inc.php
108
scan.inc.php
|
@ -2,11 +2,24 @@
|
||||||
namespace taskman;
|
namespace taskman;
|
||||||
use Exception;
|
use Exception;
|
||||||
|
|
||||||
class ConfigScanResult
|
class ConfigScanResult implements \ArrayAccess, \Countable, \Iterator
|
||||||
{
|
{
|
||||||
/*var array<string, string[]>*/
|
/*var array<string, string[]>*/
|
||||||
public array $base_dir2files = array();
|
public array $base_dir2files = array();
|
||||||
|
|
||||||
|
private $iter_pos = 0;
|
||||||
|
|
||||||
|
function __construct(array $base_dir2files = array())
|
||||||
|
{
|
||||||
|
foreach($base_dir2files as $dir => $files)
|
||||||
|
$this->base_dir2files[$dir] = $files;
|
||||||
|
}
|
||||||
|
|
||||||
|
function clear()
|
||||||
|
{
|
||||||
|
$this->base_dir2files = array();
|
||||||
|
}
|
||||||
|
|
||||||
function isEmpty() : bool
|
function isEmpty() : bool
|
||||||
{
|
{
|
||||||
return empty($this->base_dir2files);
|
return empty($this->base_dir2files);
|
||||||
|
@ -69,10 +82,94 @@ class ConfigScanResult
|
||||||
|
|
||||||
return $all_files;
|
return $all_files;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//ArrayAccess interface
|
||||||
|
function offsetExists(mixed $offset) : bool
|
||||||
|
{
|
||||||
|
if(!is_int($offset))
|
||||||
|
throw new Exception("Invalid offset");
|
||||||
|
|
||||||
|
return $this->count() > $offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
function offsetGet(mixed $offset) : mixed
|
||||||
|
{
|
||||||
|
if(!is_int($offset))
|
||||||
|
throw new Exception("Invalid offset");
|
||||||
|
|
||||||
|
foreach($this->base_dir2files as $base_dir => $files)
|
||||||
|
{
|
||||||
|
$n = count($files);
|
||||||
|
if($offset - $n < 0)
|
||||||
|
return $files[$offset];
|
||||||
|
$offset -= $n;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function offsetSet(mixed $offset, mixed $value) : void
|
||||||
|
{
|
||||||
|
if(!is_int($offset))
|
||||||
|
throw new Exception("Invalid offset");
|
||||||
|
|
||||||
|
foreach($this->base_dir2files as $base_dir => &$files)
|
||||||
|
{
|
||||||
|
$n = count($files);
|
||||||
|
if($offset - $n < 0)
|
||||||
|
{
|
||||||
|
$files[$offset] = $value;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$offset -= $n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function offsetUnset(mixed $offset) : void
|
||||||
|
{
|
||||||
|
if(!is_int($offset))
|
||||||
|
throw new Exception("Invalid offset");
|
||||||
|
|
||||||
|
foreach($this->base_dir2files as $base_dir => $files)
|
||||||
|
{
|
||||||
|
$n = count($files);
|
||||||
|
if($offset - $n < 0)
|
||||||
|
{
|
||||||
|
unset($files[$offset]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$offset -= $n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Iterator interface
|
||||||
|
function rewind() : void
|
||||||
|
{
|
||||||
|
$this->iter_pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function current() : mixed
|
||||||
|
{
|
||||||
|
return $this->offsetGet($this->iter_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
function key() : mixed
|
||||||
|
{
|
||||||
|
return $this->iter_pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
function next() : void
|
||||||
|
{
|
||||||
|
++$this->iter_pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
function valid() : bool
|
||||||
|
{
|
||||||
|
return $this->offsetExists($this->iter_pos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function config_scan_files(
|
function config_scan_files(
|
||||||
array $base_dirs,
|
iterable $base_dirs,
|
||||||
string $ext_filter = '.conf.js',
|
string $ext_filter = '.conf.js',
|
||||||
bool $verbose = false
|
bool $verbose = false
|
||||||
) : ConfigScanResult
|
) : ConfigScanResult
|
||||||
|
@ -92,3 +189,10 @@ function config_scan_files(
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function config_hash_changed(ConfigGlobals $globals, iterable $all_files)
|
||||||
|
{
|
||||||
|
$all_crc_file = $globals->build_dir . "/configs.crc";
|
||||||
|
return names_hash_changed($all_crc_file, $all_files);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
11
task.inc.php
11
task.inc.php
|
@ -38,11 +38,14 @@ function _config_worker_run_procs(ConfigFetchParams $params, array $jobs, bool $
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$worker_args = array();
|
//initializing worker for master process anyway
|
||||||
foreach($jobs as $idx => $job)
|
$params->globals->initWorker(true);
|
||||||
$worker_args[] = array($params, $job);
|
|
||||||
|
|
||||||
return run_background_gamectl_workers('config_worker', $worker_args);
|
$workers_args = array();
|
||||||
|
foreach($jobs as $job)
|
||||||
|
$workers_args[] = array($params, $job);
|
||||||
|
|
||||||
|
return run_background_gamectl_workers('config_worker', $workers_args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
22
util.inc.php
22
util.inc.php
|
@ -122,15 +122,13 @@ function config_includes_map_find_text_origin(array $map, string $file, string $
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO:
|
function config2json(object $conf, int $json_flags = 0) : string
|
||||||
//function conf2json(object $conf, int $json_flags = 0) : string
|
{
|
||||||
//{
|
$arr = $conf->export(true);
|
||||||
// $arr = $conf->export(true);
|
$arr['class'] = get_class($conf);
|
||||||
// $arr['class'] = get_class($conf);
|
unset($arr['id']); // @phpstan-ignore-line
|
||||||
// unset($arr['id']);
|
unset($arr['strid']); // @phpstan-ignore-line
|
||||||
// unset($arr['strid']);
|
$json = json_encode($arr, $json_flags);
|
||||||
// $json = json_encode($arr, $json_flags);
|
$json = str_replace(array('\\\\', '\\n', '\/'), array('\\', "\n", '/'), $json);
|
||||||
// $json = str_replace(array('\\\\', '\\n', '\/'), array('\\', "\n", '/'), $json);
|
return $json;
|
||||||
// return $json;
|
}
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue