Lines 92.30% 12 / 13
Functions and Methods 85.71% 6 / 7
Classes and Traits 0.00% 0 / 1
Name Lines Functions and Methods CRAP Classes and Traits
StateCache 92.30% 12 / 13 85.71% 6 / 7 10.05 0.00% 0 / 1
 replaceAll 100.00% 4 / 4 100.00% 1 / 1 2
 applyChange 75.00% 3 / 4 0.00% 0 / 1 2.06
 find 100.00% 1 / 1 100.00% 1 / 1 1
 listEntityIds 100.00% 1 / 1 100.00% 1 / 1 1
 getAllStates 100.00% 1 / 1 100.00% 1 / 1 1
 filterBySelector 100.00% 1 / 1 100.00% 1 / 1 2
 count 100.00% 1 / 1 100.00% 1 / 1 1
1<?php
2
3declare(strict_types=1);
4
5namespace Stewart\Runtime\State;
6
7use Stewart\Contracts\Entity\Collection\EntityIdCollection;
8use Stewart\Contracts\Entity\EntityId;
9use Stewart\Contracts\Selector\Selector;
10use Stewart\Contracts\State\Collection\EntityStateCollection;
11use Stewart\Contracts\State\EntityState;
12use Stewart\Contracts\State\StateChange;
13
14final class StateCache
15{
16    /** @var array<string, EntityState> */
17    private array $statesById = [];
18
19    // Built lazily: state changes are far more frequent than full-cache reads.
20    private ?EntityStateCollection $collection = null;
21
22    /** @param iterable<EntityState> $states */
23    public function replaceAll(iterable $states): void
24    {
25        $this->statesById = [];
26
27        foreach ($states as $state) {
28            $this->statesById[$state->entityId->value] = $state;
29        }
30
31        $this->collection = null;
32    }
33
34    public function applyChange(StateChange $change): void
35    {
36        if ($change->to === null) {
37            unset($this->statesById[$change->entityId->value]);
38        } else {
39            $this->statesById[$change->entityId->value] = $change->to;
40        }
41
42        $this->collection = null;
43    }
44
45    public function find(EntityId $entityId): ?EntityState
46    {
47        return $this->statesById[$entityId->value] ?? null;
48    }
49
50    public function listEntityIds(): EntityIdCollection
51    {
52        return $this->getAllStates()->listEntityIds();
53    }
54
55    public function getAllStates(): EntityStateCollection
56    {
57        return $this->collection ??= EntityStateCollection::keyedByEntityId($this->statesById);
58    }
59
60    public function filterBySelector(?Selector $selector): EntityStateCollection
61    {
62        return $selector === null ? $this->getAllStates() : $this->getAllStates()->filterBySelector($selector);
63    }
64
65    public function count(): int
66    {
67        return \count($this->statesById);
68    }
69}