Skip to content

Commit 60da741

Browse files
frankdejongefabpot
authored andcommitted
[Routing] Optimised dumped matcher
1 parent 4393cb2 commit 60da741

12 files changed

+745
-384
lines changed

Matcher/Dumper/DumperPrefixCollection.php

Lines changed: 0 additions & 107 deletions
This file was deleted.

Matcher/Dumper/PhpMatcherDumper.php

Lines changed: 31 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,6 @@ public function match(\$pathinfo)
134134
private function compileRoutes(RouteCollection $routes, $supportsRedirections)
135135
{
136136
$fetchedHost = false;
137-
138137
$groups = $this->groupRoutesByHostRegex($routes);
139138
$code = '';
140139

@@ -148,8 +147,8 @@ private function compileRoutes(RouteCollection $routes, $supportsRedirections)
148147
$code .= sprintf(" if (preg_match(%s, \$host, \$hostMatches)) {\n", var_export($regex, true));
149148
}
150149

151-
$tree = $this->buildPrefixTree($collection);
152-
$groupCode = $this->compilePrefixRoutes($tree, $supportsRedirections);
150+
$tree = $this->buildStaticPrefixCollection($collection);
151+
$groupCode = $this->compileStaticPrefixRoutes($tree, $supportsRedirections);
153152

154153
if (null !== $regex) {
155154
// apply extra indention at each line (except empty ones)
@@ -164,37 +163,51 @@ private function compileRoutes(RouteCollection $routes, $supportsRedirections)
164163
return $code;
165164
}
166165

166+
private function buildStaticPrefixCollection(DumperCollection $collection)
167+
{
168+
$prefixCollection = new StaticPrefixCollection();
169+
170+
foreach ($collection as $dumperRoute) {
171+
$prefix = $dumperRoute->getRoute()->compile()->getStaticPrefix();
172+
$prefixCollection->addRoute($prefix, $dumperRoute);
173+
}
174+
175+
$prefixCollection->optimizeGroups();
176+
177+
return $prefixCollection;
178+
}
179+
167180
/**
168-
* Generates PHP code recursively to match a tree of routes.
181+
* Generates PHP code to match a tree of routes.
169182
*
170-
* @param DumperPrefixCollection $collection A DumperPrefixCollection instance
183+
* @param StaticPrefixCollection $collection A StaticPrefixCollection instance
171184
* @param bool $supportsRedirections Whether redirections are supported by the base class
172-
* @param string $parentPrefix Prefix of the parent collection
185+
* @param string $ifOrElseIf Either "if" or "elseif" to influence chaining.
173186
*
174187
* @return string PHP code
175188
*/
176-
private function compilePrefixRoutes(DumperPrefixCollection $collection, $supportsRedirections, $parentPrefix = '')
189+
private function compileStaticPrefixRoutes(StaticPrefixCollection $collection, $supportsRedirections, $ifOrElseIf = 'if')
177190
{
178191
$code = '';
179192
$prefix = $collection->getPrefix();
180-
$optimizable = 1 < strlen($prefix) && 1 < count($collection->all());
181-
$optimizedPrefix = $parentPrefix;
182-
183-
if ($optimizable) {
184-
$optimizedPrefix = $prefix;
185193

186-
$code .= sprintf(" if (0 === strpos(\$pathinfo, %s)) {\n", var_export($prefix, true));
194+
if (!empty($prefix) && '/' !== $prefix) {
195+
$code .= sprintf(" %s (0 === strpos(\$pathinfo, %s)) {\n", $ifOrElseIf, var_export($prefix, true));
187196
}
188197

189-
foreach ($collection as $route) {
190-
if ($route instanceof DumperCollection) {
191-
$code .= $this->compilePrefixRoutes($route, $supportsRedirections, $optimizedPrefix);
198+
$ifOrElseIf = 'if';
199+
200+
foreach ($collection->getItems() as $route) {
201+
if ($route instanceof StaticPrefixCollection) {
202+
$code .= $this->compileStaticPrefixRoutes($route, $supportsRedirections, $ifOrElseIf);
203+
$ifOrElseIf = 'elseif';
192204
} else {
193-
$code .= $this->compileRoute($route->getRoute(), $route->getName(), $supportsRedirections, $optimizedPrefix)."\n";
205+
$code .= $this->compileRoute($route[1]->getRoute(), $route[1]->getName(), $supportsRedirections, $prefix)."\n";
206+
$ifOrElseIf = 'if';
194207
}
195208
}
196209

197-
if ($optimizable) {
210+
if (!empty($prefix) && '/' !== $prefix) {
198211
$code .= " }\n\n";
199212
// apply extra indention at each line (except empty ones)
200213
$code = preg_replace('/^.{2,}$/m', ' $0', $code);
@@ -387,7 +400,6 @@ private function compileRoute(Route $route, $name, $supportsRedirections, $paren
387400
private function groupRoutesByHostRegex(RouteCollection $routes)
388401
{
389402
$groups = new DumperCollection();
390-
391403
$currentGroup = new DumperCollection();
392404
$currentGroup->setAttribute('host_regex', null);
393405
$groups->add($currentGroup);
@@ -405,30 +417,6 @@ private function groupRoutesByHostRegex(RouteCollection $routes)
405417
return $groups;
406418
}
407419

408-
/**
409-
* Organizes the routes into a prefix tree.
410-
*
411-
* Routes order is preserved such that traversing the tree will traverse the
412-
* routes in the origin order.
413-
*
414-
* @param DumperCollection $collection A collection of routes
415-
*
416-
* @return DumperPrefixCollection
417-
*/
418-
private function buildPrefixTree(DumperCollection $collection)
419-
{
420-
$tree = new DumperPrefixCollection();
421-
$current = $tree;
422-
423-
foreach ($collection as $route) {
424-
$current = $current->addPrefixRoute($route);
425-
}
426-
427-
$tree->mergeSlashNodes();
428-
429-
return $tree;
430-
}
431-
432420
private function getExpressionLanguage()
433421
{
434422
if (null === $this->expressionLanguage) {

0 commit comments

Comments
 (0)