Performance: Get event-to-mail relations once per events list, instead of doing SELECT for every event (including recurrences)

This commit is contained in:
Aleksander Machniak 2016-02-21 19:09:04 +01:00
parent 922d8de6d0
commit d96689620f
4 changed files with 26 additions and 20 deletions

View file

@ -1744,15 +1744,6 @@ class calendar extends rcube_plugin
$event['attachments'][$k]['classname'] = rcube_utils::file2class($attachment['mimetype'], $attachment['name']);
}
// convert link URIs references into structs
if (array_key_exists('links', $event)) {
foreach ((array)$event['links'] as $i => $link) {
if (strpos($link, 'imap://') === 0 && ($msgref = $this->driver->get_message_reference($link))) {
$event['links'][$i] = $msgref;
}
}
}
// check for organizer in attendees list
$organizer = null;
foreach ((array)$event['attendees'] as $i => $attendee) {

View file

@ -298,13 +298,13 @@ class kolab_calendar extends kolab_storage_folder_api
$events = array();
foreach ($this->storage->select($query) as $record) {
$event = $this->_to_driver_event($record, !$virtual);
$event = $this->_to_driver_event($record, !$virtual, false);
// remember seen categories
if ($event['categories']) {
$cat = is_array($event['categories']) ? $event['categories'][0] : $event['categories'];
$this->categories[$cat]++;
}
}
// list events in requested time window
if ($event['start'] <= $end && $event['end'] >= $start) {
@ -347,7 +347,7 @@ class kolab_calendar extends kolab_storage_folder_api
// add top-level exceptions (aka loose single occurrences)
else if (is_array($record['exceptions'])) {
foreach ($record['exceptions'] as $ex) {
$component = $this->_to_driver_event($ex);
$component = $this->_to_driver_event($ex, false, false);
if ($component['start'] <= $end && $component['end'] >= $start) {
$events[] = $component;
}
@ -381,6 +381,10 @@ class kolab_calendar extends kolab_storage_folder_api
return true;
});
// Apply event-to-mail relations
$config = kolab_storage_config::get_instance();
$config->apply_links($events, 'event');
// avoid session race conditions that will loose temporary subscriptions
$this->cal->rc->session->nowrite = true;
@ -622,7 +626,7 @@ class kolab_calendar extends kolab_storage_folder_api
if (!$exception['_instance'])
$exception['_instance'] = libcalendaring::recurrence_instance_identifier($exception);
$rec_event = $this->_to_driver_event($exception);
$rec_event = $this->_to_driver_event($exception, false, false);
$rec_event['id'] = $event['uid'] . '-' . $exception['_instance'];
$rec_event['isexception'] = 1;
@ -671,7 +675,7 @@ class kolab_calendar extends kolab_storage_folder_api
// add to output if in range
$rec_id = $event['uid'] . '-' . $instance_id;
if (($next_event['start'] <= $end && $next_event['end'] >= $start) || ($event_id && $rec_id == $event_id)) {
$rec_event = $this->_to_driver_event($next_event);
$rec_event = $this->_to_driver_event($next_event, false, false);
$rec_event['_instance'] = $instance_id;
$rec_event['_count'] = $i + 1;
@ -703,10 +707,13 @@ class kolab_calendar extends kolab_storage_folder_api
/**
* Convert from Kolab_Format to internal representation
*/
private function _to_driver_event($record, $noinst = false)
private function _to_driver_event($record, $noinst = false, $links = true)
{
$record['calendar'] = $this->id;
$record['links'] = $this->get_links($record['uid']);
if ($links) {
$record['links'] = $this->get_links($record['uid']);
}
if ($this->get_namespace() == 'other') {
$record['className'] = 'fc-event-ns-other';

View file

@ -608,10 +608,15 @@ class kolab_storage_config
// get list of object UIDs and UIRs map
foreach ($records as $i => $rec) {
$uids[] = $rec['uid'];
$ids[self::build_member_url($rec['uid'])] = $i;
// there can be many objects with the same uid (recurring events)
$ids[self::build_member_url($rec['uid'])][] = $i;
$records[$i]['links'] = array();
}
if (!empty($uids)) {
$uids = array_unique($uids);
}
// The whole story here is to not do SELECT for every object.
// We'll build one SELECT for many (limit above) objects at once
@ -645,14 +650,17 @@ class kolab_storage_config
$members = array();
foreach ((array) $relation['members'] as $member) {
if (strpos($member, 'imap://') === 0) {
$members[$member] = kolab_storage_config::get_message_reference($link, $type) ?: array('uri' => $link);
$members[$member] = kolab_storage_config::get_message_reference($member, $type) ?: array('uri' => $member);
}
}
$members = array_values($members);
// assign links to objects
foreach ((array) $relation['members'] as $member) {
if (($id = $ids[$member]) !== null) {
$records[$id]['links'] = array_unique(array_merge($records[$id]['links'], $members));
foreach ($id as $i) {
$records[$i]['links'] = array_unique(array_merge($records[$i]['links'], $members));
}
}
}
}

View file

@ -598,7 +598,7 @@ class tasklist_kolab_driver extends tasklist_driver
}
$config->apply_tags($results);
$config->apply_links($results);
$config->apply_links($results, 'task');
foreach (array_keys($results) as $idx) {
$results[$idx] = $this->_to_rcube_task($results[$idx], $results[$idx]['list_id']);