summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG4
-rw-r--r--program/include/rcube_imap.php62
2 files changed, 42 insertions, 24 deletions
diff --git a/CHANGELOG b/CHANGELOG
index d9bb23a15..60b47dd89 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,10 @@
CHANGELOG RoundCube Webmail
---------------------------
+2008/11/15 (alec)
+----------
+- Fix big memory consumption and speed up searching on servers without SORT capability
+
2008/11/12 (alec)
----------
- Use SORT for searching on servers with SORT capability
diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php
index 1617be3ad..d867f942c 100644
--- a/program/include/rcube_imap.php
+++ b/program/include/rcube_imap.php
@@ -592,18 +592,13 @@ class rcube_imap
// fetch reuested headers from server
$a_msg_headers = array();
$deleted_count = $this->_fetch_headers($mailbox, $msgs, $a_msg_headers, $cache_key);
- if ($this->sort_order == 'DESC' && $headers_sorted) {
- //since the sort order is not used in the iil_c_sort function we have to do it here
- $a_msg_headers = array_reverse($a_msg_headers);
- }
+
// delete cached messages with a higher index than $max+1
// Changed $max to $max+1 to fix this bug : #1484295
$this->clear_message_cache($cache_key, $max + 1);
-
// kick child process to sync cache
// ...
-
}
// return empty array if no messages found
@@ -677,23 +672,39 @@ class rcube_imap
return array_values($a_msg_headers);
}
- else { // SEARCH searching result
- // not sorted, so we must fetch headers for all messages
- // TODO: to minimize big memory consumption on servers without SORT
- // capability, we should fetch only headers used for sorting, and then
- // fetch all headers needed for displaying one page of messages list.
- // Of course it has sense only for big results if count($msgs) > $this->pagesize
- $this->_fetch_headers($mailbox, join(',', $msgs), $a_msg_headers, NULL);
+ else { // SEARCH searching result, need sorting
+ if ($cnt > $this->pagesize * 2) {
+ // use memory less expensive (and quick) method for big result set
+ $a_index = $this->message_index($mailbox, $this->sort_field, $this->sort_order);
+ // get messages uids for one page...
+ $msgs = array_slice(array_keys($a_index), $start_msg, min(count($msgs)-$start_msg, $this->page_size));
+ // ...and fetch headers
+ $this->_fetch_headers($mailbox, join(',', $msgs), $a_msg_headers, NULL);
+
+ // return empty array if no messages found
+ if (!is_array($a_msg_headers) || empty($a_msg_headers))
+ return array();
+
+ $sorter = new rcube_header_sorter();
+ $sorter->set_sequence_numbers($msgs);
+ $sorter->sort_headers($a_msg_headers);
+
+ return array_values($a_msg_headers);
+ }
+ else {
+ // for small result set we can fetch all messages headers
+ $this->_fetch_headers($mailbox, join(',', $msgs), $a_msg_headers, NULL);
- // return empty array if no messages found
- if (!is_array($a_msg_headers) || empty($a_msg_headers))
- return array();
+ // return empty array if no messages found
+ if (!is_array($a_msg_headers) || empty($a_msg_headers))
+ return array();
- // if not already sorted
- $a_msg_headers = iil_SortHeaders($a_msg_headers, $this->sort_field, $this->sort_order);
+ // if not already sorted
+ $a_msg_headers = iil_SortHeaders($a_msg_headers, $this->sort_field, $this->sort_order);
- // only return the requested part of the set
- return array_slice(array_values($a_msg_headers), $start_msg, min(count($msgs)-$start_msg, $this->page_size));
+ // only return the requested part of the set
+ return array_slice(array_values($a_msg_headers), $start_msg, min(count($msgs)-$start_msg, $this->page_size));
+ }
}
}
@@ -813,11 +824,14 @@ class rcube_imap
}
else
{
- // TODO: see list_header_set (fetch only one header field needed for sorting)
- $this->_fetch_headers($mailbox, join(',', $this->search_set), $a_msg_headers, NULL);
+ $a_index = iil_C_FetchHeaderIndex($this->conn, $mailbox, join(',', $this->search_set), $this->sort_field);
+
+ if ($this->sort_order=="ASC")
+ asort($a_index);
+ else if ($this->sort_order=="DESC")
+ arsort($a_index);
- foreach (iil_SortHeaders($a_msg_headers, $this->sort_field, $this->sort_order) as $i => $msg)
- $this->cache[$key][] = $msg->id;
+ $this->cache[$key] = $a_index;
}
}