=== modified file 'includes/common.inc'
--- includes/common.inc	2008-05-16 01:23:31 +0000
+++ includes/common.inc	2008-05-24 21:00:09 +0000
@@ -1460,6 +1460,7 @@ function l($text, $path, $options = arra
  * react to the closing of the page by calling hook_exit().
  */
 function drupal_page_footer() {
+  drupal_lookup_path('footer');
 
   if (variable_get('cache', CACHE_DISABLED) != CACHE_DISABLED) {
     page_set_cache();

=== modified file 'includes/database.mysql-common.inc'
--- includes/database.mysql-common.inc	2008-04-14 17:48:33 +0000
+++ includes/database.mysql-common.inc	2008-05-25 19:36:41 +0000
@@ -7,6 +7,11 @@
  */
 
 /**
+ * Indicates we are using MySQL.
+ */
+define('PRACTICAL_DATABASE', TRUE);
+
+/**
  * Runs a basic query in the active database.
  *
  * User-supplied arguments to the query should be passed in as separate

=== modified file 'includes/path.inc'
--- includes/path.inc	2008-04-14 17:48:33 +0000
+++ includes/path.inc	2008-05-25 19:51:50 +0000
@@ -11,6 +11,21 @@
  */
 
 /**
+ * Do not cache anything.
+ */
+define('PATH_CACHE_NONE', 0);
+
+/**
+ * Cache everything.
+ */
+define('PATH_CACHE_ALL', 1);
+
+/**
+ * Cache the aliases on page that seem unchanging.
+ */
+define('PATH_CACHE_ADAPTIVE', 2);
+
+/**
  * Initialize the $_GET['q'] variable to the proper normal path.
  */
 function drupal_init_path() {
@@ -48,43 +63,105 @@ function drupal_lookup_path($action, $pa
   // $map is an array with language keys, holding arrays of Drupal paths to alias relations
   static $map = array(), $no_src = array();
 
+  if (!module_exists('path')) {
+    return FALSE;
+  }
+
   $path_language = $path_language ? $path_language : $language->language;
+  $strategy = variable_get('path_strategy', PATH_CACHE_NONE);
 
+  if ($strategy == PATH_CACHE_ALL) {
+    return drupal_lookup_path_cached($action, $path, $path_language);
+  }
   if ($action == 'wipe') {
     $map = array();
     $no_src = array();
+    return;
   }
-  elseif (module_exists('path') && $path != '') {
-    if ($action == 'alias') {
-      if (isset($map[$path_language][$path])) {
-        return $map[$path_language][$path];
+  if ($action == 'footer' && $strategy == PATH_CACHE_ADAPTIVE) {
+    foreach ($map as $path_language => $entry) {
+      foreach ($entry as $src => $dst) {
+        // The new database layer will make this PostgreSQL and whatever
+        // compatible. Let's focus on functionality for now.
+        db_query("INSERT DELAYED INTO {path_alias_statistics_map} (page_path, language, src, dst) VALUES ('%s', '%s', '%s', '%s')", $_GET['q'], $path_language, $src, $dst);
       }
-      // 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;
     }
-    // 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 {
-          // 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;
+  }
+  elseif ($path != '') {
+    if (!isset($map[$path_language]) && $strategy == PATH_CACHE_ADAPTIVE) {
+      $cache = cache_get($_GET['q'] .':'. $path_language, 'cache_path');
+      if ($cache) {
+        $map[$path_language] = $cache->data;
+      }
+      else {
+        $map[$path_language] = array();
+        $result = db_query("SELECT src, dst FROM {path_alias_map} WHERE page_path = '%s' AND language = '%s'", $_GET['q'], $path_language);
+        while ($pair = db_fetch_array($result)) {
+          $map[$path_language][$pair['src']] = $pair['dst'];
         }
+        cache_set($_GET['q'] .':'. $path_language, $map[$path_language], 'cache_path');
       }
-      return $src;
+    }
+    switch ($action) {
+      case '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;
+      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 (!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 {
+              // 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;
+            }
+          }
+          return $src;
+        }
+        break;
     }
   }
+  return FALSE;
+}
 
+function drupal_lookup_path_cached($action, $path, $path_language) {
+  static $map = array();
+  if ($action == 'wipe') {
+    $map = array();
+    return FALSE;
+  }
+  if (empty($map)) {
+    $cache = cache_get('path', 'cache_path');
+    if ($cache) {
+      $map = $cache->data;
+    }
+    else {
+      $result = db_query("SELECT src, dst, language FROM {url_alias}");
+      while ($url_alias = db_fetch_object($result)) {
+        $map[$url_alias->language][$url_alias->src] = $url_alias->dst;
+      }
+      cache_set('path', $map, 'cache_path');
+    }
+  }
+  if ($action == 'alias' && isset($map[$path_language][$path])) {
+    return $map[$path_language][$path];
+  }
+  if ($action == 'source' && ($src = array_search($path, $map[$path_language]))) {
+    return $src;
+  }
   return FALSE;
 }
 

=== modified file 'modules/path/path.admin.inc'
--- modules/path/path.admin.inc	2008-04-14 17:48:33 +0000
+++ modules/path/path.admin.inc	2008-05-25 19:36:04 +0000
@@ -239,3 +239,20 @@ function path_admin_filter_get_keys() {
   $path = explode('/', $_GET['q'], 5);
   return count($path) == 5 ? $path[4] : '';
 }
+
+function path_admin_settings() {
+  $options = array(
+    PATH_CACHE_NONE => t('Do not cache anything'),
+    PATH_CACHE_ALL => t('Cache all aliases (not recommended for a big number of aliases)'),
+  );
+  if (defined('PRACTICAL_DATABASE')) {
+    $options[PATH_CACHE_ADAPTIVE] = t('Cache the aliases on page that seem unchanging.');
+  }
+  $form['path_strategy'] = array(
+    '#type' => 'radios',
+    '#title' => 'Caching',
+    '#options' => $options,
+    '#default_value' => variable_get('path_strategy', PATH_CACHE_NONE),
+  );
+  return system_settings_form($form);
+}
\ No newline at end of file

=== added file 'modules/path/path.install'
--- modules/path/path.install	1970-01-01 00:00:00 +0000
+++ modules/path/path.install	2008-05-25 19:55:52 +0000
@@ -0,0 +1,77 @@
+<?php
+
+function path_install() {
+  // Create tables.
+  drupal_install_schema('path');
+}
+
+function path_schema() {
+  $table = array(
+    'page_path' => array(
+      'type' => 'varchar',
+      'length' => 255,
+      'not null' => FALSE,
+      'description' => t('Internal path to page visited (relative to Drupal root.)'),
+    ),
+    'src' => array(
+      'description' => t('The Drupal path this alias is for; e.g. node/12.'),
+      'type' => 'varchar',
+      'length' => 128,
+      'not null' => TRUE,
+      'default' => '',
+    ),
+    'dst' => array(
+      'description' => t('The alias for this path; e.g. title-of-the-story.'),
+      'type' => 'varchar',
+      'length' => 128,
+      'not null' => TRUE,
+      'default' => '',
+    ),
+    'language' => array(
+      'description' => t('The language this alias is for; if blank, the alias will be used for unknown languages. Each Drupal path can have an alias for each supported language.'),
+      'type' => 'varchar',
+      'length' => 12,
+      'not null' => TRUE,
+      'default' => '',
+    ),
+  );
+  $schema['path_alias_map'] = $table;
+  $schema['path_alias_statistics_map'] = $table;
+  return $schema;
+}
+
+function path_update_7001() {
+  $table = array(
+    'page_path' => array(
+      'type' => 'varchar',
+      'length' => 255,
+      'not null' => FALSE,
+      'description' => t('Internal path to page visited (relative to Drupal root.)'),
+    ),
+    'src' => array(
+      'description' => t('The Drupal path this alias is for; e.g. node/12.'),
+      'type' => 'varchar',
+      'length' => 128,
+      'not null' => TRUE,
+      'default' => '',
+    ),
+    'dst' => array(
+      'description' => t('The alias for this path; e.g. title-of-the-story.'),
+      'type' => 'varchar',
+      'length' => 128,
+      'not null' => TRUE,
+      'default' => '',
+    ),
+    'language' => array(
+      'description' => t('The language this alias is for; if blank, the alias will be used for unknown languages. Each Drupal path can have an alias for each supported language.'),
+      'type' => 'varchar',
+      'length' => 12,
+      'not null' => TRUE,
+      'default' => '',
+    ),
+  );
+  $ret = array();
+  db_create_table($ret, 'path_alias_map', $table);
+  db_create_table($ret, 'path_alias_statistics_map', $table);
+  return $ret;
+}
\ No newline at end of file

=== modified file 'modules/path/path.module'
--- modules/path/path.module	2008-05-06 12:18:44 +0000
+++ modules/path/path.module	2008-05-25 19:51:24 +0000
@@ -63,6 +63,13 @@ function path_menu() {
     'access arguments' => array('administer url aliases'),
     'type' => MENU_LOCAL_TASK,
   );
+  $items['admin/build/path/settings'] = array(
+    'title' => 'URL alias settings',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => 'path_admin_settings',
+    'access arguments' => array('administer url aliases'),
+    'type' => MENU_LOCAL_TASK,
+  );
 
   return $items;
 }
@@ -213,3 +220,10 @@ function path_perm() {
 function path_load($pid) {
   return db_fetch_array(db_query('SELECT * FROM {url_alias} WHERE pid = %d', $pid));
 }
+
+function path_cron() {
+  db_query_temporary('SELECT page_path, language, %f * MAX(c) AS cutoff FROM (SELECT page_path, language COUNT(*) AS c FROM path_alias_statistics_map GROUP BY page_path, language, src, dst) AS x GROUP BY page_path, language', variable_get('path_cutoff', .6), 'page_cutoff');
+  db_query('DELETE FROM {path_alias_map}');
+  db_query('INSERT INTO {path_alias_map} (page_path, language, src, dst, counter) SELECT page_path, language, src, dst, COUNT(*) FROM {path_alias_statistics_map} p GROUP BY page_path, language, path, alias HAVING COUNT(*) > (SELECT cutoff FROM page_cutoff pc WHERE pc.page_path = p.page_path AND pc.language = p.language)');
+  db_query('DELETE FROM {path_alias_statistics_map}');
+}

