Skip to content

Commit

Permalink
Make sure that memoized caches handle (don't set/remove) staged value…
Browse files Browse the repository at this point in the history
…s from the staging cache.
  • Loading branch information
karptonite committed Oct 23, 2024
1 parent 1f08546 commit 94ad55b
Show file tree
Hide file tree
Showing 18 changed files with 248 additions and 22 deletions.
5 changes: 0 additions & 5 deletions src/Cache/AbstractBaseCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,4 @@ protected function callRegenerator(callable $regenerator)
{
return $regenerator(false);
}

public function getGetCount():int
{
return 0;
}
}
17 changes: 13 additions & 4 deletions src/Cache/ArrayCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace GeekCache\Cache;

class ArrayCache extends AbstractBaseCache implements Cache
class ArrayCache extends AbstractBaseCache implements CheckableCache
{
private $cache = array();
private $maxputs;
Expand All @@ -15,10 +15,10 @@ public function __construct($maxputs = null)

public function get($key, callable $regenerator = null, $ttl = 0)
{
return $this->cacheExists($key) ? $this->cache[$key] : $this->regenerate($key, $regenerator, $ttl);
return $this->has($key) ? $this->cache[$key] : $this->regenerate($key, $regenerator, $ttl);
}

protected function cacheExists($key)
public function has($key): bool
{
return array_key_exists($key, $this->cache);
}
Expand All @@ -36,7 +36,7 @@ public function put($key, $value, $ttl = 0)

private function putIsPermitted($key)
{
return !$this->maxputs || $this->putcount < $this->maxputs || $this->cacheExists($key);
return !$this->maxputs || $this->putcount < $this->maxputs || $this->has($key);
}

public function delete($key)
Expand All @@ -53,4 +53,13 @@ public function clear()
public function stage(string $key):void
{
}

public function unstage(string $key):void
{
}

public function getGetCount():int
{
return 0;
}
}
2 changes: 2 additions & 0 deletions src/Cache/Cache.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
interface Cache
{
public function stage(string $key): void;
public function unstage(string $key): void;
public function get($key, callable $regenerator = null, $ttl = 0);
public function put($key, $value, $ttl = 0);
public function delete($key);
public function clear();
// the functions below are used only for debugging
public function getGetCount(): int;
}
10 changes: 10 additions & 0 deletions src/Cache/CacheDecorator.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ public function stage(string $key): void
{
$this->cache->stage($key);
}

public function unstage(string $key): void
{
$this->cache->unstage($key);
}

public function put($key, $value, $ttl = 0)
{
Expand All @@ -35,4 +40,9 @@ public function clear()
{
return $this->cache->clear();
}

public function getGetCount(): int
{
return $this->cache->getGetCount();
}
}
8 changes: 8 additions & 0 deletions src/Cache/CheckableCache.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace GeekCache\Cache;

interface CheckableCache extends Cache
{
public function has($key): bool;
}
4 changes: 2 additions & 2 deletions src/Cache/IncrementableArrayCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace GeekCache\Cache;

