Skip to content

Commit 7fee176

Browse files
committed
Merge pull request #91 from AlexeyDsov/uncachersSelf
Introducing Uncachers
2 parents d476b09 + dfcde55 commit 7fee176

23 files changed

+841
-58
lines changed

core/Cache/Cache.class.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,14 @@ public static function me()
5858
self::$peer = $peer;
5959
}
6060

61+
/**
62+
* @return CachePeer
63+
*/
64+
public static function getPeer()
65+
{
66+
return self::$peer;
67+
}
68+
6169
/* void */ public static function setDefaultWorker($worker)
6270
{
6371
Assert::classExists($worker);

core/DB/DB.class.php

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ abstract class DB
4242

4343
private $queue = array();
4444
private $toQueue = false;
45+
/**
46+
* @var UncachersPool
47+
*/
48+
private $uncacher = null;
49+
private $outOfTransactionCachePeer = null;
4550

4651
abstract public function connect();
4752
abstract public function disconnect();
@@ -130,6 +135,9 @@ public function begin(
130135

131136
$this->transaction = true;
132137

138+
$this->outOfTransactionCachePeer = Cache::getPeer();
139+
Cache::setPeer(new RuntimeMemory());
140+
133141
return $this;
134142
}
135143

@@ -146,6 +154,9 @@ public function commit()
146154
$this->transaction = false;
147155
$this->savepointList = array();
148156

157+
Cache::setPeer($this->outOfTransactionCachePeer);
158+
$this->triggerUncacher();
159+
149160
return $this;
150161
}
151162

@@ -162,6 +173,9 @@ public function rollback()
162173
$this->transaction = false;
163174
$this->savepointList = array();
164175

176+
Cache::setPeer($this->outOfTransactionCachePeer);
177+
$this->triggerUncacher();
178+
165179
return $this;
166180
}
167181

@@ -401,6 +415,14 @@ public function setEncoding($encoding)
401415
return $this;
402416
}
403417

418+
public function registerUncacher(UncacherBase $uncacher)
419+
{
420+
$uncacher->uncache();
421+
if ($this->inTransaction()) {
422+
$this->getUncacher()->merge($uncacher);
423+
}
424+
}
425+
404426
/**
405427
* @param string $savepointName
406428
* @return DB
@@ -436,5 +458,21 @@ private function assertSavePointName($savepointName)
436458
{
437459
Assert::isEqual(1, preg_match('~^[A-Za-z][A-Za-z0-9]*$~iu', $savepointName));
438460
}
461+
462+
/**
463+
* @return UncachersPool
464+
*/
465+
private function getUncacher()
466+
{
467+
return $this->uncacher = $this->uncacher ?: UncachersPool::create();
468+
}
469+
470+
private function triggerUncacher()
471+
{
472+
if ($this->uncacher) {
473+
$this->uncacher->uncache();
474+
$this->uncacher = null;
475+
}
476+
}
439477
}
440-
?>
478+
?>

doc/ChangeLog

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,30 @@
1+
2012-07-03 Alexey S. Denisov
2+
3+
* core/Cache/Cache.class.php
4+
core/DB/DB.class.php
5+
global.inc.php.tpl
6+
main/DAOs/BaseDAO.class.php
7+
main/DAOs/GenericDAO.class.php
8+
main/DAOs/Uncachers/UncacherBase.class.php
9+
main/DAOs/Uncachers/UncacherBaseDaoWorker.class.php
10+
main/DAOs/Uncachers/UncacherCacheDaoWorkerLists.class.php
11+
main/DAOs/Uncachers/UncacherCommonDaoWorker.class.php
12+
main/DAOs/Uncachers/UncacherGenericDAO.class.php
13+
main/DAOs/Uncachers/UncacherNullDaoWorker.class.php
14+
main/DAOs/Uncachers/UncacherSmartDaoWorkerLists.class.php
15+
main/DAOs/Uncachers/UncacherTaggableDaoWorker.class.php
16+
main/DAOs/Uncachers/UncacherVoodoDaoWorkerLists.class.php
17+
main/DAOs/Uncachers/UncachersPool.class.php
18+
main/DAOs/Workers/BaseDaoWorker.class.php
19+
main/DAOs/Workers/CacheDaoWorker.class.php
20+
main/DAOs/Workers/CommonDaoWorker.class.php
21+
main/DAOs/Workers/DalayedDropDaoWorker.class.php
22+
main/DAOs/Workers/NullDaoWorker.class.php
23+
main/DAOs/Workers/SmartDaoWorker.class.php
24+
main/DAOs/Workers/VoodooDaoWorker.class.php:
25+
26+
Introducing Uncachers
27+
128
2012-06-29 N. Konstantinov
229

