00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00021 final class SmartDaoWorker extends TransparentDaoWorker
00022 {
00023 private $indexKey = null;
00024 private $watermark = null;
00025
00026 public function __construct(GenericDAO $dao)
00027 {
00028 parent::__construct($dao);
00029
00030 if (($cache = Cache::me()) instanceof WatermarkedPeer)
00031 $this->watermark =
00032 $cache->mark($this->className)->getActualWatermark();
00033 else
00034 $this->watermark = null;
00035
00036 $this->indexKey =
00037 $this->watermark
00038 .$this->className
00039 .self::SUFFIX_INDEX;
00040 }
00041
00043
00044 public function cacheByQuery(
00045 SelectQuery $query, $object
00046 )
00047 {
00048 $queryId = $query->getId();
00049
00050 $semKey = $this->keyToInt($this->indexKey);
00051
00052 $key = $this->watermark.$this->className.self::SUFFIX_QUERY.$queryId;
00053
00054 $pool = SemaphorePool::me();
00055
00056 if ($pool->get($semKey)) {
00057 $this->syncMap($key);
00058
00059 Cache::me()->mark($this->className)->
00060 add($key, $object, Cache::EXPIRES_FOREVER);
00061
00062 $pool->free($semKey);
00063 }
00064
00065 return $object;
00066 }
00067
00068 public function cacheListByQuery(SelectQuery $query, $array)
00069 {
00070 if ($array !== Cache::NOT_FOUND) {
00071 Assert::isArray($array);
00072 Assert::isTrue(current($array) instanceof Identifiable);
00073 }
00074
00075 $cache = Cache::me();
00076
00077 $listKey =
00078 $this->watermark
00079 .$this->className
00080 .self::SUFFIX_LIST
00081 .$query->getId();
00082
00083 $semKey = $this->keyToInt($this->indexKey);
00084
00085 $pool = SemaphorePool::me();
00086
00087 if ($pool->get($semKey)) {
00088
00089 $this->syncMap($listKey);
00090
00091 $cache->mark($this->className)->
00092 add($listKey, $array, Cache::EXPIRES_FOREVER);
00093
00094 if ($array !== Cache::NOT_FOUND)
00095 foreach ($array as $object)
00096 $this->cacheById($object);
00097
00098 $pool->free($semKey);
00099 }
00100
00101 return $array;
00102 }
00104
00106
00107 public function uncacheLists()
00108 {
00109 $intKey = $this->keyToInt($this->indexKey);
00110
00111 $cache = Cache::me();
00112 $pool = SemaphorePool::me();
00113
00114 if ($pool->get($intKey)) {
00115 $indexList = $cache->mark($this->className)->get($this->indexKey);
00116 $cache->mark($this->className)->delete($this->indexKey);
00117
00118 if ($indexList) {
00119 foreach (array_keys($indexList) as $key)
00120 $cache->mark($this->className)->delete($key);
00121 }
00122
00123 $pool->free($intKey);
00124
00125 return true;
00126 }
00127
00128 $cache->mark($this->className)->delete($this->indexKey);
00129
00130 return false;
00131 }
00133
00135
00136 protected function gentlyGetByKey($key)
00137 {
00138 if ($object = Cache::me()->mark($this->className)->get($key)) {
00139 if ($this->checkMap($key)) {
00140 return $object;
00141 } else {
00142 Cache::me()->mark($this->className)->delete($key);
00143 }
00144 }
00145
00146 return null;
00147 }
00148
00149 private function syncMap($objectKey)
00150 {
00151 $cache = Cache::me();
00152
00153 if (!$map = $cache->mark($this->className)->get($this->indexKey))
00154 $map = array();
00155
00156 $map[$objectKey] = true;
00157
00158 $cache->mark($this->className)->
00159 set($this->indexKey, $map, Cache::EXPIRES_FOREVER);
00160
00161 return true;
00162 }
00163
00164 private function checkMap($objectKey)
00165 {
00166 $pool = SemaphorePool::me();
00167
00168 $semKey = $this->keyToInt($this->indexKey);
00169
00170 if (!$pool->get($semKey))
00171 return false;
00172
00173 if (!$map = Cache::me()->mark($this->className)->get($this->indexKey)) {
00174 $pool->free($semKey);
00175 return false;
00176 }
00177
00178 if (!isset($map[$objectKey])) {
00179 $pool->free($semKey);
00180 return false;
00181 }
00182
00183 $pool->free($semKey);
00184
00185 return true;
00186 }
00188 }
00189 ?>