Completed
Push — master ( 8f132d...823be9 )
by Hong
03:07
created

PriorityQueueTrait::flush()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 0
1
<?php
2
/**
3
 * Phossa Project
4
 *
5
 * PHP version 5.4
6
 *
7
 * @category  Library
8
 * @package   Phossa2\Shared
9
 * @copyright Copyright (c) 2016 phossa.com
10
 * @license   http://mit-license.org/ MIT License
11
 * @link      http://www.phossa.com/
12
 */
13
/*# declare(strict_types=1); */
14
15
namespace Phossa2\Shared\Queue;
16
17
/**
18
 * PriorityQueueTrait
19
 *
20
 * @package Phossa2\Shared
21
 * @author  Hong Zhang <[email protected]>
22
 * @see     PriorityQueueInterface
23
 * @version 2.0.20
24
 * @since   2.0.20 added
25
 */
26
trait PriorityQueueTrait
27
{
28
    /**
29
     * inner data storage
30
     *
31
     * @var    array
32
     * @access protected
33
     */
34
    protected $queue = [];
35
36
    /**
37
     * marker for sorted queue
38
     *
39
     * @var    bool
40
     * @access protected
41
     */
42
    protected $sorted = false;
43
44
    /**
45
     * priority counter, descreasing
46
     *
47
     * @var    int
48
     * @access protected
49
     */
50
    protected $counter = 10000000;
51
52
    /**
53
     * {@inheritDoc}
54
     */
55
    public function insert($data, /*# int */ $priority = 0)
56
    {
57
        // fix priority
58
        $pri = $this->fixPriority((int) $priority);
59
60
        // generate key to be used (int)
61
        $key = $this->generateKey($pri);
62
63
        // make sure not duplicated
64
        $this->remove($data);
65
66
        // added to the queue
67
        $this->queue[$key] = ['data' => $data, 'priority' => $pri];
68
69
        // mark as not sorted
70
        $this->sorted = false;
71
72
        return $this;
73
    }
74
75
    /**
76
     * {@inheritDoc}
77
     */
78
    public function remove($data)
79
    {
80
        foreach ($this->queue as $key => $val) {
81
            if ($val['data'] === $data) {
82
                unset($this->queue[$key]);
83
                break;
84
            }
85
        }
86
        return $this;
87
    }
88
89
    /**
90
     * {@inheritdic}
91
     */
92
    public function flush()
93
    {
94
        $this->queue = [];
95
        return $this;
96
    }
97
98
    /**
99
     * {@inheritDoc}
100
     */
101
    public function combine(
102
        PriorityQueueInterface $queue
103
    )/*# : PriorityQueueInterface */ {
104
        // clone a new queue
105
        $nqueue = clone $this;
106
107
        // insert into new queue
108
        foreach ($queue as $data) {
109
            $nqueue->insert($data['data'], $data['priority']);
110
        }
111
112
        return $nqueue;
113
    }
114
115
    /**
116
     * {@inheritDoc}
117
     */
118
    public function count()
119
    {
120
        return count($this->queue);
121
    }
122
123
    /**
124
     * {@inheritDoc}
125
     */
126
    public function getIterator()
127
    {
128
        // sort queue if not yet
129
        $this->sortQueue();
130
131
        // return iterator
132
        return new \ArrayIterator($this->queue);
133
    }
134
135
    /**
136
     * Make sure priority in the range of -100 - +100
137
     *
138
     * @param  int $priority
139
     * @return int
140
     * @access protected
141
     */
142
    protected function fixPriority(/*# int */ $priority)/*# : int */
143
    {
144
        return (int) ($priority > 100 ? 100 : ($priority < -100 ? -100 : $priority));
145
    }
146
147
    /**
148
     * Generate one int base on the priority
149
     *
150
     * @param  int $priority
151
     * @return int
152
     * @access protected
153
     */
154
    protected function generateKey(/*# int */ $priority)/*# : int */
155
    {
156
        return ($priority + 100) * 10000000 + --$this->counter;
157
    }
158
159
    /**
160
     * Sort the queue from higher to lower int $key
161
     *
162
     * @return $this
163
     * @access protected
164
     */
165
    protected function sortQueue()
166
    {
167
        if (!$this->sorted) {
168
            krsort($this->queue);
169
            $this->sorted = true;
170
        }
171
        return $this;
172
    }
173
}
174
175