<?php if (!defined('VB_ENTRY')) die('Access denied.'); class vB_Datastore_Memcached extends vB_Datastore { protected $memcache = null; protected $memcache_set = true; protected $store_result = false; public function __construct(&$config, &$db_assertor) { parent::__construct($config, $db_assertor); if (!empty($config['Cache']['memcacheprefix'])) { $this->prefix = & $config['Cache']['memcacheprefix']; } $this->memcache = vB_Memcache::instance(); } public function resetCache() { $this->memcache->flush(); } public function fetch($items) { if (!sizeof($items = $this->prepare_itemarray($items))) { return; } $this->fastDSFetch($items); if (empty($items)) { return true; } $check = $this->memcache->connect(); if ($check == 3) { return parent::fetch($items); } $this->memcache_set = false; $unfetched_items = $this->do_fetch($items); $this->store_result = true; if (!empty($unfetched_items)) { if (!($result = $this->do_db_fetch($this->prepare_itemlist($unfetched_items)))) { $this->memcache_set = true; return false; } } $this->memcache_set = true; $this->store_result = false; $this->check_options(); return true; } protected function do_fetch($items) { $cacheKeys = array(); foreach ($items as $title) { $cacheKeys[$title] = $this->prefix . $title; } $found = $this->memcache->get($cacheKeys); if (empty($found)) { return $items; } $unfetched_items = array(); foreach($items as $title) { if (isset($found[$cacheKeys[$title]])) { $this->register($title, $found[$cacheKeys[$title]]); } else { $unfetched_items[] = $title; } } return $unfetched_items; } protected function register($title, $data, $unserialize_detect = 2) { if ($this->store_result === true) { $this->storeMemcache($title, $data); } parent::register($title, $data, $unserialize_detect); } public function build($title = '', $data = '', $unserialize = 0, $storelocal = true) { parent::build($title, $data, $unserialize, $storelocal); $this->storeMemcache($title, $data); } public function delete($title) { parent::delete($title); $check = $this->memcache->connect(); if ($check == 3) { throw new Exception('Unable to connect to memcache server'); } $ptitle = $this->prefix . $title; $this->memcache->delete($ptitle); } protected function storeMemcache($title, $data) { $check = $this->memcache->connect(); if ($check == 3) { throw new Exception('Unable to connect to memcache server'); } $ptitle = $this->prefix . $title; if ($this->memcache_set) { $this->memcache->set($ptitle, $data); } else { $this->memcache->add($ptitle, $data); } } public function clearValues() { if (!defined('VB_UNITTEST')) { throw new Exception('This method should be called only from unit tests'); } else { $this->memcache_set = true; $this->store_result = false; $this->memcache->flush(); parent::clearValues(); } } } 