Completed
Push — master ( 0f341b...3e6c76 )
by Tobias
21:32
created

CacheDataCollector::calculateTotalStatistics()   B

Complexity

Conditions 4
Paths 6

Size

Total Lines 25
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 25
rs 8.5806
c 0
b 0
f 0
cc 4
eloc 18
nc 6
nop 0
1
<?php
2
3
/*
4
 * This file is part of php-cache\cache-bundle package.
5
 *
6
 * (c) 2015-2015 Aaron Scherer <[email protected]>, Tobias Nyholm <[email protected]>
7
 *
8
 * This source file is subject to the MIT license that is bundled
9
 * with this source code in the file LICENSE.
10
 */
11
12
namespace Cache\CacheBundle\DataCollector;
13
14
use Cache\CacheBundle\Cache\Recording\CachePool;
15
use Cache\CacheBundle\Cache\Recording\TraceableAdapterEvent;
16
use Symfony\Component\HttpFoundation\Request;
17
use Symfony\Component\HttpFoundation\Response;
18
use Symfony\Component\HttpKernel\DataCollector\DataCollector;
19
20
/**
21
 * @author Aaron Scherer <[email protected]>
22
 * @author Tobias Nyholm <[email protected]>
23
 */
24
class CacheDataCollector extends DataCollector
25
{
26
    /**
27
     * @type CachePool[]
28
     */
29
    private $instances = [];
30
31
    /**
32
     * @param string    $name
33
     * @param CachePool $instance
34
     */
35
    public function addInstance($name, CachePool $instance)
36
    {
37
        $this->instances[$name] = $instance;
38
    }
39
40
    /**
41
     * {@inheritdoc}
42
     */
43
    public function collect(Request $request, Response $response, \Exception $exception = null)
44
    {
45
        $empty      = ['calls' => [], 'config' => [], 'options' => [], 'statistics' => []];
46
        $this->data = ['instances' => $empty, 'total' => $empty];
47
        foreach ($this->instances as $name => $instance) {
48
            $this->data['instances']['calls'][$name] = $instance->getCalls();
49
        }
50
51
        $this->data['instances']['statistics'] = $this->calculateStatistics();
52
        $this->data['total']['statistics']     = $this->calculateTotalStatistics();
53
    }
54
55
    /**
56
     * {@inheritdoc}
57
     */
58
    public function getName()
59
    {
60
        return 'php-cache';
61
    }
62
63
    /**
64
     * Method returns amount of logged Cache reads: "get" calls.
65
     *
66
     * @return array
67
     */
68
    public function getStatistics()
69
    {
70
        return $this->data['instances']['statistics'];
71
    }
72
73
    /**
74
     * Method returns the statistic totals.
75
     *
76
     * @return array
77
     */
78
    public function getTotals()
79
    {
80
        return $this->data['total']['statistics'];
81
    }
82
83
    /**
84
     * Method returns all logged Cache call objects.
85
     *
86
     * @return mixed
87
     */
88
    public function getCalls()
89
    {
90
        return $this->data['instances']['calls'];
91
    }
92
93
    /**
94
     * @return array
95
     */
96
    private function calculateStatistics()
97
    {
98
        $statistics = [];
99
        foreach ($this->data['instances']['calls'] as $name => $calls) {
100
            $statistics[$name] = [
101
                'calls'   => 0,
102
                'time'    => 0,
103
                'reads'   => 0,
104
                'writes'  => 0,
105
                'deletes' => 0,
106
                'hits'    => 0,
107
                'misses'  => 0,
108
            ];
109
            /** @type TraceableAdapterEvent $call */
110
            foreach ($calls as $call) {
111
                $statistics[$name]['calls'] += 1;
112
                $statistics[$name]['time'] += $call->end - $call->start;
113
                if ('getItem' === $call->name) {
114
                    $statistics[$name]['reads'] += 1;
115 View Code Duplication
                    if ($call->hits) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
116
                        $statistics[$name]['hits'] += 1;
117
                    } else {
118
                        $statistics[$name]['misses'] += 1;
119
                    }
120
                } elseif ('getItems' === $call->name) {
121
                    $count = $call->hits + $call->misses;
122
                    $statistics[$name]['reads'] += $count;
123
                    $statistics[$name]['hits'] += $call->hits;
124
                    $statistics[$name]['misses'] += $count - $call->misses;
125
                } elseif ('hasItem' === $call->name) {
126
                    $statistics[$name]['reads'] += 1;
127 View Code Duplication
                    if (false === $call->result) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
128
                        $statistics[$name]['misses'] += 1;
129
                    } else {
130
                        $statistics[$name]['hits'] += 1;
131
                    }
132
                } elseif ('save' === $call->name) {
133
                    $statistics[$name]['writes'] += 1;
134
                } elseif ('deleteItem' === $call->name) {
135
                    $statistics[$name]['deletes'] += 1;
136
                }
137
            }
138
            if ($statistics[$name]['reads']) {
139
                $statistics[$name]['hit_read_ratio'] = round(100 * $statistics[$name]['hits'] / $statistics[$name]['reads'], 2);
140
            } else {
141
                $statistics[$name]['hit_read_ratio'] = null;
142
            }
143
        }
144
145
        return $statistics;
146
    }
147
148
    /**
149
     * @return array
150
     */
151
    private function calculateTotalStatistics()
152
    {
153
        $statistics = $this->getStatistics();
154
        $totals     = [
155
            'calls'   => 0,
156
            'time'    => 0,
157
            'reads'   => 0,
158
            'writes'  => 0,
159
            'deletes' => 0,
160
            'hits'    => 0,
161
            'misses'  => 0,
162
        ];
163
        foreach ($statistics as $name => $values) {
164
            foreach ($totals as $key => $value) {
165
                $totals[$key] += $statistics[$name][$key];
166
            }
167
        }
168
        if ($totals['reads']) {
169
            $totals['hit_read_ratio'] = round(100 * $totals['hits'] / $totals['reads'], 2);
170
        } else {
171
            $totals['hit_read_ratio'] = null;
172
        }
173
174
        return $totals;
175
    }
176
}
177