Hi,
I've been reading the IMAP specification to find ways to improve current rcube cache algorithms. The following is from the IMAPv4 specs:
2.3.1.2. Message Sequence Number Message Attribute
A relative position from 1 to the number of messages in the mailbox. This position MUST be ordered by ascending unique identifier. As each new message is added, it is assigned a message sequence number that is 1 higher than the number of messages in the mailbox before that new message was added.
Currently rcube stores the whole header list for each mailbox in the DB. If the current message count is bigger than the message count of the cache then it fetches the whole header list again and stores it in the cache on DB.
I think this could be improved by redesigning the caching algorithm, since each new message in a mailbox is given a sequence number higher than the other ones, we can just fetch the new messages. The following code should clarify the idea:
$mbox_count = messagecount($mbox); $cache_count = count($cache); if ($mbox_count > $cache_count) { $newMessages = iil_C_FetchHeaders( $conn, $mbox, "$cache_count:$mbox_count" ); $cache = array_merge( $cache, $newMessages ); }
Unfortunatly the specs also say:
Message sequence numbers can be reassigned during the session. For example, when a message is permanently removed (expunged) from the mailbox, the message sequence number for all subsequent messages is decremented. The number of messages in the mailbox is also decremented. Similarly, a new message can be assigned a message sequence number that was once held by some other message prior to an expunge.
We can solve this however since we have the UID of each header in the cache. Instead of fetching the (mbox_count - cache_count) headers, we can fetch (mbox_count-cache_count)+1, with this we should get as the first header the last one in the cache. We then compare its UID, so if we have in the cache the last header with id=269 and uid=468 but in the new list it has the id=269 but the uid=493 it means that there have been deleted messages in that folder and that we must revalidate the whole list. This could also be optimized but it'll require a quite complex algorithm which I guess is not worth it for most cases. The following pseudo-code should show the idea good enough:
$mbox_count = messagecount($mbox); $cache_count = count($cache); if ($mbox_count > $cache_count) { $newMessages = iil_C_FetchHeaders( $conn, $mbox, ($cache_count-1).":$mbox_count" ); if ($newMessages[0]->uid != end($cache)->uid) { //revalidate the cache $cache = iil_C_FetchHeaders( $conn, $mbox, "0:".($cache_count-1)); } $cache = array_merge( $cache, $newMessages ); }
The code I think is simple enough although I would like to discuss this before trying its implementation, I'm worried about the specs support in different servers.
ciao, ivan