summaryrefslogtreecommitdiff
path: root/program/lib/Roundcube/rcube_imap.php
diff options
context:
space:
mode:
authorThomas Bruederli <thomas@roundcube.net>2014-04-08 10:58:56 +0200
committerThomas Bruederli <thomas@roundcube.net>2014-04-08 10:58:56 +0200
commit188304872066eef4b20c305f9cd6ea939dd419e0 (patch)
tree6dcf6daf1b3a970b99ddf60cc650b9c541e2e242 /program/lib/Roundcube/rcube_imap.php
parent518963d1d4456afa6f044731e2127d488f68bb16 (diff)
Optimize header fetching of multi-folder searches with natural (UID) sorting
Diffstat (limited to 'program/lib/Roundcube/rcube_imap.php')
-rw-r--r--program/lib/Roundcube/rcube_imap.php63
1 files changed, 40 insertions, 23 deletions
diff --git a/program/lib/Roundcube/rcube_imap.php b/program/lib/Roundcube/rcube_imap.php
index a708e1d92..41430db01 100644
--- a/program/lib/Roundcube/rcube_imap.php
+++ b/program/lib/Roundcube/rcube_imap.php
@@ -955,35 +955,52 @@ class rcube_imap extends rcube_storage
$sort_field = $this->sort_field;
$search_set = $this->search_set;
- $this->sort_field = null;
- $this->page_size = 1000; // fetch up to 1000 matching messages per folder
- $this->threading = false;
-
- $a_msg_headers = array();
- foreach ($search_set->sets as $resultset) {
- if (!$resultset->is_empty()) {
- $this->search_set = $resultset;
- $this->search_threads = $resultset instanceof rcube_result_thread;
- $a_msg_headers = array_merge($a_msg_headers, $this->list_search_messages($resultset->get_parameters('MAILBOX'), 1));
- }
- }
-
- // do sorting and paging
+ // prepare paging
$cnt = $search_set->count();
$from = ($page-1) * $page_size;
$to = $from + $page_size;
+ $slice_length = min($page_size, $cnt - $from);
+
+ // fetch resultset headers, sort and slice them
+ if (!empty($sort_field)) {
+ $this->sort_field = null;
+ $this->page_size = 1000; // fetch up to 1000 matching messages per folder
+ $this->threading = false;
+
+ $a_msg_headers = array();
+ foreach ($search_set->sets as $resultset) {
+ if (!$resultset->is_empty()) {
+ $this->search_set = $resultset;
+ $this->search_threads = $resultset instanceof rcube_result_thread;
+ $a_msg_headers = array_merge($a_msg_headers, $this->list_search_messages($resultset->get_parameters('MAILBOX'), 1));
+ }
+ }
- // sort headers
- if (!$this->threading && !empty($a_msg_headers)) {
- $a_msg_headers = $this->conn->sortHeaders($a_msg_headers, $sort_field, $this->sort_order);
- }
+ // sort headers
+ if (!empty($a_msg_headers)) {
+ $a_msg_headers = $this->conn->sortHeaders($a_msg_headers, $sort_field, $this->sort_order);
+ }
- // store (sorted) message index
- $search_set->set_message_index($a_msg_headers, $sort_field, $this->sort_order);
+ // store (sorted) message index
+ $search_set->set_message_index($a_msg_headers, $sort_field, $this->sort_order);
- // only return the requested part of the set
- $slice_length = min($page_size, $cnt - $from);
- $a_msg_headers = array_slice(array_values($a_msg_headers), $from, $slice_length);
+ // only return the requested part of the set
+ $a_msg_headers = array_slice(array_values($a_msg_headers), $from, $slice_length);
+ }
+ else {
+ // slice resultset first...
+ $fetch = array();
+ foreach (array_slice($search_set->get(), $from, $slice_length) as $msg_id) {
+ list($uid, $folder) = explode('-', $msg_id, 2);
+ $fetch[$folder][] = $uid;
+ }
+
+ // ... and fetch the requested set of headers
+ $a_msg_headers = array();
+ foreach ($fetch as $folder => $a_index) {
+ $a_msg_headers = array_merge($a_msg_headers, array_values($this->fetch_headers($folder, $a_index)));
+ }
+ }
if ($slice) {
$a_msg_headers = array_slice($a_msg_headers, -$slice, $slice);