From ed3972eaf25f819cebfbdf9a60152a6cbaac3f83 Mon Sep 17 00:00:00 2001 From: Jan Schneider Date: Fri, 5 Aug 2016 10:24:41 +0200 Subject: [PATCH] [jan] Optimize deleting or moving a large number of messages. --- imp/docs/CHANGES | 1 + imp/lib/Maillog.php | 5 +- imp/lib/Maillog/Messages.php | 89 +++++++++++++++++++++++++++ imp/lib/Maillog/Storage/Base.php | 5 +- imp/lib/Maillog/Storage/Composite.php | 2 +- imp/lib/Maillog/Storage/History.php | 10 +-- imp/lib/Maillog/Storage/Mdnsent.php | 2 +- imp/lib/Maillog/Storage/Null.php | 2 +- imp/lib/Message.php | 8 +-- imp/package.xml | 8 ++- 10 files changed, 112 insertions(+), 20 deletions(-) create mode 100644 imp/lib/Maillog/Messages.php diff --git a/imp/docs/CHANGES b/imp/docs/CHANGES index 960d9b56586..21b7d850cce 100644 --- a/imp/docs/CHANGES +++ b/imp/docs/CHANGES @@ -2,6 +2,7 @@ v6.2.16-git ----------- +[jan] Optimize deleting or moving a large number of messages. [jan] Fix the 'special_mboxes' backend configuration (Bug #14423). [mjr] Fix display of applicatoin/pkcs-7-mime parts (Bug #14363). diff --git a/imp/lib/Maillog.php b/imp/lib/Maillog.php index 056031e523e..1ff1c9c8370 100644 --- a/imp/lib/Maillog.php +++ b/imp/lib/Maillog.php @@ -69,9 +69,10 @@ public function getLog(IMP_Maillog_Message $msg, array $filter = array()) /** * Delete log entries. * - * @param array $msgs An array of message objects to delete. + * @param IMP_Maillog_Messages|array $msgs A list of message objects to + * delete. */ - public function deleteLog(array $msgs) + public function deleteLog($msgs) { $this->storage->deleteLogs($msgs); } diff --git a/imp/lib/Maillog/Messages.php b/imp/lib/Maillog/Messages.php new file mode 100644 index 00000000000..f4948c65300 --- /dev/null +++ b/imp/lib/Maillog/Messages.php @@ -0,0 +1,89 @@ + + * @author Jan Schneider + * @category Horde + * @copyright 2014-2016 Horde LLC + * @license http://www.horde.org/licenses/gpl GPL + * @package IMP + */ +class IMP_Maillog_Messages implements IteratorAggregate +{ + /** + * The messages' mailbox. + * + * @var IMP_Mailbox + */ + protected $_mbox; + + /** + * IDs of the messages. + * + * @var Horde_Imap_Client_Ids + */ + protected $_ids; + + /** + * Message-IDs. + * + * @var array + */ + protected $_msgids; + + /** + * Constructor. + * + * @param IMP_Mailbox $mbox The messages' mailbox. + * @param Horde_Imap_Client_Ids $data IDs of the messages. + */ + public function __construct(IMP_Mailbox $mbox, Horde_Imap_Client_Ids $data) + { + $this->_mbox = $mbox; + $this->_ids = $data; + } + + /** + */ + public function getMessageIds() + { + if (isset($this->_msgids)) { + return $this->_msgids; + } + + $this->_msgids = array(); + $query = new Horde_Imap_Client_Fetch_Query(); + $query->envelope(); + $ret = $this->_mbox->imp_imap->fetch( + $this->_mbox, + $query, + array('ids' => $this->_ids) + ); + foreach ($ret as $ob) { + $this->_msgids[] = $ob->getEnvelope()->message_id; + } + Horde::debug($this->_msgids); + + return $this->_msgids; + } + + /* Iterator methods. */ + + public function getIterator() + { + return new ArrayIterator($this->getMessageIds()); + } +} diff --git a/imp/lib/Maillog/Storage/Base.php b/imp/lib/Maillog/Storage/Base.php index 6bf7ac57bd4..e967b67b096 100644 --- a/imp/lib/Maillog/Storage/Base.php +++ b/imp/lib/Maillog/Storage/Base.php @@ -49,9 +49,10 @@ abstract public function getLog( /** * Delete log entries. * - * @param array $msgs Message objects (IMP_Maillog_Message objects). + * @param IMP_Maillog_Messages|array $msgs Message objects + * (IMP_Maillog_Message objects). */ - abstract public function deleteLogs(array $msgs); + abstract public function deleteLogs($msgs); /** * Retrieve changes to the maillog since the provided timestamp. diff --git a/imp/lib/Maillog/Storage/Composite.php b/imp/lib/Maillog/Storage/Composite.php index 1a84f7c8ea7..2b96b7b21d0 100644 --- a/imp/lib/Maillog/Storage/Composite.php +++ b/imp/lib/Maillog/Storage/Composite.php @@ -69,7 +69,7 @@ public function getLog(IMP_Maillog_Message $msg, array $filter = array()) /** */ - public function deleteLogs(array $msgs) + public function deleteLogs($msgs) { foreach ($this->_drivers as $val) { $val->deleteLogs($msgs); diff --git a/imp/lib/Maillog/Storage/History.php b/imp/lib/Maillog/Storage/History.php index fc8328f6da2..c3146dc62b8 100644 --- a/imp/lib/Maillog/Storage/History.php +++ b/imp/lib/Maillog/Storage/History.php @@ -144,7 +144,7 @@ public function getLog(IMP_Maillog_Message $msg, array $filter = array()) /** */ - public function deleteLogs(array $msgs) + public function deleteLogs($msgs) { $ids = array(); foreach ($msgs as $val) { @@ -184,15 +184,17 @@ public function getChanges($ts) /** * Generate the unique log ID for an event. * - * @param mixed $msg An IMP_Maillog_Message object or, if null, return - * the parent ID. + * @param mixed $msg An IMP_Maillog_Message object, a Message-ID, or, if + * null, return the parent ID. * * @return string The unique log ID. * @throws RuntimeException */ protected function _getUniqueHistoryId($msg = null) { - $msgid = $msg ? $msg->msgid : null; + $msgid = $msg + ? (is_string($msg) ? $msg : $msg->msgid) + : null; if ($msgid === '') { throw new RuntimeException('Message-ID missing.'); } diff --git a/imp/lib/Maillog/Storage/Mdnsent.php b/imp/lib/Maillog/Storage/Mdnsent.php index 842db4f944a..731ccfc50a8 100644 --- a/imp/lib/Maillog/Storage/Mdnsent.php +++ b/imp/lib/Maillog/Storage/Mdnsent.php @@ -82,7 +82,7 @@ public function getLog(IMP_Maillog_Message $msg, array $filter = array()) /** */ - public function deleteLogs(array $msgs) + public function deleteLogs($msgs) { /* Deleting a message takes care of this. */ } diff --git a/imp/lib/Maillog/Storage/Null.php b/imp/lib/Maillog/Storage/Null.php index a9d7980b82c..ab4e98b17ad 100644 --- a/imp/lib/Maillog/Storage/Null.php +++ b/imp/lib/Maillog/Storage/Null.php @@ -40,7 +40,7 @@ public function getLog(IMP_Maillog_Message $msg, array $filter = array()) /** */ - public function deleteLogs(array $msgs) + public function deleteLogs($msgs) { } diff --git a/imp/lib/Message.php b/imp/lib/Message.php index 2df812ebec8..e1c57d66d73 100644 --- a/imp/lib/Message.php +++ b/imp/lib/Message.php @@ -251,13 +251,7 @@ public function delete(IMP_Indices $indices, array $opts = array()) * don't care about this data and 2) message IDs (used by some * maillog backends) won't be available after deletion. */ if ($maillog) { - $delete_ids = array(); - foreach ($ids_ob as $val) { - $delete_ids[] = new IMP_Maillog_Message( - new IMP_Indices($ob->mbox, $val) - ); - } - $maillog->deleteLog($delete_ids); + $maillog->deleteLog(new IMP_Maillog_Messages($ob->mbox, $ids_ob)); } /* Delete the messages. */ diff --git a/imp/package.xml b/imp/package.xml index 77faa318be9..d1a5b5ee1fe 100644 --- a/imp/package.xml +++ b/imp/package.xml @@ -22,7 +22,7 @@ chuck@horde.org no - 2016-07-01 + 2016-07-28 6.2.16 6.2.0 @@ -33,6 +33,7 @@ GPL-2.0 +* [jan] Optimize deleting or moving a large number of messages. * [jan] Fix the 'special_mboxes' backend configuration (Bug #14423). * [mjr] Fix display of applicatoin/pkcs-7-mime parts (Bug #14363). @@ -377,6 +378,7 @@ + @@ -1773,6 +1775,7 @@ + @@ -3960,9 +3963,10 @@ stable stable - 2016-07-01 + 2016-07-28 GPL-2.0 +* [jan] Optimize deleting or moving a large number of messages. * [jan] Fix the 'special_mboxes' backend configuration (Bug #14423). * [mjr] Fix display of applicatoin/pkcs-7-mime parts (Bug #14363).