Index: CHANGELOG.txt
===================================================================
RCS file: /cvs/drupal/drupal/CHANGELOG.txt,v
retrieving revision 1.80
diff -U3 -r1.80 CHANGELOG.txt
--- CHANGELOG.txt 12 May 2005 11:21:33 -0000  1.80
+++ CHANGELOG.txt 12 May 2005 18:09:29 -0000
@@ -14,6 +14,7 @@
 - performance:
     * added 'loose caching' option for high-traffic sites.
     * added the ability to track page generation times.
+    * improved performance of path aliasing.

 Drupal 4.6.0, 2005-04-15
 ------------------------
Index: database/updates.inc
===================================================================
RCS file: /cvs/drupal/drupal/database/updates.inc,v
retrieving revision 1.118
diff -U3 -r1.118 updates.inc
--- database/updates.inc  12 May 2005 11:21:34 -0000  1.118
+++ database/updates.inc  12 May 2005 18:09:30 -0000
@@ -115,7 +115,8 @@
   "2005-05-08" => "update_136",
   "2005-05-09" => "update_137",
   "2005-05-10" => "update_138",
-  "2005-05-11" => "update_139"
+  "2005-05-11" => "update_139",
+  "2005-05-11" => "update_140"
 );

 function update_32() {
@@ -2489,6 +2490,17 @@
   return $ret;
 }

