diff --git a/ActiveSync/SOGoActiveSyncDispatcher+Sync.m b/ActiveSync/SOGoActiveSyncDispatcher+Sync.m index fd11cf0b5..3ec9614d2 100644 --- a/ActiveSync/SOGoActiveSyncDispatcher+Sync.m +++ b/ActiveSync/SOGoActiveSyncDispatcher+Sync.m @@ -133,6 +133,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [[o properties] removeObjectForKey: @"MoreAvailable"]; [[o properties] removeObjectForKey: @"BodyPreferenceType"]; [[o properties] removeObjectForKey: @"SuccessfulMoveItemsOps"]; + [[o properties] removeObjectForKey: @"InitialLoadSequence"]; [[o properties] addEntriesFromDictionary: values]; [o save]; @@ -673,7 +674,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. NSDictionary *component; NSArray *allComponents; - BOOL updated; + BOOL updated, initialLoadInProgress; int deleted, return_count; if (theFolderType == ActiveSyncContactFolder) @@ -683,7 +684,20 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. else component_name = @"vtodo"; - allComponents = [theCollection syncTokenFieldsWithProperties: nil matchingSyncToken: theSyncKey fromDate: theFilterType]; + initialLoadInProgress = NO; + + if ([theSyncKey isEqualToString: @"-1"]) + [folderMetadata setObject: davCollectionTagToStore forKey: @"InitialLoadSequence"]; + + if ([folderMetadata objectForKey: @"InitialLoadSequence"]) + { + if ([theSyncKey intValue] < [[folderMetadata objectForKey: @"InitialLoadSequence"] intValue]) + initialLoadInProgress = YES; + else + [folderMetadata removeObjectForKey: @"InitialLoadSequence"]; + } + + allComponents = [theCollection syncTokenFieldsWithProperties: nil matchingSyncToken: theSyncKey fromDate: theFilterType initialLoad: initialLoadInProgress]; allComponents = [allComponents sortedArrayUsingDescriptors: [NSArray arrayWithObjects: [[NSSortDescriptor alloc] initWithKey: @"c_lastmodified" ascending:YES], nil]]; @@ -847,12 +861,35 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. NSMutableArray *allCacheObjects, *sortedBySequence; SOGoMailObject *mailObject; - NSArray *allMessages; + NSArray *allMessages, *a; - int j, k, return_count; - BOOL found_in_cache; + int j, k, return_count, highestmodseq; + BOOL found_in_cache, initialLoadInProgress; - allMessages = [theCollection syncTokenFieldsWithProperties: nil matchingSyncToken: theSyncKey fromDate: theFilterType]; + initialLoadInProgress = NO; + + if ([theSyncKey isEqualToString: @"-1"]) + { + highestmodseq = 0; + + a = [[theCollection davCollectionTag] componentsSeparatedByString: @"-"]; + [folderMetadata setObject: [a objectAtIndex: 1] forKey: @"InitialLoadSequence"]; + } + else + { + a = [theSyncKey componentsSeparatedByString: @"-"]; + highestmodseq = [[a objectAtIndex: 1] intValue]; + } + + if ([folderMetadata objectForKey: @"InitialLoadSequence"]) + { + if (highestmodseq < [[folderMetadata objectForKey: @"InitialLoadSequence"] intValue]) + initialLoadInProgress = YES; + else + [folderMetadata removeObjectForKey: @"InitialLoadSequence"]; + } + + allMessages = [theCollection syncTokenFieldsWithProperties: nil matchingSyncToken: theSyncKey fromDate: theFilterType initialLoad: initialLoadInProgress]; max = [allMessages count]; allCacheObjects = [NSMutableArray array]; @@ -911,7 +948,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. NSString *lastSequence; more_available = YES; - lastSequence = ([[aCacheObject sequence] isEqual: [NSNull null]] ? @"1" : [aCacheObject sequence]); + lastSequence = ([[aCacheObject sequence] isEqual: [NSNull null]] ? [NSString stringWithFormat:@"%d", highestmodseq] : [aCacheObject sequence]); *theLastServerKey = [[NSString alloc] initWithFormat: @"%@-%@", [aCacheObject uid], lastSequence]; //NSLog(@"Reached windowSize - lastUID will be: %@", *theLastServerKey); DESTROY(pool); diff --git a/ActiveSync/SOGoActiveSyncDispatcher.m b/ActiveSync/SOGoActiveSyncDispatcher.m index ddfcb57fe..df52b3c68 100644 --- a/ActiveSync/SOGoActiveSyncDispatcher.m +++ b/ActiveSync/SOGoActiveSyncDispatcher.m @@ -944,6 +944,7 @@ static BOOL debugOn = NO; [[o properties] removeObjectForKey: @"MoreAvailable"]; [[o properties] removeObjectForKey: @"BodyPreferenceType"]; [[o properties] removeObjectForKey: @"SuccessfulMoveItemsOps"]; + [[o properties] removeObjectForKey: @"InitialLoadSequence"]; [o save]; command_count++; @@ -1029,6 +1030,7 @@ static BOOL debugOn = NO; [[o properties] removeObjectForKey: @"MoreAvailable"]; [[o properties] removeObjectForKey: @"BodyPreferenceType"]; [[o properties] removeObjectForKey: @"SuccessfulMoveItemsOps"]; + [[o properties] removeObjectForKey: @"InitialLoadSequence"]; } [o save]; @@ -1052,6 +1054,7 @@ static BOOL debugOn = NO; [[o properties] removeObjectForKey: @"MoreAvailable"]; [[o properties] removeObjectForKey: @"BodyPreferenceType"]; [[o properties] removeObjectForKey: @"SuccessfulMoveItemsOps"]; + [[o properties] removeObjectForKey: @"InitialLoadSequence"]; } [o save]; @@ -1210,7 +1213,7 @@ static BOOL debugOn = NO; filter = [NSCalendarDate dateFromFilterType: [[(id)[[allCollections objectAtIndex: j] getElementsByTagName: @"FilterType"] lastObject] textValue]]; syncKey = [[(id)[[allCollections objectAtIndex: j] getElementsByTagName: @"SyncKey"] lastObject] textValue]; - allMessages = [currentCollection syncTokenFieldsWithProperties: nil matchingSyncToken: syncKey fromDate: filter]; + allMessages = [currentCollection syncTokenFieldsWithProperties: nil matchingSyncToken: syncKey fromDate: filter initialLoad: NO]; count = [allMessages count]; diff --git a/NEWS b/NEWS index 0d8e75d3a..e46bf7628 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,7 @@ Enhancements - improved EAS speed and memory usage, avoiding many IMAP LIST commands (#3294) + - improved EAS speed during initial syncing of large mailboxes (#3293) Bug fixes - fixed display of whitelisted attendees in Preferences window on Firefox (#3285) diff --git a/SoObjects/Mailer/SOGoMailFolder.h b/SoObjects/Mailer/SOGoMailFolder.h index 1b3843795..431a58eb7 100644 --- a/SoObjects/Mailer/SOGoMailFolder.h +++ b/SoObjects/Mailer/SOGoMailFolder.h @@ -97,10 +97,10 @@ - (NSString *) davCollectionTag; -- (NSArray *) syncTokenFieldsWithProperties: (NSArray *) theProperties - matchingSyncToken: (NSString *) theSyncToken - fromDate: (NSCalendarDate *) theStartDate; - +- (NSArray *) syncTokenFieldsWithProperties: (NSDictionary *) properties + matchingSyncToken: (NSString *) syncToken + fromDate: (NSCalendarDate *) theStartDate + initialLoad: (BOOL) initialLoadInProgress; /* flags */ - (NSException *) addFlagsToAllMessages: (id) _f; diff --git a/SoObjects/Mailer/SOGoMailFolder.m b/SoObjects/Mailer/SOGoMailFolder.m index d402a3248..0b8bc9d0e 100644 --- a/SoObjects/Mailer/SOGoMailFolder.m +++ b/SoObjects/Mailer/SOGoMailFolder.m @@ -2119,6 +2119,7 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data) - (NSArray *) syncTokenFieldsWithProperties: (NSArray *) theProperties matchingSyncToken: (NSString *) theSyncToken fromDate: (NSCalendarDate *) theStartDate + initialLoad: (BOOL) initialLoadInProgress { EOQualifier *searchQualifier; NSMutableArray *allTokens; @@ -2195,6 +2196,9 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data) for (i = 0; i < [fetchResults count]; i++) { + if ([[[fetchResults objectAtIndex: i] objectForKey: @"flags"] containsObject: @"deleted"] && initialLoadInProgress) + continue; + d = [NSDictionary dictionaryWithObject: ([[[fetchResults objectAtIndex: i] objectForKey: @"flags"] containsObject: @"deleted"]) ? [NSNull null] : [[fetchResults objectAtIndex: i] objectForKey: @"modseq"] forKey: [[[fetchResults objectAtIndex: i] objectForKey: @"uid"] stringValue]]; [allTokens addObject: d]; @@ -2205,7 +2209,7 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data) if (highestmodseq == 0) highestmodseq = 1; - if (highestmodseq > 0) + if (highestmodseq > 0 && !initialLoadInProgress) { id uid; diff --git a/SoObjects/SOGo/SOGoGCSFolder.h b/SoObjects/SOGo/SOGoGCSFolder.h index 9b8de6b35..578bb7157 100644 --- a/SoObjects/SOGo/SOGoGCSFolder.h +++ b/SoObjects/SOGo/SOGoGCSFolder.h @@ -128,8 +128,8 @@ - (NSArray *) syncTokenFieldsWithProperties: (NSDictionary *) properties matchingSyncToken: (NSString *) syncToken - fromDate: (NSCalendarDate *) theStartDate; - + fromDate: (NSCalendarDate *) theStartDate + initialLoad: (BOOL) initialLoadInProgress; /* multiget helper */ - (WOResponse *) performMultigetInContext: (WOContext *) queryContext diff --git a/SoObjects/SOGo/SOGoGCSFolder.m b/SoObjects/SOGo/SOGoGCSFolder.m index a17d27c4d..add26d0fb 100644 --- a/SoObjects/SOGo/SOGoGCSFolder.m +++ b/SoObjects/SOGo/SOGoGCSFolder.m @@ -1151,6 +1151,7 @@ static NSArray *childRecordFields = nil; - (NSArray *) syncTokenFieldsWithProperties: (NSDictionary *) properties matchingSyncToken: (NSString *) syncToken fromDate: (NSCalendarDate *) theStartDate + initialLoad: (BOOL) initialLoadInProgress { /* TODO: - validation: @@ -1200,13 +1201,17 @@ static NSArray *childRecordFields = nil; mRecords = [NSMutableArray arrayWithArray: [self _fetchFields: fields withQualifier: qualifier ignoreDeleted: YES]]; - qualifier = [EOQualifier qualifierWithQualifierFormat: - @"c_lastmodified > %d and c_deleted == 1", - syncTokenInt]; - fields = [NSMutableArray arrayWithObjects: @"c_name", @"c_deleted", nil]; - [mRecords addObjectsFromArray: [self _fetchFields: fields - withQualifier: qualifier - ignoreDeleted: NO]]; + if (initialLoadInProgress) + { + qualifier = [EOQualifier qualifierWithQualifierFormat: + @"c_lastmodified > %d and c_deleted == 1", + syncTokenInt]; + fields = [NSMutableArray arrayWithObjects: @"c_name", @"c_lastmodified", @"c_deleted", nil]; + [mRecords addObjectsFromArray: [self _fetchFields: fields + withQualifier: qualifier + ignoreDeleted: NO]]; + } + records = mRecords; } else @@ -1499,7 +1504,9 @@ static NSArray *childRecordFields = nil; properties = [self parseDAVRequestedProperties: propElement]; records = [self syncTokenFieldsWithProperties: properties matchingSyncToken: syncToken - fromDate: nil]; + fromDate: nil + initialLoad: NO]; + [self _appendComponentProperties: [properties allKeys] fromRecords: records matchingSyncToken: [syncToken intValue]