Skip to content

Commit

Permalink
Merge pull request #9924 from kkmuffme/compressor-configurable-lz4-de…
Browse files Browse the repository at this point in the history
…flate-off-only

make compressor configurable v2
  • Loading branch information
orklah committed Jun 18, 2023
2 parents e2dde5d + 9d1558b commit 2e8d575
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 15 deletions.
1 change: 1 addition & 0 deletions config.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
<xs:attribute name="name" type="xs:string" />
<xs:attribute name="phpVersion" type="xs:string" />
<xs:attribute name="serializer" type="xs:string" />
<xs:attribute name="compressor" type="xs:string" />

<xs:attribute name="addParamDefaultToDocblockType" type="xs:boolean" default="false" />
<xs:attribute name="allowFileIncludes" type="xs:boolean" default="true" />
Expand Down
8 changes: 8 additions & 0 deletions docs/running_psalm/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,14 @@ Whether or not to allow `require`/`include` calls in your PHP. Defaults to `true
```
Allows you to hard-code a serializer for Psalm to use when caching data. By default, Psalm uses `ext-igbinary` *if* the version is greater than or equal to 2.0.5, otherwise it defaults to PHP's built-in serializer.

#### compressor
```xml
<psalm
compressor="['lz4'|'deflate'|'off']"
>
```
Allows you to hard-code a compressor for Psalm's cache. By default, Psalm uses `ext-zlib` deflate, if it's enabled.

#### threads
```xml
<psalm
Expand Down
15 changes: 11 additions & 4 deletions src/Psalm/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -332,8 +332,8 @@ class Config
/** @var bool */
public $use_igbinary = false;

/** @var bool */
public $use_gzip = true;
/** @var 'lz4'|'deflate'|'off' */
public $compressor = 'off';

/**
* @var bool
Expand Down Expand Up @@ -1196,8 +1196,15 @@ private static function fromXmlAndPaths(
$config->use_igbinary = version_compare($igbinary_version, '2.0.5') >= 0;
}

if ($config->use_gzip) {
$config->use_gzip = function_exists('gzinflate');
if (isset($config_xml['compressor'])) {
$compressor = (string) $config_xml['compressor'];
if ($compressor === 'lz4' && function_exists('lz4_uncompress')) {
$config->compressor = 'lz4';
} elseif ($compressor !== 'off' && function_exists('gzdeflate')) {
$config->compressor = 'deflate';
}
} elseif (function_exists('gzdeflate')) {
$config->compressor = 'deflate';
}

if (!isset($config_xml['findUnusedBaselineEntry'])) {
Expand Down
61 changes: 50 additions & 11 deletions src/Psalm/Internal/Cache.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@

use Psalm\Config;
use Psalm\Internal\Provider\Providers;
use RuntimeException;

use function file_exists;
use function file_put_contents;
use function gzdeflate;
use function gzinflate;
use function igbinary_serialize;
use function igbinary_unserialize;
use function lz4_compress;
use function lz4_uncompress;
use function serialize;
use function unlink;
use function unserialize;
Expand Down Expand Up @@ -42,28 +45,50 @@ public function getItem(string $path)
}

$cache = Providers::safeFileGetContents($path);
if ($this->config->use_gzip) {
if ($cache === '') {
return null;
}

if ($this->config->compressor === 'deflate') {
$inflated = @gzinflate($cache);
if ($inflated !== false) {
$cache = $inflated;
}
} elseif ($this->config->compressor === 'lz4') {
/**
* @psalm-suppress UndefinedFunction
* @var string|false $inflated
*/
$inflated = lz4_uncompress($cache);
} else {
$inflated = $cache;
}

// invalid cache data
if ($inflated === false) {
$this->deleteItem($path);

return null;
}

if ($this->config->use_igbinary) {
/** @var object|false $unserialized */
$unserialized = igbinary_unserialize($cache);
$unserialized = @igbinary_unserialize($inflated);
} else {
/** @var object|false $unserialized */
$unserialized = @unserialize($cache);
$unserialized = @unserialize($inflated);
}

return $unserialized !== false ? $unserialized : null;
if ($unserialized === false) {
$this->deleteItem($path);

return null;
}

return $unserialized;
}

public function deleteItem(string $path): void
{
if (file_exists($path)) {
unlink($path);
@unlink($path);
}
}

Expand All @@ -78,11 +103,25 @@ public function saveItem(string $path, $item): void
$serialized = serialize($item);
}

if ($this->config->use_gzip) {
$serialized = gzdeflate($serialized);
if ($this->config->compressor === 'deflate') {
$compressed = gzdeflate($serialized);
} elseif ($this->config->compressor === 'lz4') {
/**
* @psalm-suppress UndefinedFunction
* @var string|false $compressed
*/
$compressed = lz4_compress($serialized, 4);
} else {
$compressed = $serialized;
}

if ($compressed === false) {
throw new RuntimeException(
'Failed to compress cache data',
);
}

file_put_contents($path, $serialized, LOCK_EX);
file_put_contents($path, $compressed, LOCK_EX);
}

public function getCacheDirectory(): ?string
Expand Down

0 comments on commit 2e8d575

Please sign in to comment.