Permalink
Browse files

Merge branch 'cache-tags'

  • Loading branch information...
taylorotwell committed Nov 1, 2013
2 parents 64f2482 + 1b4d4f2 commit 70108fe4f456f343325234063aa77b9012ede7dd
@@ -1,6 +1,6 @@
<?php namespace Illuminate\Cache;
class ApcStore implements StoreInterface {
class ApcStore extends TaggableStore implements StoreInterface {
/**
* The APC wrapper instance.
@@ -115,17 +115,6 @@ public function flush()
$this->apc->flush();
}
/**
* Begin executing a new section operation.
*
* @param string $name
* @return \Illuminate\Cache\Section
*/
public function section($name)
{
return new Section($this, $name);
}
/**
* Get the cache key prefix.
*
@@ -1,6 +1,6 @@
<?php namespace Illuminate\Cache;
class ArrayStore implements StoreInterface {
class ArrayStore extends TaggableStore implements StoreInterface {
/**
* The array of stored values.
@@ -97,17 +97,6 @@ public function flush()
$this->storage = array();
}
/**
* Begin executing a new section operation.
*
* @param string $name
* @return \Illuminate\Cache\Section
*/
public function section($name)
{
return new Section($this, $name);
}
/**
* Get the cache key prefix.
*
@@ -2,7 +2,7 @@
use Memcached;
class MemcachedStore implements StoreInterface {
class MemcachedStore extends TaggableStore implements StoreInterface {
/**
* The Memcached instance.
@@ -117,17 +117,6 @@ public function flush()
$this->memcached->flush();
}
/**
* Begin executing a new section operation.
*
* @param string $name
* @return \Illuminate\Cache\Section
*/
public function section($name)
{
return new Section($this, $name);
}
/**
* Get the underlying Memcached connection.
*

This file was deleted.

Oops, something went wrong.
@@ -2,7 +2,7 @@
use Illuminate\Redis\Database as Redis;
class RedisStore implements StoreInterface {
class RedisStore extends TaggableStore implements StoreInterface {
/**
* The Redis database connection.
@@ -131,14 +131,14 @@ public function flush()
}
/**
* Begin executing a new section operation.
* Begin executing a new tags operation.
*
* @param string $name
* @return \Illuminate\Cache\RedisSection
* @param array|dynamic $names
* @return \Illuminate\Cache\RedisTaggedCache
*/
public function section($name)
public function tags($names)
{
return new RedisSection($this, $name);
return new RedisTaggedCache($this, is_array($names) ? $names : func_get_args());
}
/**
@@ -0,0 +1,90 @@
<?php namespace Illuminate\Cache;
class RedisTaggedCache extends TaggedCache {
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function forever($key, $value)
{
$this->pushForeverKeys($namespace = $this->tags->getNamespace(), $key);
$this->store->forever(sha1($namespace).':'.$key, $value);
}
/**
* Remove all items from the cache.
*
* @return void
*/
public function flush()
{
$this->deleteForeverKeys();
parent::flush();
}
/**
* Store a copy of the full key for each namespace segment.
*
* @param string $namespace
* @param string $key
* @return void
*/
protected function pushForeverKeys($namespace, $key)
{
$fullKey = $this->getPrefix().sha1($namespace).':'.$key;
foreach (explode('|', $namespace) as $segment)
{
$this->store->connection()->lpush($this->foreverKey($segment), $fullKey);
}
}
/**
* Delete all of the items that were stored forever.
*
* @return void
*/
protected function deleteForeverKeys()
{
foreach (explode('|', $this->tags->getNamespace()) as $segment)
{
$this->deleteForeverValues($segment = $this->foreverKey($segment));
$this->store->connection()->del($segment);
}
}
/**
* Delete all of the keys that have been stored forever.
*
* @param string $foreverKey
* @return void
*/
protected function deleteForeverValues($foreverKey)
{
$forever = array_unique($this->store->connection()->lrange($foreverKey, 0, -1));
if (count($forever) > 0)
{
call_user_func_array(array($this->store->connection(), 'del'), $forever);
}
}
/**
* Get the forever reference key for hte segment.
*
* @param string $segment
* @return string
*/
protected function foreverKey($segment)
{
return $this->getPrefix().$segment.':forever';
}
}
@@ -0,0 +1,110 @@
<?php namespace Illuminate\Cache;
use ArrayIterator;
use IteratorAggregate;
class TagSet implements IteratorAggregate {
/**
* The cache store implementation.
*
* @var \Illuminate\Cache\StoreInterface
*/
protected $store;
/**
* The tag names.
*
* @var array
*/
protected $names = array();
/**
* Create a new TagSet instance.
*
* @param \Illuminate\Cache\StoreInterface $store
* @param string $names
* @return void
*/
public function __construct(StoreInterface $store, $names)
{
$this->store = $store;
$this->names = $names;
}
/**
* Reset all tags in the set.
*
* @return void
*/
public function reset()
{
array_walk($this->names, array($this, 'resetTag'));
}
/**
* Get the unique tag identifier for a given tag.
*
* @param string $name
* @return string
*/
public function tagId($name)
{
return $this->store->get($this->tagKey($name)) ?: $this->resetTag($name);
}
/**
* Get an array of tag identifiers for all of the tags in the set.
*
* @return array
*/
protected function tagIds()
{
return array_map(array($this, 'tagId'), $this->names);
}
/**
* Get a unique namespace that changes when any of the tags are flushed.
*
* @return string
*/
public function getNamespace()
{
return implode('|', $this->tagIds());
}
/**
* Reset the tag and return the new tag identifier
*
* @param string $name
* @return string
*/
public function resetTag($name)
{
$this->store->forever($this->tagKey($name), $id = uniqid());
return $id;
}
/**
* Get the tag identifier key for a given tag.
*
* @param string $name
* @return string
*/
public function tagKey($name)
{
return 'tag:'.$name.':key';
}
/**
* Get a traversable implementation for the class.
*
* @return \ArrayIterator
*/
public function getIterator()
{
return new ArrayIterator($this->names);
}
}
Oops, something went wrong.

0 comments on commit 70108fe

Please sign in to comment.