Skip to content

Commit 0a202c8

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

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
@@ -232,6 +236,43 @@ public function render(AbstractRenderer $renderer): string
232236
: $renderer->render();
233237
}
234238

239+
/**
240+
* Claim this class is all set.
241+
*
242+
* Properties will be propagated to other classes. You must re-call
243+
* this method after any property changed before doing calculation.
244+
*
245+
* @return self
246+
*/
247+
private function finalize(): self
248+
{
249+
if ($this->isCacheDirty) {
250+
$this->resetCachedResults();
251+
252+
$this->sequenceMatcher
253+
->setOptions($this->options)
254+
->setSequences($this->old, $this->new);
255+
}
256+
257+
return $this;
258+
}
259+
260+
/**
261+
* Reset cached results.
262+
*
263+
* @return self
264+
*/
265+
private function resetCachedResults(): self
266+
{
267+
foreach (static::CACHED_PROPERTIES as $property => $value) {
268+
$this->$property = $value;
269+
}
270+
271+
$this->isCacheDirty = false;
272+
273+
return $this;
274+
}
275+
235276
/**
236277
* The work horse of getA() and getB().
237278
*

0 commit comments

Comments
 (0)