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 15:23:40 -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 15:23:41 -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 15:23:41 -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 15:23:42 -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 15:23:43 -0000
@@ -2643,6 +2643,8 @@ function system_cron() {
   db_query('DELETE FROM {flood} WHERE timestamp < %d', time() - 3600);
   // Cleanup the batch table
   db_query('DELETE FROM {batch} WHERE timestamp < %d', time() - 864000);
+  // Cleanup the path cache
+  cache_clear_all(NULL, 'cache_path');
 }
 
 /**
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 15:23:43 -0000
@@ -29,6 +29,7 @@ function system_schema() {
   $schema['cache_form'] = $schema['cache'];
   $schema['cache_page'] = $schema['cache'];
   $schema['cache_menu'] = $schema['cache'];
+  $schema['cache_path'] = $schema['cache'];
 
   $schema['files'] = array(
     'fields' => array(
