summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAngie Byron2010-01-03 01:32:41 (GMT)
committerAngie Byron2010-01-03 01:32:41 (GMT)
commitc16dab454bd8ec2aa6f166b146b2226e4acd3376 (patch)
treed8523b4a7ca27fa8da463ac188b8534026c847a5
parent2c474d2a055faefd9100830d9503c6f47ee3be65 (diff)
#281405 follow-up by Arancaytar, catch, Crell, and justinrandell: Reduce memory consumption of menu_rebuild() by splitting huge query into multiple passes.
-rw-r--r--includes/menu.inc39
1 files changed, 28 insertions, 11 deletions
diff --git a/includes/menu.inc b/includes/menu.inc
index 5c35920..b04955c 100644
--- a/includes/menu.inc
+++ b/includes/menu.inc
@@ -2249,19 +2249,27 @@ function menu_rebuild() {
return FALSE;
}
- list($menu, $masks) = menu_router_build();
- _menu_router_save($menu, $masks);
- _menu_navigation_links_rebuild($menu);
- // Clear the menu, page and block caches.
- menu_cache_clear_all();
- _menu_clear_page_cache();
+ $transaction = db_transaction();
- if (defined('MAINTENANCE_MODE')) {
- variable_set('menu_rebuild_needed', TRUE);
+ try {
+ list($menu, $masks) = menu_router_build();
+ _menu_router_save($menu, $masks);
+ _menu_navigation_links_rebuild($menu);
+ // Clear the menu, page and block caches.
+ menu_cache_clear_all();
+ _menu_clear_page_cache();
+
+ if (defined('MAINTENANCE_MODE')) {
+ variable_set('menu_rebuild_needed', TRUE);
+ }
+ else {
+ variable_del('menu_rebuild_needed');
+ }
}
- else {
- variable_del('menu_rebuild_needed');
+ catch (Exception $e) {
+ $transaction->rollback('menu', $e->getMessage(), array(), WATCHDOG_ERROR);
}
+
lock_release('menu_rebuild');
return TRUE;
}
@@ -3230,6 +3238,8 @@ function _menu_router_save($menu, $masks) {
'file',
));
+ $num_records = 0;
+
foreach ($menu as $path => $item) {
// Fill in insert object values.
$insert->values(array(
@@ -3258,8 +3268,15 @@ function _menu_router_save($menu, $masks) {
'weight' => $item['weight'],
'file' => $item['include file'],
));
+
+ // Execute in batches to avoid the memory overhead of all of those records
+ // in the query object.
+ if (++$num_records == 20) {
+ $insert->execute();
+ $num_records = 0;
+ }
}
- // Execute insert object.
+ // Insert any remaining records.
$insert->execute();
// Store the masks.
variable_set('menu_masks', $masks);