Skip to content

Commit cacde1e

Browse files
committed
use a single array to store definitions
1 parent 188a5df commit cacde1e

File tree

2 files changed

+50
-64
lines changed

2 files changed

+50
-64
lines changed

src/Index/Index.php

Lines changed: 49 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -16,36 +16,21 @@ class Index implements ReadableIndex, \Serializable
1616

1717
/**
1818
* An associative array that maps splitted fully qualified symbol names
19-
* to member definitions, eg :
19+
* to definitions, eg :
2020
* [
2121
* 'Psr' => [
2222
* '\Log' => [
2323
* '\LoggerInterface' => [
24-
* '->log()' => $definition,
24+
* '' => $def1, // definition for 'Psr\Log\LoggerInterface' which is non-member
25+
* '->log()' => $def2, // definition for 'Psr\Log\LoggerInterface->log()' which is a member definition
2526
* ],
2627
* ],
2728
* ],
2829
* ]
2930
*
3031
* @var array
3132
*/
32-
private $memberDefinitions = [];
33-
34-
/**
35-
* An associative array that maps splitted fully qualified symbol names
36-
* to non member definitions, eg :
37-
* [
38-
* 'Psr' => [
39-
* '\Log' => [
40-
* '\LoggerInterface' => $definition,
41-
* ],
42-
* ],
43-
* ]
44-
*
45-
* @var array
46-
*/
47-
private $nonMemberDefinitions = [];
48-
33+
private $definitions = [];
4934

