# 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 ?>