Skip to content

Commit c221c25

Browse files
committed
Add (private) Diff::finalize() to help maintain cache vadility
Signed-off-by: Jack Cherng <[email protected]>
1 parent 62a2829 commit c221c25

File tree

1 file changed

+60
-19
lines changed

1 file changed

+60
-19
lines changed

src/Diff.php

Lines changed: 60 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@
1717
*/
1818
final class Diff
1919
{
20+
/**
21+
* @var array cached properties and their default values
22+
*/
23+
private const CACHED_PROPERTIES = [
24+
'groupedCodes' => null,
25+
];
26+
2027
/**
2128
* @var array array of the options that have been applied for generating the diff
2229
*/
@@ -32,6 +39,11 @@ final class Diff
3239
*/
3340
private $new = [];
3441

42+
/**
43+
* @var bool is any of cached properties dirty?
44+
*/
45+
private $isCacheDirty = true;
46+
3547
/**
3648
* @var null|SequenceMatcher the sequence matcher
3749
*/
@@ -94,8 +106,7 @@ public function setOld(array $old): self
94106
{
95107
if ($this->old !== $old) {
96108
$this->old = $old;
97-
$this->sequenceMatcher->setSeq1($old);
98-
$this->resetCachedResults();
109+
$this->isCacheDirty = true;
99110
}
100111

101112
return $this;
@@ -112,8 +123,7 @@ public function setNew(array $new): self
112123
{
113124
if ($this->new !== $new) {
114125
$this->new = $new;
115-
$this->sequenceMatcher->setSeq2($new);
116-
$this->resetCachedResults();
126+
$this->isCacheDirty = true;
117127
}
118128

119129
return $this;
@@ -128,10 +138,12 @@ public function setNew(array $new): self
128138
*/
129139
public function setOptions(array $options): self
130140
{
131-
$this->options = $options + static::$defaultOptions;
141+
$mergedOptions = $options + static::$defaultOptions;
132142

133-
$this->sequenceMatcher->setOptions($this->options);
134-
$this->resetCachedResults();
143+
if ($this->options !== $mergedOptions) {
144+
$this->options = $mergedOptions;
145+
$this->isCacheDirty = true;
146+
}
135147

136148
return $this;
137149
}
@@ -198,22 +210,12 @@ public static function getInstance(): self
198210
*/
199211
public function getGroupedOpcodes(): array
200212
{
213+
$this->finalize();
214+
201215
return $this->groupedCodes = $this->groupedCodes ??
202216
$this->sequenceMatcher->getGroupedOpcodes($this->options['context']);
203217
}
204218

205-
/**
206-
* Reset cached results.
207-
*
208-
* @return self
209-
*/
210-
public function resetCachedResults(): self
211-
{
212-
$this->groupedCodes = null;
213-
214-
return $this;
215-
}
216-
217219
/**
218220
* Render a diff using the supplied rendering class and return it.
219221
*
@@ -223,6 +225,8 @@ public function resetCachedResults(): self
223225
*/
224226
public function render(AbstractRenderer $renderer): string
225227
{
228+
$this->finalize();
229+
226230
$renderer->setDiff($this);
227231

228232
// the "no difference" situation may happen frequently
@@ -311,6 +315,43 @@ public function getB(int $start = 0, ?int $end = null): array
311315
return $this->getNew($start, $end);
312316
}
313317

318+
/**
319+
* Claim this class is all set.
320+
*
321+
* Properties will be propagated to other classes. You must re-call
322+
* this method after any property changed before doing calculation.
323+
*
324+
* @return self
325+
*/
326+
private function finalize(): self
327+
{
328+
if ($this->isCacheDirty) {
329+
$this->resetCachedResults();
330+
331+
$this->sequenceMatcher
332+
->setOptions($this->options)
333+
->setSequences($this->old, $this->new);
334+
}
335+
336+
return $this;
337+
}
338+
339+
/**
340+
* Reset cached results.
341+
*
342+
* @return self
343+
*/
344+
private function resetCachedResults(): self
345+
{
346+
foreach (static::CACHED_PROPERTIES as $property => $value) {
347+
$this->$property = $value;
348+
}
349+
350+
$this->isCacheDirty = false;
351+
352+
return $this;
353+
}
354+
314355
/**
315356
* The work horse of getA() and getB().
316357
*

0 commit comments

Comments
 (0)