5035
/**
5136
* An associative array that maps fully qualified symbol names
@@ -124,8 +109,7 @@ public function getDefinitions(): \Generator
124109
// }
125110
// }
126111

127-
yield from $this->yieldDefinitionsRecursively($this->memberDefinitions);
128-
yield from $this->yieldDefinitionsRecursively($this->nonMemberDefinitions);
112+
yield from $this->yieldDefinitionsRecursively($this->definitions);
129113
}
130114

131115
/**
@@ -141,20 +125,18 @@ public function getDefinitionsForFqn(string $fqn): \Generator
141125
// }
142126

143127
$parts = $this->splitFqn($fqn);
144-
$result = $this->getIndexValue($parts, $this->memberDefinitions);
128+
if ('' === end($parts)) {
129+
// we want to return all the definitions in the given FQN, not only
130+
// the one matching exactly the FQN.
131+
array_pop($parts);
132+
}
133+
134+
$result = $this->getIndexValue($parts, $this->definitions);
145135

146136
if ($result instanceof Definition) {
147137
yield $fqn => $result;
148138
} elseif (is_array($result)) {
149139
yield from $this->yieldDefinitionsRecursively($result, $fqn);
150-
} else {
151-
$result = $this->getIndexValue($parts, $this->nonMemberDefinitions);
152-
153-
if ($result instanceof Definition) {
154-
yield $fqn => $result;
155-
} elseif (is_array($result)) {
156-
yield from $this->yieldDefinitionsRecursively($result, $fqn);
157-
}
158140
}
159141
}
160142

@@ -181,18 +163,23 @@ public function getDefinition(string $fqn, bool $globalFallback = false)
181163
// }
182164

183165
$parts = $this->splitFqn($fqn);
184-
$result = $this->getIndexValue($parts, $this->memberDefinitions);
166+
$result = $this->getIndexValue($parts, $this->definitions);
185167

186168
if ($result instanceof Definition) {
187169
return $result;
188170
}
189171

190-
$result = $this->getIndexValue($parts, $this->nonMemberDefinitions);
172+
if ($globalFallback) {
173+
$parts = explode('\\', $fqn);
174+
$fqn = end($parts);
191175

192-
return $result instanceof Definition
193-
? $result
194-
: null
195-
;
176+
return $this->getDefinition($fqn);
177+
}
178+
179+
// return $result instanceof Definition
180+
// ? $result
181+
// : null
182+
// ;
196183
}
197184

198185
/**
@@ -212,12 +199,7 @@ public function setDefinition(string $fqn, Definition $definition)
212199
// $this->fqnDefinitions[$namespacedFqn][$fqn] = $definition;
213200

214201
$parts = $this->splitFqn($fqn);
215-
216-
if ($definition->isMember) {
217-
$this->indexDefinition(0, $parts, $this->memberDefinitions, $definition);
218-
} else {
219-
$this->indexDefinition(0, $parts, $this->nonMemberDefinitions, $definition);
220-
}
202+
$this->indexDefinition(0, $parts, $this->definitions, $definition);
221203

222204
$this->emit('definition-added');
223205
}
@@ -242,9 +224,7 @@ public function removeDefinition(string $fqn)
242224

243225
$parts = $this->splitFqn($fqn);
244226

245-
if (true !== $this->removeIndexedDefinition(0, $parts, $this->memberDefinitions)) {
246-
$this->removeIndexedDefinition(0, $parts, $this->nonMemberDefinitions);
247-
}
227+
$this->removeIndexedDefinition(0, $parts, $this->definitions);
248228

249229
unset($this->references[$fqn]);
250230
}
@@ -317,6 +297,14 @@ public function unserialize($serialized)
317297
{
318298
$data = unserialize($serialized);
319299

300+
if (isset($data['definitions'])) {
301+
foreach ($data['definitions'] as $fqn => $definition) {
302+
$this->setDefinition($fqn, $definition);
303+
}
304+
305+
unset($data['definitions']);
306+
}
307+
320308
foreach ($data as $prop => $val) {
321309
$this->$prop = $val;
322310
}
@@ -329,8 +317,7 @@ public function unserialize($serialized)
329317
public function serialize()
330318
{
331319
return serialize([
332-
'memberDefinitions' => $this->memberDefinitions,
333-
'nonMemberDefinitions' => $this->nonMemberDefinitions,
320+
'definitions' => iterator_to_array($this->getDefinitions(), true),
334321
'references' => $this->references,
335322
'complete' => $this->complete,
336323
'staticComplete' => $this->staticComplete
@@ -401,10 +388,12 @@ private function splitFqn(string $fqn): array
401388
}
402389

403390
// split the last part in 2 parts at the operator
391+
$hasOperator = false;
404392
$lastPart = end($parts);
405393
foreach (['::', '->'] as $operator) {
406394
$endParts = explode($operator, $lastPart);
407395
if (count($endParts) > 1) {
396+
$hasOperator = true;
408397
// replace the last part by its pieces
409398
array_pop($parts);
410399
$parts[] = $endParts[0];
@@ -413,6 +402,16 @@ private function splitFqn(string $fqn): array
413402
}
414403
}
415404

405+
if (!$hasOperator) {
406+
// add an empty part to store the non-member definition to avoid
407+
// definition collisions in the index array, eg
408+
// 'Psr\Log\LoggerInterface' will be stored at
409+
// ['Psr']['\Log']['\LoggerInterface'][''] to be able to also store
410+
// member definitions, ie 'Psr\Log\LoggerInterface->log()' will be
411+
// stored at ['Psr']['\Log']['\LoggerInterface']['->log()']
412+
$parts[] = '';
413+
}
414+
416415
return $parts;
417416
}
418417

@@ -439,12 +438,6 @@ private function getIndexValue(array $parts, array &$storage)
439438
return $storage[$part];
440439
}
441440

442-
if (!is_array($storage[$part]) && count($parts) > 0) {
443-
// we're looking for a member definition in the non member index,
444-
// no matches can be found.
445-
return null;
446-
}
447-
448441
return $this->getIndexValue($parts, $storage[$part]);
449442
}
450443

@@ -471,12 +464,6 @@ private function indexDefinition(int $level, array $parts, array &$storage, Defi
471464
$storage[$part] = [];
472465
}
473466

474-
if (!is_array($storage[$part])) {
475-
// it's a non member definition, we can't add it to the member
476-
// definitions index
477-
return;
478-
}
479-
480467
$this->indexDefinition($level + 1, $parts, $storage[$part], $definition);
481468
}
482469

@@ -491,7 +478,6 @@ private function indexDefinition(int $level, array $parts, array &$storage, Defi
491478
* @param array $parts The splitted FQN
492479
* @param array &$storage The current array in which to remove data
493480
* @param array &$rootStorage The root storage array
494-
* @return boolean|null True when the definition has been found and removed, null otherwise.
495481
*/
496482
private function removeIndexedDefinition(int $level, array $parts, array &$storage, &$rootStorage)
497483
{
@@ -504,16 +490,16 @@ private function removeIndexedDefinition(int $level, array $parts, array &$stora
504490
if (0 === $level) {
505491
// we're at root level, no need to check for parents
506492
// w/o children
507-
return true;
493+
return;
508494
}
509495

510496
array_pop($parts);
511497
// parse again the definition tree to see if the parent
512498
// can be removed too if it has no more children
513-
return $this->removeIndexedDefinition(0, $parts, $rootStorage, $rootStorage);
499+
$this->removeIndexedDefinition(0, $parts, $rootStorage, $rootStorage);
514500
}
515501
} else {
516-
return $this->removeIndexedDefinition($level + 1, $parts, $storage[$part], $rootStorage);
502+
$this->removeIndexedDefinition($level + 1, $parts, $storage[$part], $rootStorage);
517503
}
518504
}
519505
}

src/Indexer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class Indexer
1818
/**
1919
* @var int The prefix for every cache item
2020
*/
21-
const CACHE_VERSION = 2;
21+
const CACHE_VERSION = 1;
2222

2323
/**
2424
* @var FilesFinder

0 commit comments

Comments
 (0)