Commit 801756e7 authored by Gábor Hojtsy's avatar Gábor Hojtsy
Browse files

#111127 by chx: cache node_load(), so heavy operations loading data from...

#111127 by chx: cache node_load(), so heavy operations loading data from external sources and only invoked once (note that you should do everything dynamic in the view op, not the load op)
parent 92914245
......@@ -564,6 +564,8 @@ function book_remove_form_submit($form, &$form_state) {
// Only allowed when this is not a book (top-level page).
menu_link_delete($node->book['mlid']);
db_query('DELETE FROM {book} WHERE nid = %d', $node->nid);
// Clear the node load cache.
cache_clear_all('*', 'cache_node', TRUE);
drupal_set_message(t('The post has been removed from the book.'));
}
$form_state['redirect'] = 'node/'. $node->nid;
......@@ -609,6 +611,8 @@ function _book_update_outline(&$node) {
// Update the bid for this page and all children.
book_update_bid($node->book);
}
// Clear the node load cache.
cache_clear_all('*', 'cache_node', TRUE);
}
return TRUE;
}
......
......@@ -733,8 +733,6 @@ function comment_save($edit) {
// Update the comment in the database.
db_query("UPDATE {comments} SET status = %d, timestamp = %d, subject = '%s', comment = '%s', format = %d, uid = %d, name = '%s', mail = '%s', homepage = '%s' WHERE cid = %d", $edit['status'], $edit['timestamp'], $edit['subject'], $edit['comment'], $edit['format'], $edit['uid'], $edit['name'], $edit['mail'], $edit['homepage'], $edit['cid']);
_comment_update_node_statistics($edit['nid']);
// Allow modules to respond to the updating of a comment.
comment_invoke_comment($edit, 'update');
......@@ -799,14 +797,13 @@ function comment_save($edit) {
db_query("INSERT INTO {comments} (nid, pid, uid, subject, comment, format, hostname, timestamp, status, thread, name, mail, homepage) VALUES (%d, %d, %d, '%s', '%s', %d, '%s', %d, %d, '%s', '%s', '%s', '%s')", $edit['nid'], $edit['pid'], $edit['uid'], $edit['subject'], $edit['comment'], $edit['format'], ip_address(), $edit['timestamp'], $status, $thread, $edit['name'], $edit['mail'], $edit['homepage']);
$edit['cid'] = db_last_insert_id('comments', 'cid');
_comment_update_node_statistics($edit['nid']);
// Tell the other modules a new comment has been submitted.
comment_invoke_comment($edit, 'insert');
// Add an entry to the watchdog log.
watchdog('content', 'Comment: added %subject.', array('%subject' => $edit['subject']), WATCHDOG_NOTICE, l(t('view'), 'node/'. $edit['nid'], array('fragment' => 'comment-'. $edit['cid'])));
}
_comment_update_node_statistics($edit['nid']);
// Clear the cache so an anonymous user can see his comment being added.
cache_clear_all();
......@@ -2035,6 +2032,7 @@ function _comment_update_node_statistics($nid) {
$node = db_fetch_object(db_query("SELECT uid, created FROM {node} WHERE nid = %d", $nid));
db_query("UPDATE {node_comment_statistics} SET comment_count = 0, last_comment_timestamp = %d, last_comment_name = '', last_comment_uid = %d WHERE nid = %d", $node->created, $node->uid, $nid);
}
cache_clear_all($nid, 'cache_node');
}
/**
......
......@@ -450,6 +450,7 @@ function node_type_delete($type) {
*/
function node_type_update_nodes($old_type, $type) {
db_query("UPDATE {node} SET type = '%s' WHERE type = '%s'", $type, $old_type);
cache_clear_all('*', 'cache_node', TRUE);
return db_affected_rows();
}
......@@ -626,8 +627,17 @@ function node_load($param = array(), $revision = NULL, $reset = NULL) {
$cachable = ($revision == NULL);
$arguments = array();
if (is_numeric($param)) {
if ($cachable && isset($nodes[$param])) {
return is_object($nodes[$param]) ? drupal_clone($nodes[$param]) : $nodes[$param];
if ($cachable) {
if (!isset($nodes[$param])) {
if ($cache = cache_get($param, 'cache_node')) {
$nodes[$param] = $cache->data;
}
}
// Either the node was statically cached or we loaded from the
// cache_node table.
if (isset($nodes[$param])) {
return is_object($nodes[$param]) ? drupal_clone($nodes[$param]) : $nodes[$param];
}
}
$cond = 'n.nid = %d';
$arguments[] = $param;
......@@ -670,6 +680,11 @@ function node_load($param = array(), $revision = NULL, $reset = NULL) {
}
if ($cachable) {
$nodes[$node->nid] = is_object($node) ? drupal_clone($node) : $node;
// We can only cache when a nid is given, otherwise the conditions are
// too dynamic to be cacheable.
if (is_numeric($param)) {
cache_set($param, $nodes[$node->nid], 'cache_node');
}
}
}
......@@ -866,6 +881,8 @@ function node_save(&$node) {
// Clear the page and block caches.
cache_clear_all();
// Clear the node load cache for this node.
cache_clear_all($node->nid, 'cache_node');
}
/**
......@@ -1196,6 +1213,7 @@ function node_user($op, &$edit, &$user) {
if ($op == 'delete') {
db_query('UPDATE {node} SET uid = 0 WHERE uid = %d', $user->uid);
db_query('UPDATE {node_revisions} SET uid = 0 WHERE uid = %d', $user->uid);
cache_clear_all('*', 'cache_node', TRUE);
}
}
......
......@@ -105,6 +105,7 @@ function node_schema() {
'primary key' => array('type'),
);
$schema['cache_node'] = drupal_get_schema_unprocessed('system', 'cache');
return $schema;
}
......@@ -299,24 +299,6 @@ function poll_load($node) {
while ($choice = db_fetch_array($result)) {
$poll->choice[$choice['chorder']] = $choice;
}
// Determine whether or not this user is allowed to vote
$poll->allowvotes = FALSE;
if (user_access('vote on polls') && $poll->active) {
if ($user->uid) {
$result = db_fetch_object(db_query('SELECT chorder FROM {poll_votes} WHERE nid = %d AND uid = %d', $node->nid, $user->uid));
}
else {
$result = db_fetch_object(db_query("SELECT chorder FROM {poll_votes} WHERE nid = %d AND hostname = '%s'", $node->nid, ip_address()));
}
if (isset($result->chorder)) {
$poll->vote = $result->chorder;
}
else {
$poll->vote = -1;
$poll->allowvotes = TRUE;
}
}
return $poll;
}
......@@ -382,6 +364,25 @@ function poll_view($node, $teaser = FALSE, $page = FALSE, $block = FALSE) {
global $user;
$output = '';
// Determine whether or not this user is allowed to vote
$poll->allowvotes = FALSE;
if (user_access('vote on polls') && $poll->active) {
if ($user->uid) {
$result = db_fetch_object(db_query('SELECT chorder FROM {poll_votes} WHERE nid = %d AND uid = %d', $node->nid, $user->uid));
}
else {
$result = db_fetch_object(db_query("SELECT chorder FROM {poll_votes} WHERE nid = %d AND hostname = '%s'", $node->nid, ip_address()));
}
if (isset($result->chorder)) {
$poll->vote = $result->chorder;
}
else {
$poll->vote = -1;
$poll->allowvotes = TRUE;
}
}
// Special display for side-block
if ($block) {
// No 'read more' link
......
......@@ -3526,6 +3526,30 @@ function system_update_6027() {
return $ret;
}
/**
* Add the node load cache table.
*/
function system_update_6028() {
$ret = array();
// Create the cache_node table.
$schema['cache_node'] = array(
'fields' => array(
'cid' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
'data' => array('type' => 'blob', 'not null' => FALSE, 'size' => 'big'),
'expire' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
'created' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
'headers' => array('type' => 'text', 'not null' => FALSE),
'serialized' => array('type' => 'int', 'size' => 'small', 'not null' => TRUE, 'default' => 0)
),
'indexes' => array('expire' => array('expire')),
'primary key' => array('cid'),
);
db_create_table($ret, 'cache_node', $schema['cache_node']);
return $ret;
}
/**
* @} End of "defgroup updates-5.x-to-6.x"
* The next series of updates should start at 7000.
......
......@@ -1868,6 +1868,7 @@ function system_modules_submit($form, &$form_state) {
node_types_rebuild();
menu_rebuild();
cache_clear_all('schema', 'cache');
cache_clear_all('*', 'cache_node', TRUE);
drupal_set_message(t('The configuration options have been saved.'));
}
......
......@@ -296,6 +296,8 @@ function translation_remove_from_set($node) {
db_query('UPDATE {node} SET tnid = %d WHERE tnid = %d', $new_tnid, $node->tnid);
}
}
// TODO: it'd be better to only delete the caches of the affected nodes.
cache_clear_all('*', 'cache_node', TRUE);
}
}
......
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