blob: 069d0f44f75d66f638a7f34a805850e7b3d49fa4 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
<?php
/**
* Base Local cache object, which borrows the concept from Flow user listener
*/
abstract class EchoLocalCache {
/**
* Max number of objects to hold in $targets. In theory, 1000
* is very hard to reach in a normal web request. We need to
* put cap so it doesn't reach memory limit when running email
* digest against large amount of notications
*/
const TARGET_MAX_NUM = 1000;
/**
* Target object cache
* @var MapCacheLRU
*/
protected $targets;
/**
* Lookup ids that have not been resolved for a target
* @var int[]
*/
private $lookups = [];
/**
* Resolve ids in lookups to targets
*
* @param int[] $lookups
* @return Iterator
*/
abstract protected function resolve( array $lookups );
/**
* Use a factory method, such as EchoTitleLocalCache::create().
*
* @private
*/
public function __construct() {
$this->targets = new MapCacheLRU( self::TARGET_MAX_NUM );
}
/**
* Add a key to the lookup and the key is used to resolve cache target
*
* @param int $key
*/
public function add( $key ) {
if (
count( $this->lookups ) < self::TARGET_MAX_NUM
&& !$this->targets->get( $key )
) {
$this->lookups[$key] = true;
}
}
/**
* Get the cache target based on the key
*
* @param int $key
* @return mixed|null
*/
public function get( $key ) {
$target = $this->targets->get( $key );
if ( $target ) {
return $target;
}
if ( isset( $this->lookups[ $key ] ) ) {
// Resolve the lookup batch and store results in the cache
$targets = $this->resolve( array_keys( $this->lookups ) );
foreach ( $targets as $id => $val ) {
$this->targets->set( $id, $val );
}
$this->lookups = [];
$target = $this->targets->get( $key );
if ( $target ) {
return $target;
}
}
return null;
}
/**
* Clear everything in local cache
*/
public function clearAll() {
$this->targets->clear();
$this->lookups = [];
}
}
|