+function update_140() {
+  $ret = array();
+  if ($GLOBALS['db_type'] == 'mysql') {
+    $ret[] = update_sql("ALTER TABLE {url_alias} ADD INDEX (src)");
+  }
+  elseif ($GLOBALS['db_type'] == 'pgsql') {
+    $ret[] = update_sql("CREATE INDEX url_alias_src ON {url_alias}(src)");
+  }
+  return $ret;
+}
+
 function update_sql($sql) {
   $edit = $_POST["edit"];
   $result = db_query($sql);
Index: includes/bootstrap.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/bootstrap.inc,v
retrieving revision 1.47
diff -U3 -r1.47 bootstrap.inc
--- includes/bootstrap.inc  12 May 2005 11:21:35 -0000  1.47
+++ includes/bootstrap.inc  12 May 2005 18:09:30 -0000
@@ -448,7 +448,7 @@
   // print $name. '<br />';
   static $files = array();

-  if ($files[$type][$name]) {
+  if (isset($files[$type][$name])) {
     return TRUE;
   }

@@ -465,32 +465,63 @@
 }

 /**
- * Return an array mapping path aliases to their internal Drupal paths.
- */
-function drupal_get_path_map($action = '') {
-  static $map = NULL;
-
-  if ($action == 'rebuild') {
-    $map = NULL;
-  }
-
-  if (is_null($map)) {
-    $map = array();  // Make $map non-null in case no aliases are defined.
-    $result = db_query('SELECT * FROM {url_alias}');
-    while ($data = db_fetch_object($result)) {
-      $map[$data->dst] = $data->src;
+ * Given an alias, return its Drupal system URL if one exists. Given a Drupal
+ * system URL return its alias if one exists.
+ *
+ * @param $action
+ *   One of the following values:
+ *   - wipe: Delete the alias cache.
+ *   - src: Indicates that given a Drupal system URL, return an alias if one exists.
+ *   - alias: Indicates that given an path alias, return the Drupal system URL if one exists.
+ * @param $path
+ *   The path to investigate for corresponding aliases or system URLs.
+ */
+function drupal_lookup_path($action, $path) {
+  static $map = array();
+  static $numset = NULL;
+
+  if ($numset === NULL) {
+    $numset = db_result(db_query('SELECT COUNT(pid) FROM {url_alias}'));
+  }
+
+  if ($action == 'wipe') {
+    $map = array();
+  }
+  elseif ($numset > 0 && $path != '') {
+    if ($action == 'source') {
+      if (isset($map[$path])) {
+        return $map[$path];
+      }
+      if ($alias = db_result(db_query("SELECT dst FROM {url_alias} WHERE src = '%s'", $path))) {
+        $map[$path] = $alias;
+        return $alias;
+      }
+    }
+    elseif ($action == 'alias') {
+      if ($alias = array_search($path, $map)) {
+        return $alias;
+      }
+      if (!isset($map[$path])) {
+        if ($src = db_result(db_query("SELECT src FROM {url_alias} WHERE dst = '%s'", $path))) {
+          $map[$src] = $path;
+          return $src;
+        }
+        else {
+          $map[$path] = $path;
+        }
+      }
     }
   }

-  return $map;
+  return FALSE;
 }

 /**
  * Given an internal Drupal path, return the alias set by the administrator.
  */
 function drupal_get_path_alias($path) {
-  if (($map = drupal_get_path_map()) && ($newpath = array_search($path, $map))) {
-    return $newpath;
+  if ($alias = drupal_lookup_path('source', $path)) {
+    return $alias;
   }
   elseif (function_exists('conf_url_rewrite')) {
     return conf_url_rewrite($path, 'outgoing');
@@ -644,7 +675,7 @@
     $arguments = explode('/', $_GET['q']);
   }

-  if (array_key_exists($index, $arguments)) {
+  if ($arguments[$index] !== NULL) {
     return $arguments[$index];
   }
 }
Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.440
diff -U3 -r1.440 common.inc
--- includes/common.inc 7 May 2005 01:48:06 -0000 1.440
+++ includes/common.inc 12 May 2005 18:09:30 -0000
@@ -80,18 +80,18 @@
 }

 /**
- * Regenerate the path map from the information in the database.
+ * Reset the static variable which holds the aliases mapped for this request.
  */
-function drupal_rebuild_path_map() {
-  drupal_get_path_map('rebuild');
+function drupal_clear_path_cache() {
+  drupal_lookup_path('wipe');
 }

 /**
  * Given a path alias, return the internal path it represents.
  */
 function drupal_get_normal_path($path) {
-  if (($map = drupal_get_path_map()) && isset($map[$path])) {
-    return $map[$path];
+  if ($src = drupal_lookup_path('alias', $path)) {
+    return $src;
   }
   elseif (function_exists('conf_url_rewrite')) {
     return conf_url_rewrite($path, 'incoming');
@@ -1531,7 +1531,7 @@
  *   An HTML string ready for insertion in a tag.
  */
 function drupal_attributes($attributes = array()) {
-  if ($attributes) {
+  if (is_array($attributes)) {
     $t = array();
     foreach ($attributes as $key => $value) {
       $t[] = $key .'="'. check_plain($value) .'"';
Index: modules/path.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/path.module,v
retrieving revision 1.57
diff -U3 -r1.57 path.module
--- modules/path.module 24 Apr 2005 16:34:34 -0000  1.57
+++ modules/path.module 12 May 2005 18:09:30 -0000
@@ -132,11 +132,11 @@
 function path_set_alias($path = NULL, $alias = NULL, $pid = NULL) {
   if ($path && !$alias) {
     db_query("DELETE FROM {url_alias} WHERE src = '%s'", $path);
-    drupal_rebuild_path_map();
+    drupal_clear_path_cache();
   }
   else if (!$path && $alias) {
     db_query("DELETE FROM {url_alias} WHERE dst = '%s'", $alias);
-    drupal_rebuild_path_map();
+    drupal_clear_path_cache();
   }
   else if ($path && $alias) {
     $path_count = db_result(db_query("SELECT COUNT(src) FROM {url_alias} WHERE src = '%s'", $path));
@@ -145,7 +145,7 @@
     // 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_rebuild_path_map();
+      drupal_clear_path_cache();
     }
     else if ($path_count >= 1 && $alias_count == 0) {
       if ($pid) {
@@ -154,11 +154,11 @@
       else {
         db_query("INSERT INTO {url_alias} (src, dst) VALUES ('%s', '%s')", $path, $alias);
       }
-      drupal_rebuild_path_map();
+      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_rebuild_path_map();
+      drupal_clear_path_cache();
     }
     else if ($path_count == 1 && $alias_count == 1) {
       // This will delete the path that alias was originally pointing to:
