Index: includes/common.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/common.inc,v retrieving revision 1.593 diff -u -p -r1.593 common.inc --- includes/common.inc 30 Nov 2006 08:13:31 -0000 1.593 +++ includes/common.inc 30 Nov 2006 15:53:24 -0000 @@ -1259,6 +1259,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.11 diff -u -p -r1.11 path.inc --- includes/path.inc 26 Nov 2006 01:55:37 -0000 1.11 +++ includes/path.inc 30 Nov 2006 15:53:24 -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. * @@ -41,46 +42,88 @@ function drupal_init_path() { */ function drupal_lookup_path($action, $path = '') { // $map keys are Drupal paths and the values are the corresponding aliases - static $map = array(), $no_src = array(); - static $count = NULL; + static + $map, $no_src, + $map_dirty = FALSE, $no_src_dirty = FALSE, + $count = NULL, $expire = 0; + global $base_root; + // Use $count to avoid looking up paths in subsequent calls if there simply are no aliases if ($count === NULL) { $count = db_result(db_query('SELECT COUNT(pid) FROM {url_alias}')); } - if ($action == 'wipe') { - $map = array(); - $no_src = array(); - } - elseif ($count > 0 && $path != '') { - if ($action == 'alias') { - if (isset($map[$path]) || array_key_exists($path, $map)) { - return $map[$path]; - } - $alias = db_result(db_query("SELECT dst FROM {url_alias} WHERE src = '%s'", $path)); - $map[$path] = $alias; - return $alias; + if (!isset($map)) { + $cache = cache_get('map_'. $base_root . request_uri(), 'cache_path'); + if ($cache) { + $map = unserialize($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])) { - // Look for the value $path within the cached $map - if (!$src = array_search($path, $map)) { - if ($src = db_result(db_query("SELECT src FROM {url_alias} WHERE dst = '%s'", $path))) { - $map[$src] = $path; + else { + $map = array(); + } + + $cache = cache_get('no_src_'. $base_root . request_uri(), 'cache_path'); + if ($cache) { + $no_src = unserialize($cache->data); + $expire = $cache->expire; + } + else { + $no_src = array(); + } + } + switch ($action) { + case 'alias': + if ($count > 0 && $path) { + if (isset($map[$path])) { + return $map[$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] = TRUE; + if (!$alias = db_result(db_query("SELECT dst FROM {url_alias} WHERE src = '%s'", $path))) { + $alias = FALSE; } + $map[$path] = $alias; + $map_dirty = 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])) { + if (!$src = array_search($path, $map)) { + if ($src = db_result(db_query("SELECT src FROM {url_alias} WHERE dst = '%s'", $path))) { + $map[$src] = $path; + $map_dirty = 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] = TRUE; + $no_src_dirty = TRUE; + return FALSE; + } + } + return $src; + } + break; + case 'wipe': + $map = array(); + $no_src = array(); + break; + case 'cache': + if (!$expire) { + $expire = time() + (60 * 60 * 24); + } + if ($map_dirty) { + cache_set('map_'. $base_root . request_uri(), 'cache_path', serialize($map), $expire); + } + if ($no_src_dirty) { + cache_set('no_src_' . $base_root . request_uri(), 'cache_path', serialize($no_src), $expire); + } + break; } - return FALSE; } Index: modules/path/path.module =================================================================== RCS file: /cvs/drupal/drupal/modules/path/path.module,v retrieving revision 1.103 diff -u -p -r1.103 path.module --- modules/path/path.module 26 Nov 2006 02:20:01 -0000 1.103 +++ modules/path/path.module 30 Nov 2006 15:53:24 -0000 @@ -130,11 +130,9 @@ function path_admin_delete($pid = 0) { function path_set_alias($path = NULL, $alias = NULL, $pid = NULL) { if ($path && !$alias) { db_query("DELETE FROM {url_alias} WHERE src = '%s'", $path); - drupal_clear_path_cache(); } else if (!$path && $alias) { db_query("DELETE FROM {url_alias} WHERE dst = '%s'", $alias); - drupal_clear_path_cache(); } else if ($path && $alias) { $path = urldecode($path); @@ -145,7 +143,6 @@ function path_set_alias($path = NULL, $a // We have an insert: if ($path_count == 0 && $alias_count == 0) { db_query("INSERT INTO {url_alias} (src, dst) VALUES ('%s', '%s')", $path, $alias); - drupal_clear_path_cache(); } else if ($path_count >= 1 && $alias_count == 0) { if ($pid) { @@ -154,11 +151,9 @@ function path_set_alias($path = NULL, $a else { db_query("INSERT INTO {url_alias} (src, dst) VALUES ('%s', '%s')", $path, $alias); } - drupal_clear_path_cache(); } else if ($path_count == 0 && $alias_count == 1) { db_query("UPDATE {url_alias} SET src = '%s' WHERE dst = '%s'", $path, $alias); - drupal_clear_path_cache(); } else if ($path_count == 1 && $alias_count == 1) { // This will delete the path that alias was originally pointing to: @@ -167,6 +162,10 @@ function path_set_alias($path = NULL, $a path_set_alias($path, $alias); } } + + // Clear the static and the database cache. + drupal_clear_path_cache(); + cache_clear_all(NULL, 'cache_path'); } /** Index: modules/system/system.install =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.install,v retrieving revision 1.50 diff -u -p -r1.50 system.install --- modules/system/system.install 30 Nov 2006 02:19:38 -0000 1.50 +++ modules/system/system.install 30 Nov 2006 15:53:25 -0000 @@ -197,6 +197,15 @@ function system_install() { PRIMARY KEY (cid), INDEX expire (expire) ) /*!40100 DEFAULT CHARACTER SET UTF8 */ "); + db_query("CREATE TABLE {cache_path} ( + cid varchar(255) BINARY NOT NULL default '', + data longblob, + expire int NOT NULL default '0', + created int NOT NULL default '0', + headers text, + PRIMARY KEY (cid), + INDEX expire (expire) + ) /*!40100 DEFAULT CHARACTER SET UTF8 */ "); db_query("CREATE TABLE {comments} ( cid int NOT NULL auto_increment, @@ -658,10 +667,19 @@ function system_install() { headers text, PRIMARY KEY (cid) )"); + db_query("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, + PRIMARY KEY (cid) + )"); db_query("CREATE INDEX {cache}_expire_idx ON {cache} (expire)"); db_query("CREATE INDEX {cache_filter}_expire_idx ON {cache_filter} (expire)"); db_query("CREATE INDEX {cache_menu}_expire_idx ON {cache_menu} (expire)"); db_query("CREATE INDEX {cache_page}_expire_idx ON {cache_page} (expire)"); + db_query("CREATE INDEX {cache_path}_expire_idx ON {cache_page} (expire)"); db_query("CREATE TABLE {comments} ( cid serial, @@ -3363,6 +3381,45 @@ function system_update_1016() { } /** + * Add table for caching URL aliases + */ +function system_update_1017() { + $ret = array(); + + switch ($GLOBALS['db_type']) { + case 'mysqli': + case 'mysql': + // Create node_type table + $ret[] = update_sql("CREATE TABLE {cache_path} ( + cid varchar(255) BINARY NOT NULL default '', + data longblob, + expire int NOT NULL default '0', + created int NOT NULL default '0', + headers text, + PRIMARY KEY (cid), + INDEX expire (expire) + ) /*!40100 DEFAULT CHARACTER SET UTF8 */;"); + break; + + case 'pgsql': + // add new unsigned types for 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, + PRIMARY KEY (cid) + )"); + $ret[] = update_sql("CREATE INDEX {cache_path}_expire_idx ON {cache_page} (expire)"); + + break; + } + + return $ret; +} + +/** * @} End of "defgroup updates-4.7-to-5.0" */