1
0
mirror of https://github.com/danog/dns.git synced 2024-12-02 17:38:05 +01:00
dns/lib/Addr/Cache/MemoryCache.php
Chris Wright 585b5578e3 Cache refactoring
- pull $type back down into interface
 - remove delete() from interface
 - make get() async-capable
2014-07-22 02:54:23 +01:00

101 lines
2.4 KiB
PHP

<?php
namespace Addr\Cache;
use Addr\Cache;
class MemoryCache implements Cache
{
/**
* Default time-to-live - 1 day
*/
const DEFAULT_TTL = 86400;
/**
* Internal data store for cache values
*
* @var array
*/
private $recordsByTypeAndName = [];
/**
* Attempt to retrieve a value from the cache
*
* @param string $name
* @param int $type
* @param callable $callback
*/
public function get($name, $type, callable $callback)
{
if (isset($this->recordsByTypeAndName[$type][$name])) {
list($value, $expireTime) = $this->recordsByTypeAndName[$type][$name];
if ($expireTime > time()) {
$callback(true, $value);
return;
}
}
$callback(false, null);
}
/**
* Stores a value in the cache. Overwrites the previous value if there was one.
*
* @param string $name
* @param int $type
* @param string $addr
* @param int $ttl
*/
public function store($name, $type, $addr, $ttl = null)
{
if ($ttl === null) {
$ttl = self::DEFAULT_TTL;
}
$this->recordsByTypeAndName[$type][$name] = [$addr, time() + $ttl];
}
/**
* Deletes an entry from the cache.
*
* @param string $name
* @param int $type
*/
public function delete($name, $type = null)
{
if ($type !== null) {
unset($this->recordsByTypeAndName[$type][$name]);
} else {
/* this approach is to avoid COW of the whole record store
do not "optimise" it! */
foreach (array_keys($this->recordsByTypeAndName) as $type) {
unset($this->recordsByTypeAndName[$type][$name]);
}
}
}
/**
* Delete all expired records from the cache
*/
public function collectGarbage()
{
/* this approach is to avoid COW of the whole record store
do not "optimise" it! */
$now = time();
$toDelete = [];
foreach ($this->recordsByTypeAndName as $type => $records) {
foreach ($records as $name => $record) {
if ($record[1] <= $now) {
$toDelete[] = [$type, $name];
}
}
}
foreach ($toDelete as $record) {
unset($this->recordsByTypeAndName[$record[0]][$record[1]]);
}
}
}