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