Index: includes/common.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/common.inc,v retrieving revision 1.646 diff -u -p -r1.646 common.inc --- includes/common.inc 27 May 2007 20:31:13 -0000 1.646 +++ includes/common.inc 28 May 2007 11:09:34 -0000 @@ -1335,6 +1335,7 @@ function drupal_page_footer() { if (variable_get('cache', 0)) { page_set_cache(); } + drupal_lookup_path('cache'); module_invoke_all('exit'); } Index: includes/path.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/path.inc,v retrieving revision 1.15 diff -u -p -r1.15 path.inc --- includes/path.inc 26 Mar 2007 01:32:22 -0000 1.15 +++ includes/path.inc 28 May 2007 11:09:34 -0000 @@ -32,6 +32,7 @@ function drupal_init_path() { * - wipe: delete the alias cache. * - alias: return an alias for a given Drupal system path (if one exists). * - source: return the Drupal system URL for a path alias (if one exists). + * - cache: (internal use only) save the maps into the cache_path table. * @param $path * The path to investigate for corresponding aliases or system URLs. * @param $path_language @@ -44,52 +45,92 @@ function drupal_init_path() { * found. */ function drupal_lookup_path($action, $path = '', $path_language = '') { - global $language; + global $language, $base_root; // $map is an array with language keys, holding arrays of Drupal paths to alias relations - static $map = array(), $no_src = array(), $count; + static $map = array(), $no_src = array(), $map_dirty = array(), $no_src_dirty = array(), $count, $expire = 0; $path_language = $path_language ? $path_language : $language->language; // Use $count to avoid looking up paths in subsequent calls if there simply are no aliases if (!isset($count)) { - $count = db_result(db_query('SELECT COUNT(pid) FROM {url_alias}')); + $count = db_result(db_query('SELECT COUNT(*) FROM {url_alias}')); } - if ($action == 'wipe') { - $map = array(); - $no_src = array(); + if ($count == 0) { + return FALSE; } - elseif ($count > 0 && $path != '') { - if ($action == 'alias') { - if (isset($map[$path_language][$path])) { - return $map[$path_language][$path]; - } - // Get the most fitting result falling back with alias without language - $alias = db_result(db_query("SELECT dst FROM {url_alias} WHERE src = '%s' AND language IN('%s', '') ORDER BY language DESC", $path, $path_language)); - $map[$path_language][$path] = $alias; - return $alias; + if (!isset($map)) { + $cache = cache_get('map:'. $path_language .':'. $base_root . request_uri(), 'cache_path'); + if ($cache) { + $map[$path_language] = $cache->data; + $expire = $cache->expire; + } + else { + $map[$path_language] = array(); + } + + $cache = cache_get('no_src:'. $path_language .':'. $base_root . request_uri(), 'cache_path'); + if ($cache) { + $no_src[$path_language] = $cache->data; + $expire = $cache->expire; } - // Check $no_src for this $path in case we've already determined that there - // isn't a path that has this alias - elseif ($action == 'source' && !isset($no_src[$path_language][$path])) { - // Look for the value $path within the cached $map - $src = ''; - if (!isset($map[$path_language]) || !($src = array_search($path, $map[$path_language]))) { - // Get the most fitting result falling back with alias without language - if ($src = db_result(db_query("SELECT src FROM {url_alias} WHERE dst = '%s' AND language IN('%s', '') ORDER BY language DESC", $path, $path_language))) { - $map[$path_language][$src] = $path; + else { + $no_src[$path_language] = array(); + } + } + + switch ($action) { + case 'alias': + if ($count > 0 && $path) { + if (isset($map[$path_language][$path])) { + return $map[$path_language][$path]; } - else { - // We can't record anything into $map because we do not have a valid - // index and there is no need because we have not learned anything - // about any Drupal path. Thus cache to $no_src. - $no_src[$path_language][$path] = TRUE; + if (!$alias = db_result(db_query("SELECT dst FROM {url_alias} WHERE src = '%s' AND language IN('%s', '') ORDER BY language DESC", $path, $path_language))) { + $alias = FALSE; } + $map[$path_language][$path] = $alias; + $map_dirty[$path_language] = TRUE; + return $alias; } - return $src; - } + break; + case 'source': + // Check $no_src for this $path in case we've already determined that there + // isn't a path that has this alias + if ($count > 0 && $path && !isset($no_src[$path_language][$path])) { + if (!$src = array_search($path, $map[$path_language])) { + if ($src = db_result(db_query("SELECT src FROM {url_alias} WHERE dst = '%s' AND language IN('%s', '') ORDER BY language DESC", $path, $path_language))) { + $map[$path_language][$src] = $path; + $map_dirty[$path_language] = TRUE; + } + else { + // We can't record anything into $map because we do not have a valid + // index and there is no need because we have not learned anything + // about any Drupal path. Thus cache to $no_src. + $no_src[$path_language][$path] = TRUE; + $no_src_dirty[$path_language] = TRUE; + return FALSE; + } + } + return $src; + } + break; + case 'wipe': + $map[$path_language] = array(); + $no_src[$path_language] = array(); + break; + case 'cache': + if (!$expire) { + $expire = time() + (60 * 60 * 24); + } + if (isset($map_dirty[$path_language])) { + cache_set('map:'. $path_language .':'. $base_root . request_uri(), 'cache_path', $map[$path_language], $expire); + } + if (isset($no_src_dirty[$path_language])) { + cache_set('no_src:'. $path_language .':'. $base_root . request_uri(), 'cache_path', $no_src[$path_language], $expire); + } + break; } - + return FALSE; } Index: modules/path/path.module =================================================================== RCS file: /cvs/drupal/drupal/modules/path/path.module,v retrieving revision 1.120 diff -u -p -r1.120 path.module --- modules/path/path.module 28 May 2007 06:08:43 -0000 1.120 +++ modules/path/path.module 28 May 2007 11:09:35 -0000 @@ -129,11 +129,15 @@ function path_set_alias($path = NULL, $a // Delete based on path db_query("DELETE FROM {url_alias} WHERE src = '%s' AND language = '%s'", $path, $language); drupal_clear_path_cache(); + cache_clear_all('map_'. $language .'_', 'cache_path', TRUE); + cache_clear_all('no_src_'. $language .'_', 'cache_path', TRUE); } else if (!$path && $alias) { // Delete based on alias db_query("DELETE FROM {url_alias} WHERE dst = '%s' AND language = '%s'", $alias, $language); drupal_clear_path_cache(); + cache_clear_all('map:'. $language .':', 'cache_path', TRUE); + cache_clear_all('no_src:'. $language .':', 'cache_path', TRUE); } else if ($path && $alias) { $path = urldecode($path); @@ -168,6 +172,8 @@ function path_set_alias($path = NULL, $a } if ($alias_count == 0 || $path_count == 0) { drupal_clear_path_cache(); + cache_clear_all('map:'. $language .':', 'cache_path', TRUE); + cache_clear_all('no_src:'. $language .':', 'cache_path', TRUE); } } } Index: modules/system/system.install =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.install,v retrieving revision 1.118 diff -u -p -r1.118 system.install --- modules/system/system.install 27 May 2007 20:31:13 -0000 1.118 +++ modules/system/system.install 28 May 2007 11:09:36 -0000 @@ -3307,6 +3307,43 @@ function system_update_6021() { } /** + * Add the path cache table. + */ +function system_update_6022() { + $ret = array(); + + switch ($GLOBALS['db_type']) { + case 'pgsql': + $ret[] = update_sql("CREATE TABLE {cache_path} ( + cid varchar(255) NOT NULL default '', + data bytea, + expire int NOT NULL default '0', + created int NOT NULL default '0', + headers text, + serialized smallint NOT NULL default '0', + PRIMARY KEY (cid) + )"); + $ret[] = update_sql("CREATE INDEX {cache_path}_expire_idx ON {cache_path} (expire)"); + break; + case 'mysql': + case 'mysqli': + $ret[] = update_sql("CREATE TABLE {cache_path} ( + cid varchar(255) NOT NULL default '', + data longblob, + expire int NOT NULL default '0', + created int NOT NULL default '0', + headers text, + serialized int(1) NOT NULL default '0', + PRIMARY KEY (cid), + INDEX expire (expire) + ) /*!40100 DEFAULT CHARACTER SET UTF8 */ "); + break; + } + + return $ret; +} + +/** * @} End of "defgroup updates-5.x-to-6.x" * The next series of updates should start at 7000. */ Index: modules/system/system.module =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.module,v retrieving revision 1.484 diff -u -p -r1.484 system.module --- modules/system/system.module 28 May 2007 06:08:44 -0000 1.484 +++ modules/system/system.module 28 May 2007 11:09:37 -0000 @@ -87,6 +87,13 @@ function system_perm() { } /** + * Implementation of hook_cron(). + */ +function system_cron() { + cache_clear_all(NULL, 'cache_path'); +} + +/** * Implementation of hook_elements(). */ function system_elements() { Index: modules/system/system.schema =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.schema,v retrieving revision 1.3 diff -u -p -r1.3 system.schema --- modules/system/system.schema 27 May 2007 20:31:13 -0000 1.3 +++ modules/system/system.schema 28 May 2007 11:09:37 -0000 @@ -27,8 +27,10 @@ function system_schema() { ); $schema['cache_form'] = $schema['cache']; + $schema['cache_filter'] = $schema['cache']; $schema['cache_page'] = $schema['cache']; $schema['cache_menu'] = $schema['cache']; + $schema['cache_path'] = $schema['cache']; $schema['files'] = array( 'fields' => array(