Completed
Push — master ( 1d7ad2...efdc9e )
by Michele
05:30
created

LRUCache::prune()   B

Complexity

Conditions 5
Paths 2

Size

Total Lines 18
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 5

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 18
ccs 15
cts 15
cp 1
rs 8.8571
cc 5
eloc 12
nc 2
nop 0
crap 5
1
<?php
2
3
namespace CHMLib\LZX;
4
5
use Exception;
6
7
/**
8
 * Handle the cache of recently used data.
9
 */
10
class LRUCache
11
{
12
    /**
13
     * The cached items.
14
     *
15
     * @var LRUCacheItem[]
16
     */
17
    protected $cache;
18
19
    /**
20
     * The maximim capacity of the cache.
21
     *
22
     * @var int
23
     */
24
    protected $capacity;
25
26
    /**
27
     * Initializes the instance.
28
     *
29
     * @param int $capacity The maximim capacity of the cache.
30
     *
31
     * @throws Exception Throws an Exception in case of errors.
32
     */
33 1
    public function __construct($capacity)
34
    {
35 1
        $this->capacity = (int) $capacity;
36 1
        if ($this->capacity < 1) {
37
            throw new Exception('The cache capacity must be greather than zero');
38
        }
39 1
        $this->cache = array();
40 1
    }
41
42
    /**
43
     * Get a cached items given its key (return null if no cached items with the specified key).
44
     *
45
     * @param mixed $key
46
     *
47
     * @return mixed|null
48
     */
49 464
    public function get($key)
50
    {
51 464
        $result = null;
52 464
        if (isset($this->cache[$key])) {
53 456
            $item = $this->cache[$key];
54 456
            array_map(
55 456
                function (LRUCacheItem $i) {
56 456
                    --$i->hits;
57 456
                },
58 456
                $this->cache
59 456
            );
60 456
            $item->hits += 2;
61 456
            $result = $item->value;
62 456
        }
63
64 464
        return $result;
65
    }
66
67
    /**
68
     * Ensure that the cache has at least one empty slot (it the cache is full, we'll remove the less used cache item).
69
     *
70
     * @return null|mixed Returns null if no item has been removed, otherwise returns the value of the removed item.
71
     */
72 23
    public function prune()
73
    {
74 23
        $result = null;
75 23
        if (count($this->cache) >= $this->capacity) {
76 15
            $kick = null;
77 15
            $kickKey = null;
78 15
            foreach ($this->cache as $key => $item) {
79 15
                if ($kick === null || $kick->hits > $item->hits) {
80 15
                    $kick = $item;
81 15
                    $kickKey = $key;
82 15
                }
83 15
            }
84 15
            unset($this->cache[$kickKey]);
85 15
            $result = $kick->value;
86 15
        }
87
88 23
        return $result;
89
    }
90
91
    /**
92
     * Add a new item to the cache.
93
     *
94
     * @param mixed $key The key to assign to the cached item.
95
     * @param mixed $value The value to be cached.
96
     */
97 23
    public function put($key, $value)
98
    {
99 23
        if (!isset($this->cache[$key])) {
100 23
            $this->prune();
101 23
        }
102 23
        $this->cache[$key] = new LRUCacheItem($value);
103 23
    }
104
105
    /**
106
     * Clear the cache.
107
     */
108
    public function clear()
109
    {
110
        $this->cache = array();
111
    }
112
113
    /**
114
     * Get the number of the currently cached items.
115
     *
116
     * @return int
117
     */
118
    public function size()
119
    {
120
        return count($this->cache);
121
    }
122
}
123