Completed
Push — refactor ( 58c596...fef2f5 )
by Bogdan
02:50
created

ObjectMap::get()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2.032

Importance

Changes 0
Metric Value
dl 0
loc 10
ccs 4
cts 5
cp 0.8
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 5
nc 2
nop 1
crap 2.032
1
<?php declare(strict_types=1);
2
3
/*
4
 * This file is part of the pinepain/php-object-maps PHP library.
5
 *
6
 * Copyright (c) 2016-2017 Bogdan Padalko <[email protected]>
7
 *
8
 * Licensed under the MIT license: http://opensource.org/licenses/MIT
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code or visit http://opensource.org/licenses/MIT
12
 */
13
14
15
namespace Pinepain\ObjectMaps;
16
17
18
use OutOfBoundsException;
19
use OverflowException;
20
use Ref\WeakReference;
21
22
use function spl_object_hash;
23
24
25
class ObjectMap implements ObjectMapInterface
26
{
27
    const WEAK_KEY = 1 << 0;
28
    const WEAK_VALUE = 1 << 1;
29
    const WEAK_KEY_VALUE = self::WEAK_KEY | self::WEAK_VALUE;
30
31
    protected $behavior = 0;
32
33
    /**
34
     * @var Bucket[]
35
     */
36
    protected $keys = [];
37
38
    /**
39
     * @param int $behavior
40
     */
41 1
    public function __construct(int $behavior = 0)
42
    {
43 1
        $this->behavior = $behavior;
44 1
    }
45
46
    /**
47
     * {@inheritdoc}
48
     */
49 1
    public function put($key, $value)
50
    {
51 1
        $hash = $this->getHash($key);
52
53 1
        if (isset($this->keys[$hash])) {
54
            throw new OverflowException('Value with such key already exists');
55
        }
56
57 1
        $bucket = $this->createBucket($key, $value, $hash);
58
59 1
        $this->keys[$hash] = $bucket;
60 1
    }
61
62
    /**
63
     * {@inheritdoc}
64
     */
65 1
    public function get($key)
66
    {
67 1
        $hash = $this->getHash($key);
68
69 1
        if (!isset($this->keys[$hash])) {
70
            throw new OutOfBoundsException('Value with such key not found');
71
        }
72
73 1
        return $this->keys[$hash]->value;
74
    }
75
76
    /**
77
     * {@inheritdoc}
78
     */
79
    public function has($key): bool
80
    {
81
        $hash = $this->getHash($key);
82
83
        return isset($this->keys[$hash]);
84
    }
85
86
    /**
87
     * {@inheritdoc}
88
     */
89
    public function remove($key)
90
    {
91
        $hash = $this->getHash($key);
92
93
        if (!isset($this->keys[$hash])) {
94
            throw new OutOfBoundsException('Value with such key not found');
95
        }
96
97
        $bucket = $this->keys[$hash];
98
99
        $this->doRemove($hash);
100
101
        return $bucket->value;
102
    }
103
104
    /**
105
     * {@inheritdoc}
106
     */
107
    public function count()
108
    {
109
        return count($this->keys);
110
    }
111
112
    /**
113
     * {@inheritdoc}
114
     */
115
    public function clear()
116
    {
117
        $this->keys = [];
118
    }
119
120
    /**
121
     * @param $value
122
     *
123
     * @return string
124
     */
125 1
    protected function getHash($value)
126
    {
127 1
        return spl_object_hash($value);
128
    }
129
130
    /**
131
     * @param string $hash
132
     *
133
     * @return void
134
     */
135
    protected function doRemove(string $hash)
136
    {
137
        unset($this->keys[$hash]);
138
    }
139
140
    /**
141
     * @param object $key
142
     * @param object $value
143
     * @param string $hash
144
     *
145
     * @return Bucket
146
     */
147 1
    protected function createBucket($key, $value, string $hash)
148
    {
149 1 View Code Duplication
        if ($this->behavior & self::WEAK_KEY) {
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...
150
            $key = new WeakReference($key, function () use ($hash) {
151
                $this->doRemove($hash);
152
            });
153
        }
154
155 1 View Code Duplication
        if ($this->behavior & self::WEAK_VALUE) {
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...
156
            $value = new WeakReference($value, function () use ($hash) {
157
                $this->doRemove($hash);
158
            });
159
        }
160
161
        return new Bucket($key, $value);
162
    }
163
}
164
165
166
167
168
169
170
171