330
* core/DB/PgSQL.class.php

global.inc.php.tpl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@
115115
.ONPHP_MAIN_PATH.'DAOs' .PATH_SEPARATOR
116116
.ONPHP_MAIN_PATH.'DAOs'.DIRECTORY_SEPARATOR.'Handlers'.PATH_SEPARATOR
117117
.ONPHP_MAIN_PATH.'DAOs'.DIRECTORY_SEPARATOR.'Workers'.PATH_SEPARATOR
118+
.ONPHP_MAIN_PATH.'DAOs'.DIRECTORY_SEPARATOR.'Uncachers'.PATH_SEPARATOR
118119

119120
.ONPHP_MAIN_PATH.'Flow' .PATH_SEPARATOR
120121
.ONPHP_MAIN_PATH.'SPL' .PATH_SEPARATOR

main/DAOs/BaseDAO.class.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,12 @@ public function dropByIds(array $ids);
5151
/// uncachers
5252
//@{
5353
public function uncacheById($id);
54+
/**
55+
* @return UncacherBase
56+
*/
57+
public function getUncacherById($id);
5458
public function uncacheByIds($ids);
5559
public function uncacheLists();
5660
//@}
5761
}
58-
?>
62+
?>

main/DAOs/GenericDAO.class.php

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -301,17 +301,32 @@ public function dropByIds(array $ids)
301301

302302
public function uncacheById($id)
303303
{
304-
unset($this->identityMap[$id]);
305-
306-
return Cache::worker($this)->uncacheById($id);
304+
return $this->getUncacherById($id)->uncache();
305+
}
306+
307+
/**
308+
* @return UncachersPool
309+
*/
310+
public function getUncacherById($id)
311+
{
312+
return UncacherGenericDAO::create(
313+
$this,
314+
$id,
315+
Cache::worker($this)->getUncacherById($id)
316+
);
307317
}
308318

309319
public function uncacheByIds($ids)
310320
{
321+
if (empty($ids))
322+
return;
323+
324+
$uncacher = $this->getUncacherById(array_shift($ids));
325+
311326
foreach ($ids as $id)
312-
unset($this->identityMap[$id]);
327+
$uncacher->merge($this->getUncacherById($id));
313328

314-
return Cache::worker($this)->uncacheByIds($ids);
329+
return $uncacher->uncache();
315330
}
316331

317332
public function uncacheLists()
@@ -339,6 +354,11 @@ public function dropObjectIdentityMapById($id)
339354
return $this;
340355
}
341356

