Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 41 |
|
0.00% |
0 / 3 |
CRAP | |
0.00% |
0 / 1 |
MultiGetList | |
0.00% |
0 / 41 |
|
0.00% |
0 / 3 |
240 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
get | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
30 | |||
getByKey | |
0.00% |
0 / 30 |
|
0.00% |
0 / 1 |
90 |
1 | <?php |
2 | |
3 | namespace Flow\Repository; |
4 | |
5 | use Flow\Data\FlowObjectCache; |
6 | use Flow\Exception\InvalidParameterException; |
7 | use Flow\Model\UUID; |
8 | |
9 | class MultiGetList { |
10 | |
11 | /** |
12 | * @var FlowObjectCache |
13 | */ |
14 | protected $cache; |
15 | |
16 | /** |
17 | * @param FlowObjectCache $cache |
18 | */ |
19 | public function __construct( FlowObjectCache $cache ) { |
20 | $this->cache = $cache; |
21 | } |
22 | |
23 | /** |
24 | * @param string $treeType |
25 | * @param array $ids |
26 | * @param callable $loadCallback |
27 | * @return array |
28 | * @throws InvalidParameterException |
29 | */ |
30 | public function get( $treeType, array $ids, $loadCallback ) { |
31 | $cacheKeys = []; |
32 | foreach ( $ids as $id ) { |
33 | if ( $id instanceof UUID ) { |
34 | $cacheId = $id; |
35 | } elseif ( is_scalar( $id ) ) { |
36 | $cacheId = UUID::create( $id ); |
37 | } else { |
38 | $type = is_object( $id ) ? get_class( $id ) : gettype( $id ); |
39 | throw new InvalidParameterException( "Not scalar: $type" ); |
40 | } |
41 | // @phan-suppress-next-line PhanTypeMismatchArgumentNullable |
42 | $cacheKeys[ TreeCacheKey::build( $treeType, $cacheId ) ] = $id; |
43 | } |
44 | return $this->getByKey( $cacheKeys, $loadCallback ); |
45 | } |
46 | |
47 | /** |
48 | * @param array $cacheKeys |
49 | * @param callable $loadCallback |
50 | * @return array |
51 | */ |
52 | public function getByKey( array $cacheKeys, $loadCallback ) { |
53 | if ( !$cacheKeys ) { |
54 | return []; |
55 | } |
56 | $result = []; |
57 | $multiRes = $this->cache->getMulti( array_keys( $cacheKeys ) ); |
58 | // Memcached BagOStuff only returns found keys, but the redis bag |
59 | // returns false for not found keys. |
60 | $multiRes = array_filter( |
61 | $multiRes, |
62 | static function ( $val ) { |
63 | return $val !== false; |
64 | } |
65 | ); |
66 | foreach ( $multiRes as $key => $value ) { |
67 | $idx = $cacheKeys[$key]; |
68 | if ( $idx instanceof UUID ) { |
69 | $idx = $idx->getAlphadecimal(); |
70 | } |
71 | $result[$idx] = $value; |
72 | unset( $cacheKeys[$key] ); |
73 | } |
74 | |
75 | if ( count( $cacheKeys ) === 0 ) { |
76 | return $result; |
77 | } |
78 | $res = $loadCallback( array_values( $cacheKeys ) ); |
79 | if ( !$res ) { |
80 | // storage failure of some sort |
81 | return $result; |
82 | } |
83 | $invCacheKeys = []; |
84 | foreach ( $cacheKeys as $cacheKey => $id ) { |
85 | if ( $id instanceof UUID ) { |
86 | $id = $id->getAlphadecimal(); |
87 | } |
88 | $invCacheKeys[$id] = $cacheKey; |
89 | } |
90 | foreach ( $res as $id => $row ) { |
91 | $this->cache->set( $invCacheKeys[$id], $row ); |
92 | $result[$id] = $row; |
93 | } |
94 | |
95 | return $result; |
96 | } |
97 | } |