core/source/helpers/cache.php

371 lines
4.4 KiB
PHP
Raw Normal View History

2025-09-09 12:07:53 +02:00
<?php
namespace davigil\helpers\cache;
/**
*/
interface interface_cache/*<type_value>*/
{
/**
*/
public function has(
string $key
) : bool
;
/**
*/
public function get(
string $key
)/* : type_value*/
;
/**
*/
public function set(
string $key,
/*type_value */$value
) : void
;
}
/**
*/
class class_cache_encoded
implements interface_cache/*<type_value_inner, type_value_outer>*/
{
/**
*/
private interface_cache $core;
/**
*/
private \Closure $encode;
/**
*/
private \Closure $decode;
/**
*/
public function __construct(
interface_cache $core,
\Closure $encode,
\Closure $decode
)
{
$this->core = $core;
$this->encode = $encode;
$this->decode = $decode;
}
/**
* [implementation]
*/
public function has(
string $key
) : bool
{
return $this->core->has($key);
}
/**
* [implementation]
*/
public function get(
string $key
)/* : type_value*/
{
return ($this->decode)($this->core->get($key));
}
/**
* [implementation]
*/
public function set(
string $key,
/*type_value */$value
) : void
{
$this->core->set($key, ($this->encode)($value));
}
}
/**
*/
class class_cache_memory
implements interface_cache/*<any>*/
{
/**
* @property array $data {map<string,any>}
*/
private array $data;
/**
*/
public function __construct(
)
{
$this->data = [];
}
/**
* [implementation]
*/
public function has(
string $key
) : bool
{
return \array_key_exists($key, $this->data);
}
/**
* [implementation]
*/
public function get(
string $key
)/* : any*/
{
if (! \array_key_exists($key, $this->data))
{
throw (new \Exception('missing'));
}
else
{
return $this->data[$key];
}
}
/**
* [implementation]
*/
public function set(
string $key,
/*any */$value
) : void
{
$this->data[$key] = $value;
}
}
/**
*/
class class_cache_file
implements interface_cache/*<string>*/
{
/**
*/
private $directory;
/**
*/
public function __construct(
string $directory
)
{
$this->directory = $directory;
}
public function compose_path(
string $key
) : string
{
return \sprintf(
'%s/%s', $this->directory,
\hash('sha256', $key)
);
}
/**
* [implementation]
*/
public function has(
string $key
) : bool
{
$path = $this->compose_path($key);
return \file_exists($path);
}
/**
* [implementation]
*/
public function get(
string $key
)/* : string*/
{
$path = $this->compose_path($key);
if (! \file_exists($path))
{
throw (new \Exception('missing'));
}
else
{
return \file_get_contents($path);
}
}
/**
* [implementation]
*/
public function set(
string $key,
/*string */$value
) : void
{
$path = $this->compose_path($key);
\file_put_contents($path, $value);
}
}
/**
*/
class class_cache_apcu
implements interface_cache/*<any>*/
{
/**
*/
private string $prefix;
/**
*/
public function __construct(
?array $options = null
)
{
$options = \array_merge(
[
'prefix' => 'davigil_',
],
($options ?? [])
);
$this->prefix = $options['prefix'];
}
/**
*/
private function compose_id(
string $key
) : string
{
return \sprintf('%s%s', $this->prefix, $key);
}
/**
* [implementation]
*/
public function has(
string $key
) : bool
{
$id = $this->compose_id($key);
return \apcu_exists($id);
}
/**
* [implementation]
*/
public function get(
string $key
)/* : any*/
{
$id = $this->compose_id($key);
return \apcu_fetch($id);
}
/**
* [implementation]
*/
public function set(
string $key,
/*any */$value
) : void
{
$id = $this->compose_id($key);
\apcu_store($id, $value);
}
}
/**
*/
function get/*<type_value>*/(
interface_cache $cache/*<type_value>*/,
string $key,
\Closure $retrieve,
?array $options = null
)/* : type_value*/
{
$options = \array_merge(
[
'ttl' => null,
'now' => \time(),
],
($options ?? [])
);
if (! $cache->has($key))
{
$entry = null;
$shall_retrieve = true;
}
else
{
$entry = $cache->get($key);
$shall_retrieve = (($entry['expiry'] !== null) && ($options['now'] >= $entry['expiry']));
}
if ($shall_retrieve)
{
$value = ($retrieve)();
$entry = [
'expiry' => (($options['ttl'] === null) ? null : ($options['now'] + $options['ttl'])),
'value' => $value,
];
$cache->set($key, $entry);
}
else
{
$value = $entry['value'];
}
return $value;
}
?>