Index: modules/taxonomy/taxonomy.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.module,v
retrieving revision 1.436
diff -u -p -r1.436 taxonomy.module
--- modules/taxonomy/taxonomy.module	2 Nov 2008 17:46:47 -0000	1.436
+++ modules/taxonomy/taxonomy.module	3 Nov 2008 21:35:21 -0000
@@ -624,6 +624,41 @@ function taxonomy_node_get_terms_by_voca
 }
 
 /**
+ * Find all term IDs associated with a set of nodes.
+ *
+ * @param $nodes
+ *  An array of node objects.
+ *
+ * @return
+ * An array of term and node IDs ordered by vocabulary and term weight.
+ */
+function taxonomy_get_tids_from_nodes($nodes) {
+  $vids = array();
+  foreach ($nodes as $node) {
+    $vids = $node->vid;
+  }
+
+  $query = db_select('term_node', 'r');
+  $query->addField('r', 'tid');
+  $query->addField('r', 'nid');
+  $query->addField('r', 'vid');
+  $query->join('term_data', 't', 'r.tid = t.tid');
+  $query->join('vocabulary', 'v', 't.vid = v.vid');
+  $query->condition('r.vid', $vids, 'IN');
+  $query->orderBy('v.weight');
+  $query->orderBy('t.weight');
+  $query->orderBy('t.name');
+  $query->addTag('term_access');
+  $result = $query->execute();
+  $tids = array();
+  foreach ($result as $record) {
+    $tids[$record->tid] = $record;
+  }
+
+  return $tids;
+}
+
+/**
  * Find all terms associated with the given node, ordered by vocabulary and term weight.
  */
 function taxonomy_node_get_terms($node, $key = 'tid') {
@@ -1050,6 +1085,92 @@ function taxonomy_terms_load($str_tids) 
 }
 
 /**
+ * Load multiple taxonomy terms based on certain conditions.
+ *
+ * @param $tids
+ *  An array of taxonomy term IDs.
+ * @param $conditions
+ *  An array of conditions to add to the query.
+ * @param $reset
+ *  Whether to reset the internal cache.
+ *
+ * @return
+ *  An array of term objects, indexed by tid.
+ */
+function taxonomy_term_multiple_load($tids = array(), $conditions = array(), $reset = FALSE) {
+  static $term_cache = array();
+
+  if ($reset) {
+    $term_cache = array();
+  }
+
+  $terms = array();
+
+  // Load any available terms from the cache.
+  if (!empty($tids)) {
+    foreach ($tids as $key => $tid) {
+      if (isset($term_cache[$tid])) {
+        $terms[$tid] = $term_cache[$tid];
+        unset($tids[$key]);
+      }
+    }
+  }
+
+  // If any terms loaded from the cache don't match a condition, remove them.
+  if (!empty($conditions)) {
+    foreach ($terms as $tid => $term) {
+      foreach ($conditions as $key => $value) {
+        if ($term->$key != $value) {
+          unset($terms[$tid]);
+        }
+      }
+    }
+  }
+
+  // Fetch any remaining terms from the database.
+  if (!empty($tids) || !empty($conditions)) {
+    $query = db_select('term_data', 't');
+    $term_data_fields = drupal_schema_fields_sql('term_data');
+    foreach ($term_data_fields as $field) {
+      $query->addField('t', $field, $field);
+    }
+
+    // If the $tids array is populated, add those to the query.
+    if (!empty($tids)) {
+      $query->condition('t.tid', $tids, 'IN');
+    }
+
+    // If the conditions array is populated, add those to the query.
+    if (!empty($conditions)) {
+      foreach ($conditions as $field => $value) {
+        $query->conditions('t.' . $field, $value);
+      }
+    }
+    $result = $query->execute();
+
+    foreach ($result as $record) {
+      $terms[$record->tid] = $record;
+    }
+  }
+
+  // Invoke hook_taxonomy_multiple_load() on the terms array.
+  foreach (module_implements('taxonomy_term_multiple_load') as $module) {
+    $function = $module . '_taxonomy_term_multiple_load';
+    call_user_func($function, &$terms);
+  }
+
+  // Invoke hook_taxonomy_term_load() on each individual term.
+  foreach (module_implements('taxonomy_term_load') as $module) {
+    $function = $module . '_taxonomy_term_load';
+    array_walk(&$terms, $function);
+  }
+
+  $term_cache += $terms;
+
+  return $terms;
+}
+
+/**
  * Return the term object matching a term ID.
  *
  * @param $tid
@@ -1062,12 +1183,7 @@ function taxonomy_term_load($tid, $reset
   if (!is_numeric($tid)) {
     return FALSE;
   }
-  static $terms = array();
-  if (!isset($terms[$tid]) || $reset) {
-    $terms[$tid] = taxonomy_get_term_data($tid, $reset);
-    module_invoke_all('taxonomy_term_load', $terms[$tid]);
-  }
-  return $terms[$tid];
+  return array_shift(taxonomy_term_multiple_load(array($tid), NULL, $reset));
 }
 
 /**
@@ -1210,9 +1326,17 @@ function taxonomy_render_nodes($result) 
 /**
  * Implementation of hook_nodeapi_load().
  */
-function taxonomy_nodeapi_load($node, $arg = 0) {
-  $output['taxonomy'] = taxonomy_node_get_terms($node);
-  return $output;
+function taxonomy_nodeapi_load(&$nodes) {
+  $tids = taxonomy_get_tids_from_nodes($nodes);
+  $terms = taxonomy_term_multiple_load(array_keys($tids));
+  foreach ($nodes as $node) {
+    $nodes[$node->nid]['taxonomy'] = array();
+    foreach ($tids as $tid) {
+      if ($node->vid == $tid->vid) {
+        $nodes[$node->nid]['taxonomy'][] = $terms[$tid];
+      }
+    }
+  }
 }
 
 /**
