[incomplete]Memcached Element and ElementList auto version control [占位]
This is my 1st version, maybe i can use getMulti and setMulti refactor it(优化之).
class CacheUtils { const CACHE_MAX_VERSION = 10; private $memcache; private static $instance; private function __construct() { $this->memcache = new Memcache(); $this->memcache->connect('127.0.0.1', 11211) or die('Can not connect to memcached server.'); } public static function getInstance() { if(self::$instance == null) { self::$instance = new CacheUtils(); } return self::$instance; } public function addElementVersion($type) { $key = 'Element_Version:'.$type; $ver = $this->memcache->increment($key); if ($ver == false) { $ver = $this->memcache->set($key, 0); $ver = $this->memcache->increment($key); } else if ($ver > self::CACHE_MAX_VERSION) { // flush all! keep data correct $this->memcache->flush(); } return $ver; } public function getElementVersion($type) { $key = 'Element_Version:'.$type; return $this->memcache->get($key); } public function addElement($elem) { $key = 'Element:'.$elem->type.':'.$elem->id; $retE = $this->memcache->set($key, $elem); $retV = $this->addElementVersion($elem->type); return $retE && $retV; } public function getElement($type, $id) { $key = 'Element:'.$type.':'.$id; return $this->memcache->get($key); } public function getElementListVersion($type, $sql) { $key = 'Element_List_Version:'.$type.':'.$sql; return $this->memcache->get($key); } public function addElementList($type, $list, $sql = '') { $keyList = 'Element_List:'.$type.':'.$sql; $keyVersion = 'Element_List_Version:'.$type.':'.$sql; $ver = $this->getElementVersion($type); $retL = $this->memcache->set($keyList, $list); $retV = $this->memcache->set($keyVersion, $ver); return $retL && $retV; } public function getElementList($type, $sql = '') { $keyList = 'Element_List:'.$type.':'.$sql; $elementVersion = $this->getElementVersion($type); $elementListVersion = $this->getElementListVersion($type, $sql); if ($elementListVersion != $elementVersion) return false; else return $this->memcache->get($keyList); } }
Test Case:
<?php require_once 'PHPUnit/Framework.php'; require_once dirname(__FILE__).'/../CacheUtils.php'; class Person { public $id; public $name; public $age; public $createTime; public $type; function __construct($id, $name, $age) { $this->id = $id; $this->name = $name; $this->age = $age; $this->type = get_class($this); $this->createTime = time(); } } /** * Test class for CacheFacade. * Generated by PHPUnit on 2010-03-28 at 04:07:43. */ class CacheUtilsTest extends PHPUnit_Framework_TestCase { /** * testAddElement */ public function testAddAndGetElement() { $cacheUtils = CacheUtils::getInstance(); $person = new Person(101,'Linx', 29); $this->assertEquals(true, $cacheUtils->addElement($person)); $personGet = $cacheUtils->getElement('Person', 101); $this->assertEquals('Linx', $personGet->name); var_dump($personGet); } public function testAddAndGetElementList() { $cacheUtils = CacheUtils::getInstance(); $person1 = new Person(101,'Linx1', 29); $person2 = new Person(102,'Linx2', 30); $list = array($person1, $person2); $this->assertEquals(true, $cacheUtils->addElementList('Person', $list)); $listGet = $cacheUtils->getElementList('Person'); $this->assertEquals(2, count($listGet)); $this->assertEquals('Linx1', $listGet[0]->name); var_dump($listGet); } public function testAddAndGetElementListExpired() { $cacheUtils = CacheUtils::getInstance(); $person1 = new Person(101,'Linx1', 29); $person2 = new Person(102,'Linx2', 30); $list = array($person1, $person2); $this->assertEquals(true, $cacheUtils->addElementList('Person', $list)); // Person v2 $this->assertEquals(true, $cacheUtils->addElement($person1)); // v1 is expired $listGet = $cacheUtils->getElementList('Person'); $this->assertEquals(false, $listGet); var_dump($listGet); } } ?>