Commit 139ef402 authored by Dries's avatar Dries

- Patch #22035 by mathias/mikeryan: improved performance of path aliases.

parent 229e2e4f
......@@ -13,6 +13,7 @@ Drupal x.x.x, xxxx-xx-xx (Development version)
* added support for private profile fields.
- performance:
* added 'loose caching' option for high-traffic sites.
* improved performance of path aliasing.
* added the ability to track page generation times.
Drupal 4.6.0, 2005-04-15
......
......@@ -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-12" => "update_140"
);
function update_32() {
......@@ -2489,6 +2490,18 @@ function update_139() {
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);
......
......@@ -448,7 +448,7 @@ function drupal_load($type, $name) {
// print $name. '<br />';
static $files = array();
if ($files[$type][$name]) {
if (isset($files[$type][$name])) {
return TRUE;
}
......@@ -465,32 +465,66 @@ function drupal_load($type, $name) {
}
/**
* Return an array mapping path aliases to their internal Drupal paths.
* 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.
* - source: 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_get_path_map($action = '') {
static $map = NULL;
function drupal_lookup_path($action, $path = '') {
static $map = array();
static $count = NULL;
if ($action == 'rebuild') {
$map = NULL;
if ($count === NULL) {
$count = db_result(db_query('SELECT COUNT(pid) FROM {url_alias}'));
}
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;
if ($action == 'wipe') {
$map = array();
}
elseif ($count > 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;
}
else {
$map[$path] = $path;
}
}
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 +678,7 @@ function arg($index) {
$arguments = explode('/', $_GET['q']);
}
if (array_key_exists($index, $arguments)) {
if ($arguments[$index] !== NULL) {
return $arguments[$index];
}
}
......
......@@ -80,18 +80,19 @@ function drupal_get_html_head() {
}
/**
* 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];
//drupal_get_path_alias($path);
if ($src = drupal_lookup_path('alias', $path)) {
return $src;
}
elseif (function_exists('conf_url_rewrite')) {
return conf_url_rewrite($path, 'incoming');
......@@ -1531,7 +1532,7 @@ function url($path = NULL, $query = NULL, $fragment = NULL, $absolute = FALSE) {
* 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) .'"';
......@@ -1551,7 +1552,8 @@ function drupal_attributes($attributes = array()) {
* @param $text
* The text to be enclosed with the anchor tag.
* @param $path
* The Drupal path being linked to, such as "admin/node".
* The Drupal path being linked to, such as "admin/node". Note, this must be a
* system URL as the url() function will generate the alias.
* @param $attributes
* An associative array of HTML attributes to apply to the anchor tag.
* @param $query
......@@ -1567,7 +1569,7 @@ function drupal_attributes($attributes = array()) {
* an HTML string containing a link to the given path.
*/
function l($text, $path, $attributes = array(), $query = NULL, $fragment = NULL, $absolute = FALSE, $html = FALSE) {
if (drupal_get_normal_path($path) == $_GET['q']) {
if ($path == $_GET['q']) {
if (isset($attributes['class'])) {
$attributes['class'] .= ' active';
}
......
......@@ -132,11 +132,11 @@ 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_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 @@ function path_set_alias($path = NULL, $alias = NULL, $pid = NULL) {
// 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 @@ function path_set_alias($path = NULL, $alias = NULL, $pid = NULL) {
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:
......
......@@ -132,11 +132,11 @@ 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_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 @@ function path_set_alias($path = NULL, $alias = NULL, $pid = NULL) {
// 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 @@ function path_set_alias($path = NULL, $alias = NULL, $pid = NULL) {
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:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment