Skip to content

Commit d370f04

Browse files
committed
Update the behaviour of capacities
1 parent d188956 commit d370f04

File tree

6 files changed

+91
-32
lines changed

6 files changed

+91
-32
lines changed

src/Map.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,14 @@ public function __construct($values = null)
3636
}
3737
}
3838

39+
// /**
40+
// * @return whether capacity should be increased.
41+
// */
42+
// protected function shouldIncreaseCapacity(): bool
43+
// {
44+
// return count($this) > $this->capacity;
45+
// }
46+
3947
/**
4048
* Updates all values by applying a callback function to each value.
4149
*
@@ -350,7 +358,7 @@ public function put($key, $value)
350358
$pair->value = $value;
351359

352360
} else {
353-
$this->adjustCapacity();
361+
$this->checkCapacity();
354362
$this->pairs[] = new Pair($key, $value);
355363
}
356364
}
@@ -400,7 +408,7 @@ private function delete(int $position)
400408
$value = $pair->value;
401409

402410
array_splice($this->pairs, $position, 1, null);
403-
$this->adjustCapacity();
411+
$this->checkCapacity();
404412

405413
return $value;
406414
}

src/PriorityQueue.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ public function pop()
237237

238238
// Replace the root, then sift down.
239239
$this->setRoot($leaf);
240-
$this->adjustCapacity();
240+
$this->checkCapacity();
241241

242242
return $value;
243243
}
@@ -269,7 +269,7 @@ private function siftUp(int $leaf)
269269
*/
270270
public function push($value, int $priority)
271271
{
272-
$this->adjustCapacity();
272+
$this->checkCapacity();
273273

274274
// Add new leaf, then sift up to maintain heap,
275275
$this->heap[] = new PriorityNode($value, $priority, $this->stamp++);

src/Traits/Capacity.php

Lines changed: 60 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
trait Capacity
1010
{
1111
/**
12-
* @var int internal capacity
12+
* @var integer internal capacity
1313
*/
1414
private $capacity = self::MIN_CAPACITY;
1515

@@ -37,27 +37,73 @@ public function allocate(int $capacity)
3737
}
3838

3939
/**
40-
* Called when capacity should be increased to accommodate new values.
40+
* @return the structures growth factor.
4141
*/
42-
abstract protected function increaseCapacity();
42+
protected function getGrowthFactor(): float
43+
{
44+
return 2;
45+
}
4346

4447
/**
45-
* Adjusts the structure's capacity according to its current size.
48+
* @return float to multiply by when decreasing capacity.
4649
*/
47-
private function adjustCapacity()
50+
protected function getDecayFactor(): float
4851
{
49-
$size = count($this);
52+
return 0.5;
53+
}
5054

51-
// Automatically truncate the allocated buffer when the size of the
52-
// structure drops low enough.
53-
if ($size < $this->capacity / 4) {
54-
$this->capacity = max(self::MIN_CAPACITY, $this->capacity / 2);
55-
} else {
55+
/**
56+
* @return float the ratio between size and capacity when capacity should be
57+
* decreased.
58+
*/
59+
protected function getTruncateThreshold(): float
60+
{
61+
return 0.25;
62+
}
5663

57-
// Also check if we should increase capacity when the size changes.
58-
if ($size >= $this->capacity) {
59-
$this->increaseCapacity();
64+
/**
65+
* Checks and adjusts capacity if required.
66+
*/
67+
protected function checkCapacity()
68+
{
69+
if ($this->shouldIncreaseCapacity()) {
70+
$this->increaseCapacity();
71+
} else {
72+
if ($this->shouldDecreaseCapacity()) {
73+
$this->decreaseCapacity();
6074
}
6175
}
6276
}
77+
78+
/**
79+
* Called when capacity should be increased to accommodate new values.
80+
*/
81+
protected function increaseCapacity()
82+
{
83+
$this->capacity = max($this->count(), $this->capacity * $this->getGrowthFactor());
84+
}
85+
86+
/**
87+
* Called when capacity should be decrease if it drops below a threshold.
88+
*/
89+
protected function decreaseCapacity()
90+
{
91+
$this->capacity = max(self::MIN_CAPACITY, $this->capacity * $this->getDecayFactor());
92+
}
93+
94+
/**
95+
* @return whether capacity should be increased.
96+
*/
97+
protected function shouldDecreaseCapacity(): bool
98+
{
99+
return count($this) <= $this->capacity * $this->getTruncateThreshold();
100+
}
101+
102+
/**
103+
* @return whether capacity should be increased.
104+
*/
105+
protected function shouldIncreaseCapacity(): bool
106+
{
107+
return count($this) >= $this->capacity;
108+
}
63109
}

src/Traits/GenericSequence.php

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,8 @@ public function pop()
169169
}
170170

171171
$value = array_pop($this->array);
172-
$this->adjustCapacity();
172+
$this->checkCapacity();
173+
173174
return $value;
174175
}
175176

@@ -181,7 +182,8 @@ private function pushAll($values)
181182
foreach ($values as $value) {
182183
$this->array[] = $value;
183184
}
184-
$this->adjustCapacity();
185+
186+
$this->checkCapacity();
185187
}
186188

187189
/**
@@ -210,7 +212,8 @@ public function remove(int $index)
210212
}
211213

212214
$value = array_splice($this->array, $index, 1, null)[0];
213-
$this->adjustCapacity();
215+
$this->checkCapacity();
216+
214217
return $value;
215218
}
216219

@@ -276,7 +279,8 @@ public function shift()
276279
}
277280

278281
$value = array_shift($this->array);
279-
$this->adjustCapacity();
282+
$this->checkCapacity();
283+
280284
return $value;
281285
}
282286

@@ -329,7 +333,7 @@ public function unshift(...$values)
329333
{
330334
if ($values) {
331335
$this->array = array_merge($values, $this->array);
332-
$this->adjustCapacity();
336+
$this->checkCapacity();
333337
}
334338
}
335339

src/Traits/SquaredCapacity.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,6 @@ public function allocate(int $capacity)
3838
*/
3939
protected function increaseCapacity()
4040
{
41-
$this->capacity = $this->square(max(count($this), $this->capacity + 1));
41+
$this->capacity = $this->square(max(count($this) + 1, $this->capacity * $this->getGrowthFactor()));
4242
}
4343
}

src/Vector.php

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,18 @@ final class Vector implements \IteratorAggregate, \ArrayAccess, Sequence
1515
use Traits\GenericSequence;
1616
use Traits\Capacity;
1717

18-
const MIN_CAPACITY = 10;
18+
const MIN_CAPACITY = 8;
19+
20+
protected function getGrowthFactor(): float
21+
{
22+
return 1.5;
23+
}
1924

2025
/**
21-
* Called when capacity should be increased to accommodate new values.
26+
* @return whether capacity should be increased.
2227
*/
23-
protected function increaseCapacity()
28+
protected function shouldIncreaseCapacity(): bool
2429
{
25-
$size = count($this);
26-
27-
if ($size > $this->capacity) {
28-
$this->capacity = max(intval($this->capacity * 1.5), $size);
29-
}
30+
return count($this) > $this->capacity;
3031
}
3132
}

0 commit comments

Comments
 (0)