357+
public function registerWorkerUncacher(UncacherBase $uncacher)
358+
{
359+
DBPool::getByDao($this)->registerUncacher($uncacher);
360+
}
361+
342362
protected function inject(
343363
InsertOrUpdateQuery $query,
344364
Identifiable $object
@@ -362,19 +382,35 @@ protected function doInject(
362382
$db = DBPool::getByDao($this);
363383

364384
if (!$db->isQueueActive()) {
385+
$preUncacher = is_scalar($object->getId())
386+
? $this->getUncacherById($object->getId())
387+
: null;
388+
365389
$count = $db->queryCount($query);
366390

367-
$this->uncacheById($object->getId());
391+
$uncacher = $this->getUncacherById($object->getId());
392+
if ($preUncacher) {
393+
$uncacher->merge($uncacher);
394+
}
395+
$uncacher->uncache();
368396

369397
if ($count !== 1)
370398
throw new WrongStateException(
371399
$count.' rows affected: racy or insane inject happened: '
372400
.$query->toDialectString($db->getDialect())
373401
);
374402
} else {
403+
$preUncacher = is_scalar($object->getId())
404+
? $this->getUncacherById($object->getId())
405+
: null;
406+
375407
$db->queryNull($query);
376408

377-
$this->uncacheById($object->getId());
409+
$uncacher = $this->getUncacherById($object->getId());
410+
if ($preUncacher) {
411+
$uncacher->merge($uncacher);
412+
}
413+
$uncacher->uncache();
378414
}
379415

380416
// clean out Identifier, if any
@@ -403,4 +439,4 @@ private function addObjectListToMap($list)
403439
return $list;
404440
}
405441
}
406-
?>
442+
?>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
/***************************************************************************
3+
* Copyright (C) 2012 by Aleksey S. Denisov *
4+
* *
5+
* This program is free software; you can redistribute it and/or modify *
6+
* it under the terms of the GNU Lesser General Public License as *
7+
* published by the Free Software Foundation; either version 3 of the *
8+
* License, or (at your option) any later version. *
9+
* *
10+
***************************************************************************/
11+
12+
/**
13+
* @ingroup Uncachers
14+
**/
15+
interface UncacherBase
16+
{
17+
/**
18+
* @param $uncacher BaseUncacher same as self class
19+
* @return BaseUncacher (this)
20+
*/
21+
public function merge(UncacherBase $uncacher);
22+
23+
public function uncache();
24+
}
25+
?>
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php
2+
/***************************************************************************
3+
* Copyright (C) 2012 by Aleksey S. Denisov *
4+
* *
5+
* This program is free software; you can redistribute it and/or modify *
6+
* it under the terms of the GNU Lesser General Public License as *
7+
* published by the Free Software Foundation; either version 3 of the *
8+
* License, or (at your option) any later version. *
9+
* *
10+
***************************************************************************/
11+
12+
/**
13+
* @ingroup Uncachers
14+
**/
15+
class UncacherBaseDaoWorker implements UncacherBase
16+
{
17+
private $classNameMap = array();
18+
19+
/**
20+
* @return UncacherBaseDaoWorker
21+
*/
22+
public static function create($className, $idKey)
23+
{
24+
return new self($className, $idKey);
25+
}
26+
27+
public function __construct($className, $idKey)
28+
{
29+
$this->classNameMap[$className] = array($idKey);
30+
}
31+
32+
public function getClassNameMap()
33+
{
34+
return $this->classNameMap;
35+
}
36+
37+
/**
38+
* @param $uncacher UncacherNullDaoWorker same as self class
39+
* @return BaseUncacher (this)
40+
*/
41+
public function merge(UncacherBase $uncacher)
42+
{
43+
Assert::isInstance($uncacher, get_class($this));
44+
return $this->mergeSelf($uncacher);
45+
}
46+
47+
public function uncache()
48+
{
49+
foreach ($this->classNameMap as $className => $idKeys) {
50+
foreach ($idKeys as $key) {
51+
$this->uncacheClassName($className, $idKeys);
52+
}
53+
}
54+
}
55+
56+
protected function uncacheClassName($className, $idKeys) {
57+
foreach ($idKeys as $key)
58+
Cache::me()->mark($className)->delete($key);
59+
}
60+
61+
/**
62+
* @param UncacherBaseDaoWorker $uncacher
63+
* @return UncacherBaseDaoWorker
64+
*/
65+
private function mergeSelf(UncacherBaseDaoWorker $uncacher)
66+
{
67+
foreach ($uncacher->getClassNameMap() as $className => $idKeys) {
68+
if (isset($this->classNameMap[$className])) {
69+
$this->classNameMap[$className] = ArrayUtils::mergeUnique(
70+
$this->classNameMap[$className],
71+
$idKeys
72+
);
73+
} else {
74+
$this->classNameMap[$className] = $idKeys;
75+
}
76+
}
77+
return $this;
78+
}
79+
}
80+
?>

0 commit comments

Comments
 (0)