class IncrementableArrayCache extends ArrayCache implements IncrementableCache
class IncrementableArrayCache extends ArrayCache implements IncrementableCheckableCache
{
public function increment($key, $value = 1, $ttl = 0)
{
Expand All @@ -24,7 +24,7 @@ private function shouldIncrement($value)

private function shouldDecrement($key, $value)
{
return $value < 0 && $this->cacheExists($key);
return $value < 0 && $this->has($key);
}

private function decrementNumber($current, $value)
Expand Down
7 changes: 7 additions & 0 deletions src/Cache/IncrementableCheckableCache.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace GeekCache\Cache;

interface IncrementableCheckableCache extends CheckableCache, IncrementableCache
{
}
2 changes: 1 addition & 1 deletion src/Cache/IncrementableMemoizedCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class IncrementableMemoizedCache extends MemoizedCache implements IncrementableC
{
private $incrementablecache;

public function __construct(IncrementableCache $incrementablecache, Cache $memocache)
public function __construct(IncrementableCache $incrementablecache, CheckableCache $memocache)
{
parent::__construct($incrementablecache, $memocache);
$this->incrementablecache = $incrementablecache;
Expand Down
15 changes: 13 additions & 2 deletions src/Cache/MemoizedCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,27 @@ class MemoizedCache extends CacheDecorator
{
private $memocache;

public function __construct(Cache $primaryCache, Cache $memocache)
public function __construct(Cache $primaryCache, CheckableCache $memocache)
{
parent::__construct($primaryCache);
$this->memocache = $memocache;
}

public function stage($key):void
{
if (!$this->memocache->has($key)) {
parent::stage($key);
}
}

public function get($key, callable $regenerator = null, $ttl = 0)
{
$result = $this->memocache->get($key);
return $result !== false ? $result : $this->getAndMemoize($key, $regenerator, $ttl);
if ($result !== false) {
parent::unstage($key);
return $result;
}
return $this->getAndMemoize($key, $regenerator, $ttl);
}

public function put($key, $value, $ttl = 0)
Expand Down
11 changes: 10 additions & 1 deletion src/Cache/NullCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@

namespace GeekCache\Cache;

class NullCache implements Cache, IncrementableCache
class NullCache implements IncrementableCheckableCache
{
public function get($key, callable $regenerator = null, $ttl = 0)
{
return false;
}

public function has($key): bool
{
return false;
}

public function put($key, $value, $ttl = 0)
{
Expand Down Expand Up @@ -37,4 +42,8 @@ public function getGetCount():int
public function stage(string $key): void
{
}

public function unstage(string $key): void
{
}
}
7 changes: 6 additions & 1 deletion src/Cache/StageableCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@ public function stage(string $key): void
{
$this->stagingCache->stage($key);
}


public function unstage(string $key): void
{
$this->stagingCache->unstage($key);
}

public function get($key, callable $regenerator = null, $ttl = 0)
{
// if we have a pending result, use that
Expand Down
7 changes: 7 additions & 0 deletions src/Cache/StagingCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ public function stage(string $key): void
$this->stagedRequests[$key] = ($this->stagedRequests[$key] ?? null) ? $this->stagedRequests[$key] + 1 : 1;
}

//fully unstage all counts for key
public function unstage(string $key): void
{
unset($this->stagedRequests[$key]);
unset($this->stagedResults[$key]);
}

public function resultIsStaged(string $key): bool
{
return array_key_exists($key, $this->stagedResults);
Expand Down
2 changes: 1 addition & 1 deletion src/Counter/CounterBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class CounterBuilder

private $stack;

public function __construct(Cache\IncrementableCache $cache, Cache\IncrementableCache $memocache, array $stack = null)
public function __construct(Cache\IncrementableCache $cache, Cache\IncrementableCheckableCache $memocache, array $stack = null)
{
$this->cache = $cache;
$this->memocache = $memocache;
Expand Down
6 changes: 3 additions & 3 deletions tests/Cache/BaseCacheTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@ public function testGetWithCacheMiss()
{
$this->assertCacheReturnsFalseOnCacheMiss($this->cache);
}

public function testPutAndGet()
{
$this->assertCachePutsAndGets($this->cache);
}

public function testPutReturnsTrueOnSuccess()
{
$result = $this->cache->put( self::KEY, self::VALUE );
$this->assertTrue( $result );
$result = $this->cache->put(self::KEY, self::VALUE);
$this->assertTrue($result);
}

public function testPutAndGetZero()
Expand Down
2 changes: 1 addition & 1 deletion tests/Cache/CacheBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public function tearDown(): void
public function prepareFullMockBuilder()
{
$this->cache = m::mock('GeekCache\Cache\Cache');
$this->memocache = m::mock('GeekCache\Cache\Cache');
$this->memocache = m::mock('GeekCache\Cache\CheckableCache');
$this->tagsetfactory = m::mock('GeekCache\Tag\TagSetFactory');

$this->builder = new GeekCache\Cache\CacheBuilder($this->cache, $this->memocache, $this->tagsetfactory);
Expand Down
1 change: 1 addition & 0 deletions tests/Cache/TaggedCacheMemcachedTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class TaggedCacheMemcachedTest extends BaseCacheTest

const TAG_NAMES = ['TAG_1', 'TAG_2'];
const TAG_NAMES2 = ['TAG_3', 'TAG_4'];
private $parentcache;

public function setUp(): void
{
Expand Down
Loading

0 comments on commit 94ad55b

Please sign in to comment.