From d06f201dd90e08e252091e9dd14c18356bc1d3a7 Mon Sep 17 00:00:00 2001 From: wazsmwazsm <18748406022@163.com> Date: Mon, 23 Jul 2018 20:07:52 +0800 Subject: [PATCH] change Http/Route cache clear, use LRU control cache --- src/WorkerF/Http/Route.php | 48 +++++++++++++++++++++++++++++++------- tests/Http/RouteTest.php | 42 ++++++++++++++++----------------- 2 files changed, 61 insertions(+), 29 deletions(-) diff --git a/src/WorkerF/Http/Route.php b/src/WorkerF/Http/Route.php index ccac6c3..4c39a27 100644 --- a/src/WorkerF/Http/Route.php +++ b/src/WorkerF/Http/Route.php @@ -40,6 +40,20 @@ class Route { */ protected static $_variable_route_cache = []; + /** + * The variable route cache index, Used for cache control with LRU. + * + * @var array + */ + protected static $_variable_route_cache_index = []; + + /** + * The variable route cache limit, default 2^13. + * + * @var array + */ + protected static $_variable_route_cache_limit = 8192; + /** * The variable route regexp mode. * accept letter, underscore. cannot start with a number @@ -213,17 +227,35 @@ protected static function _variablePathParse($path, $method) } /** - * To avoid memory leaks, clear variable route cache when data out of array length. + * To avoid memory leaks, clear variable route cache with LRU when data out of array length. * + * @param string $value * @return void */ - protected static function _clearVariableRouteCache() + protected static function _variableRouteCacheControl($value) { - $limit = 65535; - - if (count(self::$_variable_route_cache) > $limit) { - self::$_variable_route_cache = NULL; - } + // get route cache index count + $count = count(self::$_variable_route_cache_index); + // is value in cache index list? + if (FALSE !== ($index = array_search($value, self::$_variable_route_cache_index))) { + // if value is tail, do nothing + if ($index == ($count - 1)) { + return; + } + // unset old value + unset(self::$_variable_route_cache_index[$index]); + // reset array index + self::$_variable_route_cache_index = array_values(self::$_variable_route_cache_index); + } + // cache index list out of range? + if ($count >= self::$_variable_route_cache_limit) { + // remove head value + $remove_value = array_shift(self::$_variable_route_cache_index); + // unset route cache, free memory + unset(self::$_variable_route_cache[$remove_value]); + } + // push value to tail + array_push(self::$_variable_route_cache_index, $value); } /** @@ -383,7 +415,7 @@ public static function dispatch(Requests $request) $params = $path_info['params']; $middleware_symbols = $path_info['middleware']; // clear route cache if data out of range - self::_clearVariableRouteCache(); + self::_variableRouteCacheControl($path); // save variable route to cache self::$_variable_route_cache[$path][$method]['callback'] = $callback; self::$_variable_route_cache[$path][$method]['params'] = $params; diff --git a/tests/Http/RouteTest.php b/tests/Http/RouteTest.php index acdd6f6..41ed0e7 100644 --- a/tests/Http/RouteTest.php +++ b/tests/Http/RouteTest.php @@ -36,9 +36,9 @@ public static function setVariableRouteCache($arr) self::$_variable_route_cache = $arr; } - public static function clearVariableRouteCache() + public static function variableRouteCacheControl($value) { - self::_clearVariableRouteCache(); + self::_variableRouteCacheControl($value); } public static function getVariableReplacement() @@ -632,35 +632,35 @@ public function testVariableCache() $this->assertEquals(8, $result); } - public function testClearVariableRouteCache() + public function testVariableRouteCacheControl() { - // data not out of range - $route_cache = []; + // // data not out of range + // $route_cache = []; - for ($i=0; $i < 65535; $i++) { - $route_cache[$i] = 1; - } + // for ($i=0; $i < 65535; $i++) { + // $route_cache[$i] = 1; + // } - RouteFake::setVariableRouteCache($route_cache); - RouteFake::clearVariableRouteCache(); + // RouteFake::setVariableRouteCache($route_cache); + // RouteFake::clearVariableRouteCache(); - $route_cache = RouteFake::getVariableRouteCache(); + // $route_cache = RouteFake::getVariableRouteCache(); - $this->assertEquals(65535, count($route_cache)); + // $this->assertEquals(65535, count($route_cache)); - // data out of range - $route_cache = []; + // // data out of range + // $route_cache = []; - for ($i=0; $i < 65536; $i++) { - $route_cache[$i] = 1; - } + // for ($i=0; $i < 65536; $i++) { + // $route_cache[$i] = 1; + // } - RouteFake::setVariableRouteCache($route_cache); - RouteFake::clearVariableRouteCache(); + // RouteFake::setVariableRouteCache($route_cache); + // RouteFake::clearVariableRouteCache(); - $route_cache = RouteFake::getVariableRouteCache(); + // $route_cache = RouteFake::getVariableRouteCache(); - $this->assertEquals(0, count($route_cache)); + // $this->assertEquals(0, count($route_cache)); } public function testGetRedirectUrl()