SmartDaoWorker.class.php

Go to the documentation of this file.
00001 <?php
00002 /***************************************************************************
00003  *   Copyright (C) 2005-2008 by Konstantin V. Arkhipov                     *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU Lesser General Public License as        *
00007  *   published by the Free Software Foundation; either version 3 of the    *
00008  *   License, or (at your option) any later version.                       *
00009  *                                                                         *
00010  ***************************************************************************/
00011 
00020     final class SmartDaoWorker extends TransparentDaoWorker
00021     {
00022         private $indexKey   = null;
00023         
00024         public function __construct(GenericDAO $dao)
00025         {
00026             parent::__construct($dao);
00027             
00028             $this->indexKey =
00029                 $this->watermark
00030                 .$this->className
00031                 .self::SUFFIX_INDEX;
00032         }
00033         
00035 
00036         protected function cacheByQuery(
00037             SelectQuery $query,
00038             /* Identifiable */ $object,
00039             $expires = Cache::EXPIRES_FOREVER
00040         )
00041         {
00042             $queryId = $query->getId();
00043             
00044             $semKey = $this->keyToInt($this->indexKey);
00045             
00046             $key = $this->makeQueryKey($query, self::SUFFIX_QUERY);
00047             
00048             $pool = SemaphorePool::me();
00049             
00050             if ($pool->get($semKey)) {
00051                 $this->syncMap($key);
00052                 
00053                 Cache::me()->mark($this->className)->
00054                     add($key, $object, $expires);
00055                 
00056                 $pool->free($semKey);
00057             }
00058             
00059             return $object;
00060         }
00061         
00062         protected function cacheListByQuery(
00063             SelectQuery $query,
00064             /* array || Cache::NOT_FOUND */ $array
00065         )
00066         {
00067             if ($array !== Cache::NOT_FOUND) {
00068                 Assert::isArray($array);
00069                 Assert::isTrue(current($array) instanceof Identifiable);
00070             }
00071             
00072             $cache = Cache::me();
00073             
00074             $listKey = $this->makeQueryKey($query, self::SUFFIX_LIST);
00075             
00076             $semKey = $this->keyToInt($this->indexKey);
00077             
00078             $pool = SemaphorePool::me();
00079             
00080             if ($pool->get($semKey)) {
00081                 
00082                 $this->syncMap($listKey);
00083                 
00084                 $cache->mark($this->className)->
00085                     add($listKey, $array, Cache::EXPIRES_FOREVER);
00086                 
00087                 if ($array !== Cache::NOT_FOUND)
00088                     foreach ($array as $object)
00089                         $this->cacheById($object);
00090                 
00091                 $pool->free($semKey);
00092             }
00093             
00094             return $array;
00095         }
00097         
00099 
00100         public function uncacheLists()
00101         {
00102             $intKey = $this->keyToInt($this->indexKey);
00103             
00104             $cache = Cache::me();
00105             $pool = SemaphorePool::me();
00106             
00107             if ($pool->get($intKey)) {
00108                 $indexList = $cache->mark($this->className)->get($this->indexKey);
00109                 $cache->mark($this->className)->delete($this->indexKey);
00110                     
00111                 if ($indexList) {
00112                     foreach (array_keys($indexList) as $key)
00113                         $cache->mark($this->className)->delete($key);
00114                 }
00115                 
00116                 $pool->free($intKey);
00117                 
00118                 return true;
00119             }
00120             
00121             $cache->mark($this->className)->delete($this->indexKey);
00122             
00123             return false;
00124         }
00126         
00128 
00129         protected function gentlyGetByKey($key)
00130         {
00131             if ($object = Cache::me()->mark($this->className)->get($key)) {
00132                 if ($this->checkMap($key)) {
00133                     return $object;
00134                 } else {
00135                     Cache::me()->mark($this->className)->delete($key);
00136                 }
00137             }
00138             
00139             return null;
00140         }
00141         
00142         private function syncMap($objectKey)
00143         {
00144             $cache = Cache::me();
00145             
00146             if (!$map = $cache->mark($this->className)->get($this->indexKey))
00147                 $map = array();
00148             
00149             $map[$objectKey] = true;
00150             
00151             $cache->mark($this->className)->
00152                 set($this->indexKey, $map, Cache::EXPIRES_FOREVER);
00153             
00154             return true;
00155         }
00156         
00157         private function checkMap($objectKey)
00158         {
00159             $pool = SemaphorePool::me();
00160             
00161             $semKey = $this->keyToInt($this->indexKey);
00162             
00163             if (!$pool->get($semKey))
00164                 return false;
00165             
00166             if (!$map = Cache::me()->mark($this->className)->get($this->indexKey)) {
00167                 $pool->free($semKey);
00168                 return false;
00169             }
00170             
00171             if (!isset($map[$objectKey])) {
00172                 $pool->free($semKey);
00173                 return false;
00174             }
00175             
00176             $pool->free($semKey);
00177             
00178             return true;
00179         }
00181     }
00182 ?>