diff -r 342465f7ecab modules/user/user.module
--- modules/user/user.module	Sat Oct 25 19:20:21 2008 +0200
+++ modules/user/user.module	Sun Oct 26 18:16:57 2008 +0100
@@ -137,27 +137,90 @@
 /**
  * Fetch a user object.
  *
- * @param $array
+ * @param $conditions
  *   An associative array of attributes to search for in selecting the
  *   user, such as user name or e-mail address.
  *
+ * @param $reset
+ *   Resets the internal cache for the first user object that is saved
+ *   in the cache that matches the $conditions, or when $conditions is
+ *   an empty array it resets the whole internal cache
+ *
  * @return
  *   A fully-loaded $user object upon successful user load or FALSE if user
- *   cannot be loaded.
+ *   cannot be loaded. When $conditions is empty and $reset is TRUE a 
+ *   FALSE boolean is returned.
  */
-function user_load($array = array()) {
-  // Dynamically compose a SQL query:
-  $query = array();
-  $params = array();
+function user_load($conditions = array(), $reset = NULL) {
+  static $cache;
 
-  if (is_numeric($array)) {
-    $array = array('uid' => $array);
+  // Instantiate cache or reset cache when conditions are zero.
+  if (!$cache || (empty($conditions) && $reset) ) {
+    $cache = array();
+    $cache['users'] = $cache['conditions'] = array();
+
+    if (empty($conditions)) {
+      return FALSE;
+    }
   }
-  elseif (!is_array($array)) {
+
+  // Make sure $conditions is an array at all times or jack out.
+  if (is_numeric($conditions)) {
+    $conditions = array('uid' => $conditions);
+  }
+  elseif (!is_array($conditions)) {
     return FALSE;
   }
 
-  foreach ($array as $key => $value) {
+  // Return user from cache if only uid was given.
+  if (isset($conditions['uid']) && (count($conditions)==1) && !$reset) {
+    $uid = $conditions['uid'];
+    if (isset($cache['users'][$uid])) {
+      return $cache['users'][$uid];
+    }
+  }
+
+  // Try to match the exact condition set and return from cache.
+  $uid_matches = array();
+  foreach ($conditions as $key => $value) {
+    if ($key == 'uid') continue;
+
+    if (isset($cache['conditions'][$key])) {
+      if (isset($cache['conditions'][$key][$value])) {
+
+        // Collect the matching uid's.
+        foreach ($cache['conditions'][$key][$value] as $uid) {
+          $uid_matches[] = (int)$uid;
+        }
+      }
+      else {
+        break;
+      }
+    }
+    else {
+      break;
+    }
+  }
+
+  if ($match_count = count($uid_matches)) {
+    if ( (array_sum($uid_matches) / $match_count) == $uid_matches[0]) { // Are all uid's in the array equal?
+      $uid = $uid_matches[0];
+
+      if (isset($cache['users'][$uid])) {
+        if ($reset) {
+          unset($cache['users'][$uid]);
+        }
+        else {
+          return $cache['users'][$uid];
+        }
+      }
+    }
+  }
+
+  // Dynamically compose a SQL query.
+  $query = $params = array();
+
+  foreach ($conditions as $key => $value) {
     if ($key == 'uid' || $key == 'status') {
       $query[] = "$key = %d";
       $params[] = $value;
@@ -171,10 +234,10 @@
       $params[] = $value;
     }
   }
-  $result = db_query('SELECT * FROM {users} u WHERE ' . implode(' AND ', $query), $params);
+  $result = db_fetch_object(db_query('SELECT * FROM {users} u WHERE ' . implode(' AND ', $query), $params));
 
-  if ($user = db_fetch_object($result)) {
-    $user = drupal_unpack($user);
+  if (isset($result->uid)) {
+    $user = drupal_unpack($result);
 
     $user->roles = array();
     if ($user->uid) {
@@ -187,9 +250,30 @@
     while ($role = db_fetch_object($result)) {
       $user->roles[$role->rid] = $role->name;
     }
-    user_module_invoke('load', $array, $user);
+    user_module_invoke('load', $conditions, $user);
+
+    // Save the uid of the object in the conditions cache,
+    // we group the database keys, then their values so we
+    // have a unique match at all times.
+    foreach ($conditions as $key => $value) {
+      if (!isset($cache['conditions'][$key][$value])) {
+        $cache['conditions'][$key][$value] = array();
+      }
+      if (!in_array($user->uid, $cache['conditions'][$key][$value])) {
+        $cache['conditions'][$key][$value][] = $user->uid;
+      }
+    }
+
+    // Save user object in cache.
+    $cache['users'][$user->uid] = $user;
   }
   else {
+    if (isset($conditions['uid'])) {
+      $uid = $conditions['uid'];
+      if (isset($cache['users'][$uid])) {
+        unset($cache['users'][$uid]);
+      }
+    }
     $user = FALSE;
   }
 
@@ -288,7 +372,7 @@
     }
 
     // Refresh user object.
-    $user = user_load(array('uid' => $account->uid));
+    $user = user_load($edit['uid'], TRUE);
 
     // Send emails after we have the new user object.
     if (isset($edit['status']) && $edit['status'] != $account->status) {
@@ -318,7 +402,7 @@
     }
 
     // Build the initial user object.
-    $user = user_load(array('uid' => $edit['uid']));
+    $user = user_load(array('uid' => $edit['uid']), TRUE);
 
     user_module_invoke('insert', $edit, $user, $category);
 
@@ -346,7 +430,7 @@
     }
 
     // Build the finished user object.
-    $user = user_load(array('uid' => $edit['uid']));
+    $user = user_load(array('uid' => $edit['uid']), TRUE);
   }
 
   return $user;
@@ -1594,6 +1678,7 @@
   db_query('DELETE FROM {users} WHERE uid = %d', $uid);
   db_query('DELETE FROM {users_roles} WHERE uid = %d', $uid);
   db_query('DELETE FROM {authmap} WHERE uid = %d', $uid);
+  user_load($uid, TRUE); // Update user_load()'s cache.
   $variables = array('%name' => $account->name, '%email' => '<' . $account->mail . '>');
   watchdog('user', 'Deleted user: %name %email.', $variables, WATCHDOG_NOTICE);
 }
@@ -2241,6 +2326,7 @@
     $uid = $user->uid;
   }
   db_query("UPDATE {users} SET status = 0 WHERE uid = %d", $uid);
+  user_load((int)$uid, TRUE); // Refresh user_load()'s static cache.
   drupal_session_destroy_uid($uid);
   watchdog('action', 'Blocked user %name.', array('%name' => check_plain($user->name)));
 }
diff -r 342465f7ecab modules/user/user.test
--- modules/user/user.test	Sat Oct 25 19:20:21 2008 +0200
+++ modules/user/user.test	Sun Oct 26 18:16:57 2008 +0100
@@ -1,6 +1,9 @@
 <?php
 // $Id: user.test,v 1.17 2008/10/10 07:49:49 webchick Exp $
 
+/**
+ * Test user registration
+ */
 class UserRegistrationTestCase extends DrupalWebTestCase {
   /**
    * Implementation of getInfo().
@@ -77,7 +80,7 @@
     // Make sure password changes are present in database.
     require_once DRUPAL_ROOT . '/' . variable_get('password_inc', 'includes/password.inc');
 
-    $user = user_load(array('uid' => $user->uid));
+    $user = user_load(array('uid' => $user->uid), TRUE);
     $this->assertTrue(user_check_password($new_pass, $user), t('Correct password in database.'));
 
     // Logout of user account.
@@ -102,7 +105,9 @@
   }
 }
 
-
+/**
+ * Verify that username/email validity checks behave as designed.
+ */
 class UserValidationTestCase extends DrupalWebTestCase {
   /**
    * Implementation of getInfo().
@@ -157,7 +162,9 @@
   }
 }
 
-
+/**
+ * Registers a user and deletes it.
+ */
 class UserDeleteTestCase extends DrupalWebTestCase {
   /**
    * Implementation of getInfo().
@@ -198,10 +205,13 @@
     // Confirm deletion.
     $this->drupalPost(NULL, NULL, t('Delete'));
     $this->assertRaw(t('%name has been deleted.', array('%name' => $user->name)), t('User deleted'));
-    $this->assertFalse(user_load($edit), t('User is not found in the database'));
+    $this->assertFalse(user_load($edit, TRUE), t('User is not found in the database'));
   }
 }
 
+/**
+ * Checks that the image picture code works as designed.
+ */
 class UserPictureTestCase extends DrupalWebTestCase {
   protected $user;
   protected $_directory_test;
@@ -417,7 +427,9 @@
   }
 }
 
-
+/**
+ * Verify that role permissions can be added and removed via the permissions page.
+ */
 class UserPermissionsTestCase extends DrupalWebTestCase {
   protected $admin_user;
   protected $rid;
@@ -471,6 +483,9 @@
 
 }
 
+/**
+ * Test user admininstration page functionality.
+ */
 class UserAdminTestCase extends DrupalWebTestCase {
   /**
    * Implementation of getInfo().
@@ -519,7 +534,7 @@
     $edit['operation'] = 'block';
     $edit['accounts['. $account->uid .']'] = TRUE;
     $this->drupalPost('admin/user/user', $edit, t('Update'));
-    $account = user_load(array('name' => $user_b->name));
+    $account = user_load(array('name' => $user_b->name), TRUE);
     $this->assertEqual($account->status, 0, 'User B blocked');
   }
 }
@@ -528,7 +543,6 @@
  * Test user autocompletion.
  */
 class UserAutocompleteTestCase extends DrupalWebTestCase {
-
   /**
    * Implementation of getInfo().
    */
@@ -570,3 +584,87 @@
     $this->assertRaw($this->unprivileged_user->name, t('User name found in autocompletion results.'));
   }
 }
+
+/**
+ * Test loading of users and test the static cache of user_load().
+ */
+class UserLoadingTestCase extends DrupalWebTestCase {
+  /**
+   * Implementation of getInfo().
+   */
+  function getInfo() {
+    return array(
+      'name' => t('User loading'),
+      'description' => t('Registers a user, loads it in several circumstances and multiple times. Validates that the static cache in the user_load() method works properly.'),
+      'group' => t('User')
+    );
+  }
+  
+  /**
+   * Implementation of setUp()
+   */
+  function setUp() {
+    parent::setUp();
+    $this->user = $this->drupalCreateUser();
+  }
+
+  /**
+   * Test simple user loading by uid.
+   */
+  function testUserLoadByUid() {
+    user_load(array(), TRUE); // Reset static cache.
+    $user = user_load($this->user->uid);
+    $this->assertTrue(isset($user->uid), t("User loaded by uid: user_load(!uid);", array('!uid' => $this->user->uid)) );
+
+    user_load(array(), TRUE); // Reset static cache.
+    $user = user_load(array('uid' => $this->user->uid));
+    $this->assertTrue(isset($user->uid), t("User loaded by uid: user_load(array('uid' => !uid));", array('!uid' => $this->user->uid)) );
+  }
+
+  /**
+   * Test simple user loading by name.
+   */
+  function testUserLoadByName() {
+    user_load(array(), TRUE); // Reset static cache.
+    $user = user_load(array('name' => $this->user->name));
+    $this->assertTrue(isset($user->uid), t("User loaded by name: user_load('name' => '!name');", array('!name' => $this->user->name)) );
+  }
+
+  /**
+   * Test simple user loading by mail address.
+   */
+  function testUserLoadByMail() {
+    user_load(array(), TRUE); // Reset static cache.
+    $user = user_load(array('mail' => $this->user->mail));
+    $this->assertTrue(isset($user->uid), t("User loaded by mail: user_load('mail' => '!mail');", array('!mail' => $this->user->mail)) );
+  }
+
+  /**
+   * Test simple user_load() cache by requesting the
+   * same user and changing the database in between.
+   */
+  function testUserSimpleCache() {
+    $user = user_load($this->user->uid);
+    
+    $fields = array('name' => 'wrongname');
+    db_update('users')->fields($fields)->condition('uid', $user->uid)->execute();
+    
+    $user2 = user_load($this->user->uid);
+    $this->assertEqual($user->name, $user2->name, t("The user object got statically cached."));
+  }
+
+  /**
+   * Test simple user_load() cache refreshing by requesting
+   * the same user and changing the database in between.
+   */
+  function testUserRefreshSimpleCache() {
+    $user = user_load($this->user->uid);
+
+    $fields = array('name' => 'wrongname');
+    db_update('users')->fields($fields)->condition('uid', $user->uid)->execute();
+
+    $user2 = user_load($this->user->uid, TRUE);
+    $this->assertEqual($user2->name, 'wrongname', t("Static user_load() cache got refreshed correctly."));
+  }
+
+}
\ No newline at end of file
