Skip to content

Commit

Permalink
misc: use xxh128 hash algorithm for cache keys
Browse files Browse the repository at this point in the history
This algorithm is way faster than the originally used `sha1`.

This commit also moves the hash logic into one place, saving even more
processing time. 

Reference: https://php.watch/versions/8.1/xxHash

Co-authored-by: Romain Canon <[email protected]>
  • Loading branch information
TimWolla and romm authored Sep 18, 2024
1 parent 8742b27 commit 546c458
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 27 deletions.
49 changes: 28 additions & 21 deletions src/Cache/KeySanitizerCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@

namespace CuyZ\Valinor\Cache;

use Closure;
use CuyZ\Valinor\Utility\Package;
use Psr\SimpleCache\CacheInterface;
use Traversable;

use function sha1;
use function hash;
use function strstr;

/**
* @internal
Expand All @@ -21,21 +21,28 @@ final class KeySanitizerCache implements WarmupCache
{
private static string $version;

/** @var Closure(string): string */
private Closure $sanitize;

public function __construct(
/** @var CacheInterface<EntryType> */
private CacheInterface $delegate
) {
// Two things:
// 1. We append the current version of the package to the cache key in
// order to avoid collisions between entries from different versions
// of the library.
// 2. The key is sha1'd so that it does not contain illegal characters.
// @see https://www.php-fig.org/psr/psr-16/#12-definitions
// @infection-ignore-all
$this->sanitize = static fn (string $key) => $key . sha1(self::$version ??= PHP_VERSION . '/' . Package::version());
) {}

/**
* Two things:
* 1. We append the current version of the package to the cache key in order
* to avoid collisions between entries from different versions of the
* library.
* 2. The key is hashed so that it does not contain illegal characters.
* @see https://www.php-fig.org/psr/psr-16/#12-definitions
*
* @infection-ignore-all
*/
private function sanitize(string $key): string
{
self::$version ??= PHP_VERSION . '/' . Package::version();

$firstPart = strstr($key, "\0", before_needle: true);

return $firstPart . hash('xxh128', $key . self::$version);
}

public function warmup(): void
Expand All @@ -47,17 +54,17 @@ public function warmup(): void

public function get($key, $default = null): mixed
{
return $this->delegate->get(($this->sanitize)($key), $default);
return $this->delegate->get($this->sanitize($key), $default);
}

public function set($key, $value, $ttl = null): bool
{
return $this->delegate->set(($this->sanitize)($key), $value, $ttl);
return $this->delegate->set($this->sanitize($key), $value, $ttl);
}

public function delete($key): bool
{
return $this->delegate->delete(($this->sanitize)($key));
return $this->delegate->delete($this->sanitize($key));
}

public function clear(): bool
Expand All @@ -67,7 +74,7 @@ public function clear(): bool

public function has($key): bool
{
return $this->delegate->has(($this->sanitize)($key));
return $this->delegate->has($this->sanitize($key));
}

/**
Expand All @@ -76,7 +83,7 @@ public function has($key): bool
public function getMultiple($keys, $default = null): Traversable
{
foreach ($keys as $key) {
yield $key => $this->delegate->get(($this->sanitize)($key), $default);
yield $key => $this->delegate->get($this->sanitize($key), $default);
}
}

Expand All @@ -85,7 +92,7 @@ public function setMultiple($values, $ttl = null): bool
$versionedValues = [];

foreach ($values as $key => $value) {
$versionedValues[($this->sanitize)($key)] = $value;
$versionedValues[$this->sanitize($key)] = $value;
}

return $this->delegate->setMultiple($versionedValues, $ttl);
Expand All @@ -96,7 +103,7 @@ public function deleteMultiple($keys): bool
$transformedKeys = [];

foreach ($keys as $key) {
$transformedKeys[] = ($this->sanitize)($key);
$transformedKeys[] = $this->sanitize($key);
}

return $this->delegate->deleteMultiple($transformedKeys);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
use CuyZ\Valinor\Type\ObjectType;
use Psr\SimpleCache\CacheInterface;

use function sha1;

/** @internal */
final class CacheClassDefinitionRepository implements ClassDefinitionRepository
{
Expand All @@ -23,7 +21,7 @@ public function __construct(
public function for(ObjectType $type): ClassDefinition
{
// @infection-ignore-all
$key = 'class-definition' . sha1($type->toString());
$key = "class-definition-\0" . $type->toString();

$entry = $this->cache->get($key);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
use CuyZ\Valinor\Utility\Reflection\Reflection;
use Psr\SimpleCache\CacheInterface;

use function sha1;

/** @internal */
final class CacheFunctionDefinitionRepository implements FunctionDefinitionRepository
{
Expand All @@ -25,7 +23,7 @@ public function for(callable $function): FunctionDefinition
$reflection = Reflection::function($function);

// @infection-ignore-all
$key = 'function-definition-' . sha1($reflection->getFileName() . $reflection->getStartLine() . $reflection->getEndLine());
$key = "function-definition-\0" . $reflection->getFileName() . ':' . $reflection->getStartLine() . '-' . $reflection->getEndLine();

$entry = $this->cache->get($key);

Expand Down

0 comments on commit 546c458

Please sign in to comment.