From 4d6bf807a8582046281c72b6c1e77ce6ee825514 Mon Sep 17 00:00:00 2001 From: "Michael J. Rubinsky" Date: Sun, 25 Apr 2010 10:53:03 -0400 Subject: [PATCH] No need to stat each change if we know for sure we don't have any PIM originated chagnes. If we don't have any entries in the map table for this device, no need to check each change. This makes another big improvement in syncing - this time during the initial sync. --- .../lib/Horde/ActiveSync/State/History.php | 48 ++++++++++++++++++---- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/framework/ActiveSync/lib/Horde/ActiveSync/State/History.php b/framework/ActiveSync/lib/Horde/ActiveSync/State/History.php index 480368512..2e139f9a9 100644 --- a/framework/ActiveSync/lib/Horde/ActiveSync/State/History.php +++ b/framework/ActiveSync/lib/Horde/ActiveSync/State/History.php @@ -653,16 +653,29 @@ class Horde_ActiveSync_State_History extends Horde_ActiveSync_State_Base /* No existing changes, poll the backend */ $changes = $this->_backend->getServerChanges($folderId, $this->_lastSyncTS, $this->_thisSyncTS, $cutoffdate); } + /* Unfortunately we can't use an empty synckey to detect an initial + * sync. The AS protocol doesn't start looking for changes until + * after the device/server negotiate a synckey, so we can't use an + * empty synckey to determine an initial sync. What we CAN do is + * at least query the map table to see if there any entries in it + * at all for this device before going through and stating all the + * messages. */ $this->_logger->debug('[' . $this->_devId . '] Found ' . count($changes) . ' message changes, checking for PIM initiated changes.'); - $this->_changes = array(); - foreach ($changes as $change) { - $stat = $this->_backend->statMessage($folderId, $change['id']); - $ts = $this->_getPIMChangeTS($change['id']); - if ($ts && $ts >= $stat['mod']) { - $this->_logger->debug('[' . $this->_devId . '] Ignoring PIM initiated change for ' . $change['id'] . '(PIM TS: ' . $ts . ' Stat TS: ' . $stat['mod']); - } else { - $this->_changes[] = $change; + if ($this->_havePIMChanges()) { + $this->_changes = array(); + foreach ($changes as $change) { + $stat = $this->_backend->statMessage($folderId, $change['id']); + $ts = $this->_getPIMChangeTS($change['id']); + if ($ts && $ts >= $stat['mod']) { + $this->_logger->debug('[' . $this->_devId . '] Ignoring PIM initiated change for ' . $change['id'] . '(PIM TS: ' . $ts . ' Stat TS: ' . $stat['mod']); + } else { + $this->_changes[] = $change; + } } + } else { + // No known PIM originated changes + $this->_logger->debug('[' . $this->_devId . '] No PIM changes present, returning all messages.'); + $this->_changes = $changes; } } else { $this->_logger->debug('[' . $this->_devId . '] Initializing folder diff engine'); @@ -758,6 +771,25 @@ class Horde_ActiveSync_State_History extends Horde_ActiveSync_State_Base } /** + * Check for the existence of ANY entries in the map table for this device. + * An extra database query for each sync, but the payoff is that we avoid + * having to state every message change we send to the PIM if there are no + * PIM generated changes for this sync period. + * + * @return boolean + * @throws Horde_ActiveSync_Exception + */ + protected function _havePIMChanges() + { + $sql = 'SELECT COUNT(*) FROM ' . $this->_syncMapTable . ' WHERE sync_devid = ?'; + try { + return (bool)$this->_db->selectValue($sql, array($this->_devId)); + } catch (Horde_Db_Exception $e) { + throw new Horde_ActiveSync_Exception($e); + } + } + + /** * Get the timestamp for the last successful sync for the current collection * or specified syncKey. * -- 2.11.0