Use NSString instances as keys rather than NSNumber, to work around a performance issue with GNUstep < 1.24
parent
c9dad4cab6
commit
5b7cbb6350
|
@ -44,9 +44,9 @@
|
||||||
|
|
||||||
/* synchronisation & versioning */
|
/* synchronisation & versioning */
|
||||||
- (BOOL) synchroniseCache;
|
- (BOOL) synchroniseCache;
|
||||||
- (NSNumber *) modseqFromMessageChangeNumber: (NSNumber *) changeNum;
|
- (NSNumber *) modseqFromMessageChangeNumber: (NSString *) changeNum;
|
||||||
- (NSNumber *) messageUIDFromMessageKey: (NSString *) messageKey;
|
- (NSString *) messageUIDFromMessageKey: (NSString *) messageKey;
|
||||||
- (NSNumber *) changeNumberForMessageUID: (NSNumber *) messageUid;
|
- (NSString *) changeNumberForMessageUID: (NSString *) messageUid;
|
||||||
- (void) setChangeKey: (NSData *) changeKey
|
- (void) setChangeKey: (NSData *) changeKey
|
||||||
forMessageWithKey: (NSString *) messageKey;
|
forMessageWithKey: (NSString *) messageKey;
|
||||||
- (NSData *) changeKeyForMessageWithKey: (NSString *) messageKey;
|
- (NSData *) changeKeyForMessageWithKey: (NSString *) messageKey;
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#import <EOControl/EOQualifier.h>
|
#import <EOControl/EOQualifier.h>
|
||||||
#import <EOControl/EOSortOrdering.h>
|
#import <EOControl/EOSortOrdering.h>
|
||||||
#import <NGExtensions/NSObject+Logs.h>
|
#import <NGExtensions/NSObject+Logs.h>
|
||||||
|
#import <NGExtensions/NSObject+Values.h>
|
||||||
#import <NGExtensions/NSString+misc.h>
|
#import <NGExtensions/NSString+misc.h>
|
||||||
#import <NGImap4/NGImap4Connection.h>
|
#import <NGImap4/NGImap4Connection.h>
|
||||||
#import <NGImap4/NGImap4Client.h>
|
#import <NGImap4/NGImap4Client.h>
|
||||||
|
@ -507,8 +508,9 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data)
|
||||||
{
|
{
|
||||||
BOOL rc = YES;
|
BOOL rc = YES;
|
||||||
uint64_t newChangeNum;
|
uint64_t newChangeNum;
|
||||||
NSNumber *ti, *changeNumber, *modseq, *initialLastModseq, *lastModseq,
|
NSNumber *ti, *modseq, *initialLastModseq, *lastModseq,
|
||||||
*nextModseq, *uid;
|
*nextModseq;
|
||||||
|
NSString *changeNumber, *uid;
|
||||||
uint64_t lastModseqNbr;
|
uint64_t lastModseqNbr;
|
||||||
EOQualifier *kvQualifier, *searchQualifier;
|
EOQualifier *kvQualifier, *searchQualifier;
|
||||||
NSArray *uids;
|
NSArray *uids;
|
||||||
|
@ -520,6 +522,10 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data)
|
||||||
NSCalendarDate *now;
|
NSCalendarDate *now;
|
||||||
BOOL foundChange = NO;
|
BOOL foundChange = NO;
|
||||||
|
|
||||||
|
/* NOTE: we are using NSString instance for "uid" and "changeNumber" because
|
||||||
|
NSNumber proved to give very bad performances when used as NSDictionary
|
||||||
|
keys with GNUstep 1.22.1. The bug seems to be solved with 1.24 but many
|
||||||
|
distros still ship an older version. */
|
||||||
now = [NSCalendarDate date];
|
now = [NSCalendarDate date];
|
||||||
[now setTimeZone: utcTZ];
|
[now setTimeZone: utcTZ];
|
||||||
|
|
||||||
|
@ -584,10 +590,10 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data)
|
||||||
for (count = 0; count < max; count++)
|
for (count = 0; count < max; count++)
|
||||||
{
|
{
|
||||||
result = [fetchResults objectAtIndex: count];
|
result = [fetchResults objectAtIndex: count];
|
||||||
uid = [result objectForKey: @"uid"];
|
uid = [[result objectForKey: @"uid"] stringValue];
|
||||||
modseq = [result objectForKey: @"modseq"];
|
modseq = [result objectForKey: @"modseq"];
|
||||||
newChangeNum = [[self context] getNewChangeNumber];
|
newChangeNum = [[self context] getNewChangeNumber];
|
||||||
changeNumber = [NSNumber numberWithUnsignedLongLong: newChangeNum];
|
changeNumber = [NSString stringWithUnsignedLongLong: newChangeNum];
|
||||||
|
|
||||||
messageEntry = [NSMutableDictionary new];
|
messageEntry = [NSMutableDictionary new];
|
||||||
[messages setObject: messageEntry forKey: uid];
|
[messages setObject: messageEntry forKey: uid];
|
||||||
|
@ -627,7 +633,7 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data)
|
||||||
if ([messages objectForKey: uid])
|
if ([messages objectForKey: uid])
|
||||||
{
|
{
|
||||||
newChangeNum = [[self context] getNewChangeNumber];
|
newChangeNum = [[self context] getNewChangeNumber];
|
||||||
changeNumber = [NSNumber numberWithUnsignedLongLong: newChangeNum];
|
changeNumber = [NSString stringWithUnsignedLongLong: newChangeNum];
|
||||||
[messages removeObjectForKey: uid];
|
[messages removeObjectForKey: uid];
|
||||||
[self logWithFormat: @"removed message entry for uid %@", uid];
|
[self logWithFormat: @"removed message entry for uid %@", uid];
|
||||||
}
|
}
|
||||||
|
@ -651,7 +657,7 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSNumber *) modseqFromMessageChangeNumber: (NSNumber *) changeNum
|
- (NSNumber *) modseqFromMessageChangeNumber: (NSString *) changeNum
|
||||||
{
|
{
|
||||||
NSDictionary *mapping;
|
NSDictionary *mapping;
|
||||||
NSNumber *modseq;
|
NSNumber *modseq;
|
||||||
|
@ -662,28 +668,24 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data)
|
||||||
return modseq;
|
return modseq;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSNumber *) messageUIDFromMessageKey: (NSString *) messageKey
|
- (NSString *) messageUIDFromMessageKey: (NSString *) messageKey
|
||||||
{
|
{
|
||||||
NSNumber *messageUid;
|
NSString *messageUid;
|
||||||
NSString *uidString;
|
|
||||||
NSRange dotRange;
|
NSRange dotRange;
|
||||||
|
|
||||||
dotRange = [messageKey rangeOfString: @".eml"];
|
dotRange = [messageKey rangeOfString: @".eml"];
|
||||||
if (dotRange.location != NSNotFound)
|
if (dotRange.location != NSNotFound)
|
||||||
{
|
messageUid = [messageKey substringToIndex: dotRange.location];
|
||||||
uidString = [messageKey substringToIndex: dotRange.location];
|
|
||||||
messageUid = [NSNumber numberWithInt: [uidString intValue]];
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
messageUid = nil;
|
messageUid = nil;
|
||||||
|
|
||||||
return messageUid;
|
return messageUid;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSNumber *) changeNumberForMessageUID: (NSNumber *) messageUid
|
- (NSString *) changeNumberForMessageUID: (NSString *) messageUid
|
||||||
{
|
{
|
||||||
NSDictionary *messages;
|
NSDictionary *messages;
|
||||||
NSNumber *changeNumber;
|
NSString *changeNumber;
|
||||||
|
|
||||||
messages = [[versionsMessage properties] objectForKey: @"Messages"];
|
messages = [[versionsMessage properties] objectForKey: @"Messages"];
|
||||||
changeNumber = [[messages objectForKey: messageUid]
|
changeNumber = [[messages objectForKey: messageUid]
|
||||||
|
@ -695,9 +697,8 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data)
|
||||||
- (void) setChangeKey: (NSData *) changeKey
|
- (void) setChangeKey: (NSData *) changeKey
|
||||||
forMessageWithKey: (NSString *) messageKey
|
forMessageWithKey: (NSString *) messageKey
|
||||||
{
|
{
|
||||||
NSMutableDictionary *messages;
|
NSMutableDictionary *messages, *messageEntry;
|
||||||
NSMutableDictionary *messageEntry;
|
NSString *messageUid;
|
||||||
NSNumber *messageUid;
|
|
||||||
|
|
||||||
messageUid = [self messageUIDFromMessageKey: messageKey];
|
messageUid = [self messageUIDFromMessageKey: messageKey];
|
||||||
messages = [[versionsMessage properties] objectForKey: @"Messages"];
|
messages = [[versionsMessage properties] objectForKey: @"Messages"];
|
||||||
|
@ -712,8 +713,7 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data)
|
||||||
- (NSData *) changeKeyForMessageWithKey: (NSString *) messageKey
|
- (NSData *) changeKeyForMessageWithKey: (NSString *) messageKey
|
||||||
{
|
{
|
||||||
NSDictionary *messages, *changeKeyDict;
|
NSDictionary *messages, *changeKeyDict;
|
||||||
NSString *guid;
|
NSString *guid, *messageUid;
|
||||||
NSNumber *messageUid;
|
|
||||||
NSData *globCnt, *changeKey = nil;
|
NSData *globCnt, *changeKey = nil;
|
||||||
|
|
||||||
messageUid = [self messageUIDFromMessageKey: messageKey];
|
messageUid = [self messageUIDFromMessageKey: messageKey];
|
||||||
|
@ -738,8 +738,7 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data)
|
||||||
NSMutableArray *changeKeys;
|
NSMutableArray *changeKeys;
|
||||||
NSUInteger count, max;
|
NSUInteger count, max;
|
||||||
NSData *changeKey;
|
NSData *changeKey;
|
||||||
NSString *guid;
|
NSString *guid, *messageUid;
|
||||||
NSNumber *messageUid;
|
|
||||||
NSData *globCnt;
|
NSData *globCnt;
|
||||||
|
|
||||||
messageUid = [self messageUIDFromMessageKey: messageKey];
|
messageUid = [self messageUIDFromMessageKey: messageKey];
|
||||||
|
@ -779,26 +778,27 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data)
|
||||||
inTableType: (uint8_t) tableType
|
inTableType: (uint8_t) tableType
|
||||||
{
|
{
|
||||||
NSArray *deletedKeys, *deletedUIDs;
|
NSArray *deletedKeys, *deletedUIDs;
|
||||||
NSNumber *changeNumber;
|
NSString *changeNumber;
|
||||||
uint64_t modseq;
|
uint64_t modseq;
|
||||||
NSDictionary *versionProperties;
|
NSDictionary *versionProperties;
|
||||||
|
|
||||||
if (tableType == MAPISTORE_MESSAGE_TABLE)
|
if (tableType == MAPISTORE_MESSAGE_TABLE)
|
||||||
{
|
{
|
||||||
changeNumber = [NSNumber numberWithUnsignedLongLong: changeNum];
|
changeNumber = [NSString stringWithUnsignedLongLong: changeNum];
|
||||||
modseq = [[self modseqFromMessageChangeNumber: changeNumber]
|
modseq = [[self modseqFromMessageChangeNumber: changeNumber]
|
||||||
unsignedLongLongValue];
|
unsignedLongLongValue];
|
||||||
if (modseq > 0)
|
if (modseq > 0)
|
||||||
{
|
{
|
||||||
deletedUIDs = [(SOGoMailFolder *) sogoObject
|
deletedUIDs = [(SOGoMailFolder *) sogoObject
|
||||||
fetchUIDsOfVanishedItems: modseq];
|
fetchUIDsOfVanishedItems: modseq];
|
||||||
deletedKeys = [deletedUIDs stringsWithFormat: @"%@.eml"];
|
deletedKeys = [deletedUIDs stringsWithFormat: @"%@.eml"];
|
||||||
if ([deletedUIDs count] > 0)
|
if ([deletedUIDs count] > 0)
|
||||||
{
|
{
|
||||||
versionProperties = [versionsMessage properties];
|
versionProperties = [versionsMessage properties];
|
||||||
changeNumber = [versionProperties
|
changeNumber = [versionProperties
|
||||||
objectForKey: @"SyncLastDeleteChangeNumber"];
|
objectForKey: @"SyncLastDeleteChangeNumber"];
|
||||||
*cnNbr = changeNumber;
|
*cnNbr = [NSNumber numberWithUnsignedLongLong:
|
||||||
|
[changeNumber unsignedLongLongValue]];
|
||||||
[versionsMessage save];
|
[versionsMessage save];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -920,9 +920,9 @@ _parseCOPYUID (NSString *line, NSArray **destUIDsP)
|
||||||
{
|
{
|
||||||
NGImap4Connection *connection;
|
NGImap4Connection *connection;
|
||||||
NGImap4Client *client;
|
NGImap4Client *client;
|
||||||
NSString *sourceFolderName, *targetFolderName, *messageURL, *messageKey, *v;
|
NSString *sourceFolderName, *targetFolderName, *messageURL, *messageKey,
|
||||||
|
*uid, *v;
|
||||||
NSMutableArray *uids, *oldMessageURLs;
|
NSMutableArray *uids, *oldMessageURLs;
|
||||||
NSNumber *uid;
|
|
||||||
NSArray *destUIDs;
|
NSArray *destUIDs;
|
||||||
MAPIStoreMapping *mapping;
|
MAPIStoreMapping *mapping;
|
||||||
NSDictionary *result;
|
NSDictionary *result;
|
||||||
|
@ -1169,13 +1169,11 @@ _parseCOPYUID (NSString *line, NSArray **destUIDsP)
|
||||||
{
|
{
|
||||||
MAPIStoreMailMessage *message;
|
MAPIStoreMailMessage *message;
|
||||||
NSData *rawBodyData;
|
NSData *rawBodyData;
|
||||||
NSNumber *messageUID;
|
|
||||||
|
|
||||||
message = [super lookupMessage: messageKey];
|
message = [super lookupMessage: messageKey];
|
||||||
if (message)
|
if (message)
|
||||||
{
|
{
|
||||||
messageUID = [self messageUIDFromMessageKey: messageKey];
|
rawBodyData = [bodyData objectForKey: messageKey];
|
||||||
rawBodyData = [bodyData objectForKey: messageUID];
|
|
||||||
if (rawBodyData)
|
if (rawBodyData)
|
||||||
[message setBodyContentFromRawData: rawBodyData];
|
[message setBodyContentFromRawData: rawBodyData];
|
||||||
}
|
}
|
||||||
|
@ -1248,8 +1246,7 @@ _parseCOPYUID (NSString *line, NSArray **destUIDsP)
|
||||||
NSMutableDictionary *keyAssoc;
|
NSMutableDictionary *keyAssoc;
|
||||||
NSDictionary *response;
|
NSDictionary *response;
|
||||||
NSUInteger count, max;
|
NSUInteger count, max;
|
||||||
NSString *messageKey, *bodyPartKey;
|
NSString *messageKey, *messageUid, *bodyPartKey;
|
||||||
NSNumber *messageUID;
|
|
||||||
NGImap4Client *client;
|
NGImap4Client *client;
|
||||||
NSArray *fetch;
|
NSArray *fetch;
|
||||||
NSData *bodyContent;
|
NSData *bodyContent;
|
||||||
|
@ -1265,16 +1262,13 @@ _parseCOPYUID (NSString *line, NSArray **destUIDsP)
|
||||||
for (count = 0; count < max; count++)
|
for (count = 0; count < max; count++)
|
||||||
{
|
{
|
||||||
messageKey = [keys objectAtIndex: count];
|
messageKey = [keys objectAtIndex: count];
|
||||||
messageUID = [self messageUIDFromMessageKey: messageKey];
|
message = [self lookupMessage: messageKey];
|
||||||
if (messageUID)
|
if (message)
|
||||||
{
|
{
|
||||||
message = [self lookupMessage: messageKey];
|
bodyPartKey = [message bodyContentPartKey];
|
||||||
if (message)
|
[bodyPartKeys addObject: bodyPartKey];
|
||||||
{
|
messageUid = [self messageUIDFromMessageKey: messageKey];
|
||||||
bodyPartKey = [message bodyContentPartKey];
|
[keyAssoc setObject: bodyPartKey forKey: messageUid];
|
||||||
[bodyPartKeys addObject: bodyPartKey];
|
|
||||||
[keyAssoc setObject: bodyPartKey forKey: messageUID];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1287,16 +1281,17 @@ _parseCOPYUID (NSString *line, NSArray **destUIDsP)
|
||||||
for (count = 0; count < max; count++)
|
for (count = 0; count < max; count++)
|
||||||
{
|
{
|
||||||
response = [fetch objectAtIndex: count];
|
response = [fetch objectAtIndex: count];
|
||||||
messageUID = [response objectForKey: @"uid"];
|
messageUid = [[response objectForKey: @"uid"] stringValue];
|
||||||
if (messageUID)
|
bodyPartKey = [keyAssoc objectForKey: messageUid];
|
||||||
|
if (bodyPartKey)
|
||||||
{
|
{
|
||||||
bodyPartKey = [keyAssoc objectForKey: messageUID];
|
bodyContent = [[response objectForKey: bodyPartKey]
|
||||||
if (bodyPartKey)
|
objectForKey: @"data"];
|
||||||
|
if (bodyContent)
|
||||||
{
|
{
|
||||||
bodyContent = [[response objectForKey: bodyPartKey]
|
messageKey = [NSString stringWithFormat: @"%@.eml",
|
||||||
objectForKey: @"data"];
|
messageUid];
|
||||||
if (bodyContent)
|
[bodyData setObject: bodyContent forKey: messageKey];
|
||||||
[bodyData setObject: bodyContent forKey: messageUID];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#import <Foundation/NSDictionary.h>
|
#import <Foundation/NSDictionary.h>
|
||||||
#import <Foundation/NSException.h>
|
#import <Foundation/NSException.h>
|
||||||
#import <NGExtensions/NSObject+Logs.h>
|
#import <NGExtensions/NSObject+Logs.h>
|
||||||
|
#import <NGExtensions/NSObject+Values.h>
|
||||||
#import <NGImap4/NGImap4Client.h>
|
#import <NGImap4/NGImap4Client.h>
|
||||||
#import <NGImap4/NGImap4Connection.h>
|
#import <NGImap4/NGImap4Connection.h>
|
||||||
#import <NGImap4/NGImap4EnvelopeAddress.h>
|
#import <NGImap4/NGImap4EnvelopeAddress.h>
|
||||||
|
@ -366,21 +367,21 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data)
|
||||||
- (uint64_t) objectVersion
|
- (uint64_t) objectVersion
|
||||||
{
|
{
|
||||||
uint64_t version = ULLONG_MAX;
|
uint64_t version = ULLONG_MAX;
|
||||||
NSNumber *uid, *changeNumber;
|
NSString *uid, *changeNumber;
|
||||||
|
|
||||||
uid = [(MAPIStoreMailFolder *)
|
uid = [(MAPIStoreMailFolder *)
|
||||||
container messageUIDFromMessageKey: [self nameInContainer]];
|
container messageUIDFromMessageKey: [self nameInContainer]];
|
||||||
if (uid)
|
if (uid)
|
||||||
{
|
{
|
||||||
changeNumber = [(MAPIStoreMailFolder *) container
|
changeNumber = [(MAPIStoreMailFolder *) container
|
||||||
changeNumberForMessageUID: uid];
|
changeNumberForMessageUID: uid];
|
||||||
if (!changeNumber)
|
if (!changeNumber)
|
||||||
{
|
{
|
||||||
[self warnWithFormat: @"attempting to get change number"
|
[self warnWithFormat: @"attempting to get change number"
|
||||||
@" by synchronising folder..."];
|
@" by synchronising folder..."];
|
||||||
[(MAPIStoreMailFolder *) container synchroniseCache];
|
[(MAPIStoreMailFolder *) container synchroniseCache];
|
||||||
changeNumber = [(MAPIStoreMailFolder *) container
|
changeNumber = [(MAPIStoreMailFolder *) container
|
||||||
changeNumberForMessageUID: uid];
|
changeNumberForMessageUID: uid];
|
||||||
if (changeNumber)
|
if (changeNumber)
|
||||||
[self logWithFormat: @"got one"];
|
[self logWithFormat: @"got one"];
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in New Issue