Commit 8cd0a71f authored by Ralf Becker's avatar Ralf Becker

- improve performance, by not iterating for each entry through all entries,...

- improve performance, by not iterating for each entry through all entries, but initially create an associative array of old entries indexed by their key and then iterating through the new entries once identifying new, modfied or removed entries
(this makes a hugh difference eg. for addressbooks with a couple of thousand entries more then a factor of 10)
- it drops the requirement that ids need to be in ascending order, new diff code works also if $new contains smaller ids. That happens eg. for us when a users unsubscribs from a mail folder and subscribes again
parent 1e51bf35
...@@ -110,20 +110,6 @@ class DiffState implements IChanges { ...@@ -110,20 +110,6 @@ class DiffState implements IChanges {
* DiffState specific stuff * DiffState specific stuff
*/ */
/**
* Comparing function used for sorting of the differential engine
*
* @param array $a
* @param array $b
*
* @access public
* @return boolean
*/
static public function RowCmp($a, $b) {
// TODO implement different comparing functions
return $a["id"] < $b["id"] ? 1 : -1;
}
/** /**
* Differential mechanism * Differential mechanism
* Compares the current syncstate to the sent $new * Compares the current syncstate to the sent $new
...@@ -134,74 +120,51 @@ class DiffState implements IChanges { ...@@ -134,74 +120,51 @@ class DiffState implements IChanges {
* @return array * @return array
*/ */
protected function getDiffTo($new) { protected function getDiffTo($new) {
$changes = array(); $changes = $old = array();
// Sort both arrays in the same way by ID // create associative array of old items with id as key
usort($this->syncstate, array("DiffState", "RowCmp")); foreach($this->syncstate as &$item) {
usort($new, array("DiffState", "RowCmp")); $old[$item['id']] =& $item;
}
$inew = 0;
$iold = 0;
// Get changes by comparing our list of messages with // iterate through new items to identify new or changed items
// our previous state foreach($new as &$item) {
while(1) { $id = $item['id'];
$change = array(); $change = array("id" => $id);
if($iold >= count($this->syncstate) || $inew >= count($new)) if (!isset($old[$id])) {
break; // Message in new seems to be new (add)
$change["type"] = "change";
$change['flags'] = SYNC_NEWMESSAGE;
$changes[] = $change;
} else {
$old_item =& $old[$id];
if($this->syncstate[$iold]["id"] == $new[$inew]["id"]) {
// Both messages are still available, compare flags and mod // Both messages are still available, compare flags and mod
if(isset($this->syncstate[$iold]["flags"]) && isset($new[$inew]["flags"]) && $this->syncstate[$iold]["flags"] != $new[$inew]["flags"]) { if(isset($old_item["flags"]) && isset($item["flags"]) && $old_item["flags"] != $item["flags"]) {
// Flags changed // Flags changed
$change["type"] = "flags"; $change["type"] = "flags";
$change["id"] = $new[$inew]["id"]; $change["flags"] = $item["flags"];
$change["flags"] = $new[$inew]["flags"];
$changes[] = $change; $changes[] = $change;
} }
if($this->syncstate[$iold]["mod"] != $new[$inew]["mod"]) { if ($old_item['mod'] != $item['mod']) {
$change["type"] = "change"; $change["type"] = "change";
$change["id"] = $new[$inew]["id"];
$changes[] = $change; $changes[] = $change;
} }
$inew++; // unset in $old, so $old contains only the deleted items
$iold++; unset($old[$id]);
} else {
if($this->syncstate[$iold]["id"] > $new[$inew]["id"]) {
// Message in state seems to have disappeared (delete)
$change["type"] = "delete";
$change["id"] = $this->syncstate[$iold]["id"];
$changes[] = $change;
$iold++;
} else {
// Message in new seems to be new (add)
$change["type"] = "change";
$change["flags"] = SYNC_NEWMESSAGE;
$change["id"] = $new[$inew]["id"];
$changes[] = $change;
$inew++;
}
} }
} }
while($iold < count($this->syncstate)) { // now $old contains only deleted items
// All data left in 'syncstate' have been deleted foreach($old as $id => &$item) {
$change["type"] = "delete"; // Message in state seems to have disappeared (delete)
$change["id"] = $this->syncstate[$iold]["id"]; $changes[] = array(
$changes[] = $change; "type" => "delete",
$iold++; "id" => $id,
} );
while($inew < count($new)) {
// All data left in new have been added
$change["type"] = "change";
$change["flags"] = SYNC_NEWMESSAGE;
$change["id"] = $new[$inew]["id"];
$changes[] = $change;
$inew++;
} }
return $changes; return $changes;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment