From 22d513ba9a542a508459490fbffb7575ab1dda60 Mon Sep 17 00:00:00 2001 From: beidson Date: Thu, 24 Aug 2006 05:59:33 +0000 Subject: [PATCH] Reviewed by Maciej First pass at pruning unused WebIconDatabase code. Focus on removing methods that simply have no place in the new DB at all. A few renames and a few important FIXMEs result, but no functionality changes. * Loader/WebIconLoader.m: (-[WebIconLoader didFinishLoading]): Call to WebIconDatabase instead of directly to the bridge * Misc/WebIconDatabase.h: * Misc/WebIconDatabase.m: (-[WebIconDatabase init]): (-[WebIconDatabase iconForURL:withSize:cache:]): (-[WebIconDatabase iconURLForURL:]): (-[WebIconDatabase defaultIconWithSize:]): (-[WebIconDatabase retainIconForURL:]): (-[WebIconDatabase releaseIconForURL:]): (-[WebIconDatabase removeAllIcons]): (-[WebIconDatabase _setIconData:forIconURL:]): (-[WebIconDatabase _setHaveNoIconForIconURL:]): (-[WebIconDatabase _setIconURL:forURL:]): (-[WebIconDatabase _hasEntryForIconURL:]): (-[WebIconDatabase _applicationWillTerminate:]): (-[WebIconDatabase _resetCachedWebPreferences:]): * Misc/WebIconDatabasePrivate.h: Changed setIcon: to setIconData: git-svn-id: https://svn.webkit.org/repository/webkit/trunk@16005 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- WebKit/ChangeLog | 27 ++ WebKit/Loader/WebIconLoader.m | 30 +- WebKit/Misc/WebIconDatabase.h | 16 - WebKit/Misc/WebIconDatabase.m | 529 ++------------------------- WebKit/Misc/WebIconDatabasePrivate.h | 2 +- 5 files changed, 55 insertions(+), 549 deletions(-) diff --git a/WebKit/ChangeLog b/WebKit/ChangeLog index 9d6e4dec342c..79bbb1d62414 100644 --- a/WebKit/ChangeLog +++ b/WebKit/ChangeLog @@ -1,3 +1,30 @@ +2006-08-23 Brady Eidson + + Reviewed by Maciej + + First pass at pruning unused WebIconDatabase code. Focus on removing methods that simply + have no place in the new DB at all. A few renames and a few important FIXMEs result, but no + functionality changes. + + * Loader/WebIconLoader.m: + (-[WebIconLoader didFinishLoading]): Call to WebIconDatabase instead of directly to the bridge + * Misc/WebIconDatabase.h: + * Misc/WebIconDatabase.m: + (-[WebIconDatabase init]): + (-[WebIconDatabase iconForURL:withSize:cache:]): + (-[WebIconDatabase iconURLForURL:]): + (-[WebIconDatabase defaultIconWithSize:]): + (-[WebIconDatabase retainIconForURL:]): + (-[WebIconDatabase releaseIconForURL:]): + (-[WebIconDatabase removeAllIcons]): + (-[WebIconDatabase _setIconData:forIconURL:]): + (-[WebIconDatabase _setHaveNoIconForIconURL:]): + (-[WebIconDatabase _setIconURL:forURL:]): + (-[WebIconDatabase _hasEntryForIconURL:]): + (-[WebIconDatabase _applicationWillTerminate:]): + (-[WebIconDatabase _resetCachedWebPreferences:]): + * Misc/WebIconDatabasePrivate.h: Changed setIcon: to setIconData: + 2006-08-23 Maciej Stachowiak Reviewed by Adele. diff --git a/WebKit/Loader/WebIconLoader.m b/WebKit/Loader/WebIconLoader.m index 9f2cb1114c1e..6630f58141ba 100644 --- a/WebKit/Loader/WebIconLoader.m +++ b/WebKit/Loader/WebIconLoader.m @@ -97,34 +97,12 @@ else data = [self resourceData]; - if (data) { - [[WebIconDatabaseBridge sharedBridgeInstance] _setIconData:data forIconURL:[[self URL] _web_originalDataAsString]]; - LOG(IconDatabase, "NewDB - Icon data set for URL %@", [[self URL] _web_originalDataAsString]); - } else { - [[WebIconDatabaseBridge sharedBridgeInstance] _setHaveNoIconForIconURL:[[self URL] _web_originalDataAsString]]; - LOG(IconDatabase, "NewDB - No icon for URL %@", [[self URL] _web_originalDataAsString]); - } - [frameLoader _iconLoaderReceivedPageIcon:[self URL]]; - [super didFinishLoading]; -#else - NSImage *icon; - - NS_DURING - NSData *data = [self resourceData]; - icon = [data length] > 0 ? [[NSImage alloc] initWithData:data] : nil; - NS_HANDLER - icon = nil; - NS_ENDHANDLER - - - if ([[icon representations] count] > 0) { - [[WebIconDatabase sharedIconDatabase] _setIcon:icon forIconURL:[[self URL] _web_originalDataAsString]]; - } else { + if (data) + [[WebIconDatabase sharedIconDatabase] _setIconData:data forIconURL:[[self URL] _web_originalDataAsString]]; + else [[WebIconDatabase sharedIconDatabase] _setHaveNoIconForIconURL:[[self URL] _web_originalDataAsString]]; - } - + [frameLoader _iconLoaderReceivedPageIcon:[self URL]]; - [icon release]; [super didFinishLoading]; #endif } diff --git a/WebKit/Misc/WebIconDatabase.h b/WebKit/Misc/WebIconDatabase.h index 76c30374fdbf..70cf7251f4cf 100644 --- a/WebKit/Misc/WebIconDatabase.h +++ b/WebKit/Misc/WebIconDatabase.h @@ -122,22 +122,6 @@ extern NSSize WebIconLargeSize; // 128 x 128 */ - (void)releaseIconForURL:(NSString *)URL; -/*! - @method delayDatabaseCleanup: - @discussion Only effective if called before the database begins removing icons. - delayDatabaseCleanUp increments an internal counter that when 0 begins the database clean-up. - The counter equals 0 at initialization. -*/ -- (void)delayDatabaseCleanup; - -/*! - @method allowDatabaseCleanup: - @discussion Informs the database that it now can begin removing icons. - allowDatabaseCleanup decrements an internal counter that when 0 begins the database clean-up. - The counter equals 0 at initialization. -*/ -- (void)allowDatabaseCleanup; - @end diff --git a/WebKit/Misc/WebIconDatabase.m b/WebKit/Misc/WebIconDatabase.m index be28b1e2def5..894123e6bb02 100644 --- a/WebKit/Misc/WebIconDatabase.m +++ b/WebKit/Misc/WebIconDatabase.m @@ -67,16 +67,8 @@ NSSize WebIconLargeSize = {128, 128}; - (void)_clearDictionaries; - (void)_createFileDatabase; - (void)_loadIconDictionaries; -- (void)_updateFileDatabase; -- (void)_forgetIconForIconURLString:(NSString *)iconURLString; -- (NSMutableDictionary *)_iconsForIconURLString:(NSString *)iconURL; - (NSImage *)_iconForFileURL:(NSString *)fileURL withSize:(NSSize)size; -- (void)_retainIconForIconURLString:(NSString *)iconURL; -- (void)_releaseIconForIconURLString:(NSString *)iconURL; -- (void)_retainOriginalIconsOnDisk; -- (void)_releaseOriginalIconsOnDisk; - (void)_resetCachedWebPreferences:(NSNotification *)notification; -- (int)_totalRetainCountForIconURLString:(NSString *)iconURLString; - (NSImage *)_largestIconFromDictionary:(NSMutableDictionary *)icons; - (NSMutableDictionary *)_iconsBySplittingRepresentationsOfIcon:(NSImage *)icon; - (NSImage *)_iconFromDictionary:(NSMutableDictionary *)icons forSize:(NSSize)size cache:(BOOL)cache; @@ -122,8 +114,6 @@ NSSize WebIconLargeSize = {128, 128}; [self _createFileDatabase]; [self _loadIconDictionaries]; - _isClosing = NO; - #ifdef ICONDEBUG _private->databaseBridge = [WebIconDatabaseBridge sharedBridgeInstance]; if (_private->databaseBridge) { @@ -139,10 +129,8 @@ NSSize WebIconLargeSize = {128, 128}; } [self _convertToWebCoreFormat]; -#else - _private->databaseBridge = nil; #endif - + _private->iconURLToIcons = [[NSMutableDictionary alloc] init]; _private->iconURLToExtraRetainCount = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, NULL); _private->pageURLToRetainCount = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, NULL); @@ -164,12 +152,6 @@ NSSize WebIconLargeSize = {128, 128}; // FIXME - Once the new iconDB is the only game in town, we need to remove any of the WebFileDatabase code // that is threaded and expects certain files to exist - certain files we rip right out from underneath it // in the _convertToWebCoreFormat method -#ifndef ICONDEBUG - // Retain icons on disk then release them once clean-up has begun. - // This gives the client the opportunity to retain them before they are erased. - [self _retainOriginalIconsOnDisk]; - [self performSelector:@selector(_releaseOriginalIconsOnDisk) withObject:nil afterDelay:0]; -#endif return self; } @@ -182,34 +164,14 @@ NSSize WebIconLargeSize = {128, 128}; if (!URL || ![self _isEnabled]) return [self defaultIconWithSize:size]; + // - Move the handling of FileURLs to WebCore and implement in ObjC++ if ([URL _webkit_isFileURL]) return [self _iconForFileURL:URL withSize:size]; #ifdef ICONDEBUG NSImage* image = [_private->databaseBridge iconForPageURL:URL withSize:size]; - - // FIXME - We currently don't embed the default icon in the new WebCore IconDB, so we'll return the old version of it; return image ? image : [self defaultIconWithSize:size]; #endif - - NSString *iconURLString = [_private->pageURLToIconURL objectForKey:URL]; - if (!iconURLString) - // Don't have it - return [self defaultIconWithSize:size]; - - NSMutableDictionary *icons = [self _iconsForIconURLString:iconURLString]; - - if (!icons) { - if (![_private->iconURLsWithNoIcons containsObject:iconURLString]) { - // We used to have this icon, but don't have it anymore for some reason. (Bug? Deleted from - // disk behind our back?). Forget that we ever had it so it will be re-fetched next time. - LOG_ERROR("WebIconDatabase used to contain %@, but the icon file is missing. Now forgetting that we ever knew about this icon.", iconURLString); - [self _forgetIconForIconURLString:iconURLString]; - } - return [self defaultIconWithSize:size]; - } - - return [self _iconFromDictionary:icons forSize:size cache:cache]; } - (NSImage *)iconForURL:(NSString *)URL withSize:(NSSize)size @@ -226,8 +188,6 @@ NSSize WebIconLargeSize = {128, 128}; NSString* iconurl = [_private->databaseBridge iconURLForPageURL:URL]; return iconurl; #endif - - return URL ? [_private->pageURLToIconURL objectForKey:URL] : nil; } - (NSImage *)defaultIconWithSize:(NSSize)size @@ -238,18 +198,6 @@ NSSize WebIconLargeSize = {128, 128}; #ifdef ICONDEBUG return [_private->databaseBridge defaultIconWithSize:size]; #endif - - if (!_private->defaultIcons) { - NSString *path = [[NSBundle bundleForClass:[self class]] pathForResource:@"url_icon" ofType:@"tiff"]; - if (path) { - NSImage *icon = [[NSImage alloc] initByReferencingFile:path]; - _private->defaultIcons = [[NSMutableDictionary dictionaryWithObject:icon - forKey:[NSValue valueWithSize:[icon size]]] retain]; - [icon release]; - } - } - - return [self _iconFromDictionary:_private->defaultIcons forSize:size cache:YES]; } - (void)retainIconForURL:(NSString *)URL @@ -262,10 +210,6 @@ NSSize WebIconLargeSize = {128, 128}; [_private->databaseBridge retainIconForURL:URL]; return; #endif - - WebNSUInteger retainCount = (WebNSUInteger)(void *)CFDictionaryGetValue(_private->pageURLToRetainCount, URL); - CFDictionarySetValue(_private->pageURLToRetainCount, URL, (void *)(retainCount + 1)); - } - (void)releaseIconForURL:(NSString *)pageURL @@ -273,93 +217,12 @@ NSSize WebIconLargeSize = {128, 128}; ASSERT(pageURL); if (![self _isEnabled]) return; - + #ifdef ICONDEBUG [_private->databaseBridge releaseIconForURL:pageURL]; return; #endif - - WebNSUInteger retainCount = (WebNSUInteger)(void *)CFDictionaryGetValue(_private->pageURLToRetainCount, pageURL); - - if (retainCount <= 0) { - LOG_ERROR("The icon for %@ was released more times than it was retained.", pageURL); - return; - } - - WebNSUInteger newRetainCount = retainCount - 1; - - if (newRetainCount == 0) { - // Forget association between this page URL and a retain count - CFDictionaryRemoveValue(_private->pageURLToRetainCount, pageURL); - - // If there's a known iconURL for this page URL, we need to do more cleanup - NSString *iconURL = [_private->pageURLToIconURL objectForKey:pageURL]; - if (iconURL != nil) { - // If there are no other retainers of this icon, forget it entirely - if ([self _totalRetainCountForIconURLString:iconURL] == 0) { - [self _forgetIconForIconURLString:iconURL]; - } else { - // There's at least one other retainer of this icon, so we need to forget the - // two-way links between this page URL and the icon URL, without blowing away - // the icon entirely. - id pageURLs = [_private->iconURLToPageURLs objectForKey:iconURL]; - if ([pageURLs isKindOfClass:[NSMutableSet class]]) { - ASSERT([pageURLs containsObject:pageURL]); - [pageURLs removeObject:pageURL]; - - // Maybe this was the last page URL mapped to this icon URL - if ([(NSMutableSet *)pageURLs count] == 0) { - [_private->iconURLToPageURLs removeObjectForKey:iconURL]; - } - } else { - // Only one page URL was associated with this icon URL; it must have been us - ASSERT([pageURLs isKindOfClass:[NSString class]]); - ASSERT([pageURLs isEqualToString:pageURL]); - [_private->iconURLToPageURLs removeObjectForKey:pageURL]; - } - - // Remove iconURL from this dictionary last, since this might be the last - // reference and we need to use it as a key for _private->iconURLToPageURLs above. - [_private->pageURLToIconURL removeObjectForKey:pageURL]; - } - } - } else { - CFDictionarySetValue(_private->pageURLToRetainCount, pageURL, (void *)newRetainCount); - } -} - -- (void)delayDatabaseCleanup -{ - if (![self _isEnabled]) { - return; - } - - if(_private->didCleanup){ - LOG_ERROR("delayDatabaseCleanup cannot be called after cleanup has begun"); - return; - } - - _private->cleanupCount++; -} - -- (void)allowDatabaseCleanup -{ - if (![self _isEnabled]) { - return; - } - - if(_private->didCleanup){ - LOG_ERROR("allowDatabaseCleanup cannot be called after cleanup has begun"); - return; - } - - _private->cleanupCount--; - - if(_private->cleanupCount == 0 && _private->waitingToCleanup){ - [self _releaseOriginalIconsOnDisk]; - } } - @end @@ -367,27 +230,10 @@ NSSize WebIconLargeSize = {128, 128}; - (void)removeAllIcons { - NSArray *keys = [(NSDictionary *)_private->iconURLToPageURLs allKeys]; - unsigned count = [keys count]; - for (unsigned i = 0; i < count; i++) - [self _forgetIconForIconURLString:[keys objectAtIndex:i]]; - - // Delete entire file database immediately. This has at least three advantages over waiting for - // _updateFileDatabase to execute: - // (1) _updateFileDatabase won't execute until an icon has been added - // (2) this is faster - // (3) this deletes all the on-disk hierarchy (especially useful if due to past problems there are - // some stale files in that hierarchy) - [_private->fileDatabase removeAllObjects]; - [_private->iconsToEraseWithURLs removeAllObjects]; - [_private->iconsToSaveWithURLs removeAllObjects]; - [_private->iconURLsBoundDuringPrivateBrowsing removeAllObjects]; - [_private->pageURLsBoundDuringPrivateBrowsing removeAllObjects]; - [self _clearDictionaries]; - [[NSNotificationCenter defaultCenter] postNotificationName:WebIconDatabaseDidRemoveAllIconsNotification - object:self - userInfo:nil]; + // FIXME - + // Need to create a bridge method that calls through to WebCore and performs a wipe of the DB there } + - (BOOL)isIconExpiredForIconURL:(NSString *)iconURL { return [_private->databaseBridge isIconExpiredForIconURL:iconURL]; @@ -402,30 +248,13 @@ NSSize WebIconLargeSize = {128, 128}; return (_private->fileDatabase != nil); } -- (void)_setIcon:(NSImage *)icon forIconURL:(NSString *)iconURL +- (void)_setIconData:(NSData *)data forIconURL:(NSString *)iconURL { - ASSERT(icon); + ASSERT(data); ASSERT(iconURL); - ASSERT([self _isEnabled]); - - NSMutableDictionary *icons = [self _iconsBySplittingRepresentationsOfIcon:icon]; - - if (!icons) - return; - - [_private->iconURLToIcons setObject:icons forKey:iconURL]; - - // Don't update any icon information on disk during private browsing. Remember which icons have been - // affected during private browsing so we can forget this information when private browsing is turned off. - if (_private->privateBrowsingEnabled) - [_private->iconURLsBoundDuringPrivateBrowsing addObject:iconURL]; - - [self _retainIconForIconURLString:iconURL]; + ASSERT([self _isEnabled]); - // Release the newly created icon much like an autorelease. - // This gives the client enough time to retain it. - // FIXME: Should use an actual autorelease here using a proxy object instead. - [self performSelector:@selector(_releaseIconForIconURLString:) withObject:iconURL afterDelay:0]; + [_private->databaseBridge _setIconData:data forIconURL:iconURL]; } - (void)_setHaveNoIconForIconURL:(NSString *)iconURL @@ -437,20 +266,6 @@ NSSize WebIconLargeSize = {128, 128}; [_private->databaseBridge _setHaveNoIconForIconURL:iconURL]; return; #endif - - [_private->iconURLsWithNoIcons addObject:iconURL]; - - // Don't update any icon information on disk during private browsing. Remember which icons have been - // affected during private browsing so we can forget this information when private browsing is turned off. - if (_private->privateBrowsingEnabled) - [_private->iconURLsBoundDuringPrivateBrowsing addObject:iconURL]; - - [self _retainIconForIconURLString:iconURL]; - - // Release the newly created icon much like an autorelease. - // This gives the client enough time to retain it. - // FIXME: Should use an actual autorelease here using a proxy object instead. - [self performSelector:@selector(_releaseIconForIconURLString:) withObject:iconURL afterDelay:0]; } @@ -459,40 +274,26 @@ NSSize WebIconLargeSize = {128, 128}; ASSERT(iconURL); ASSERT(URL); ASSERT([self _isEnabled]); - ASSERT(_private->pageURLToIconURL); #ifdef ICONDEBUG - [_private->databaseBridge _setIconURL:iconURL forPageURL:URL]; - [self _sendNotificationForURL:URL]; - return; -#endif - - if ([[_private->pageURLToIconURL objectForKey:URL] isEqualToString:iconURL]) { - // Don't do any work if the icon URL is already bound to the site URL - return; - } - - // Keep track of which entries in pageURLToIconURL were created during private browsing so that they can be skipped - // when saving to disk. - if (_private->privateBrowsingEnabled) - [_private->pageURLsBoundDuringPrivateBrowsing addObject:URL]; - - [_private->pageURLToIconURL setObject:iconURL forKey:URL]; - [_private->iconURLToPageURLs _web_setObjectUsingSetIfNecessary:URL forKey:iconURL]; - - if ([_private->iconURLsWithNoIcons containsObject:iconURL]) { + // FIXME - The following comment is a holdover from the old icon DB, which handled missing icons + // differently than the new db. It would return early if the icon is in the negative cache, + // avoiding the notification. We should explore and see if a similar optimization can take place- // If the icon is in the negative cache (ie, there is no icon), avoid the // work of delivering a notification for it or saving it to disk. This is a significant // win on the iBench HTML test. - // This return must occur after the dictionary set calls above, so the icon record - // is properly retained. Otherwise, we'll forget that the site had no icon, and - // inefficiently request its icon again. - return; - } + // FIXME - The following comment is also a holdover - if the iconURL->pageURL mapping was already the + // same, the notification would again be avoided - we should try to do this, too. + // Don't do any work if the icon URL is already bound to the site URL + + // A possible solution for both of these is to have the bridge method return a BOOL saying "Yes, notify" or + // "no, don't bother notifying" + [_private->databaseBridge _setIconURL:iconURL forPageURL:URL]; [self _sendNotificationForURL:URL]; - [self _updateFileDatabase]; + return; +#endif } - (BOOL)_hasEntryForIconURL:(NSString *)iconURL; @@ -500,18 +301,8 @@ NSSize WebIconLargeSize = {128, 128}; ASSERT([self _isEnabled]); #ifdef ICONDEBUG - BOOL result = [_private->databaseBridge _hasEntryForIconURL:iconURL]; - if (result) - LOG(IconDatabase, "NewDB has icon for IconURL %@", iconURL); - else - LOG(IconDatabase, "NewDB has NO icon for IconURL %@", iconURL); - return result; + return [_private->databaseBridge _hasEntryForIconURL:iconURL]; #endif - - return (([_private->iconURLToIcons objectForKey:iconURL] || - [_private->iconURLsWithNoIcons containsObject:iconURL] || - [_private->iconsOnDiskWithURLs containsObject:iconURL]) && - [self _totalRetainCountForIconURLString:iconURL] > 0); } - (void)_sendNotificationForURL:(NSString *)URL @@ -634,150 +425,17 @@ NSSize WebIconLargeSize = {128, 128}; _private->originalIconsOnDiskWithURLs = [iconsOnDiskWithURLs copy]; } -// Only called by _setIconURL:forKey: -- (void)_updateFileDatabase -{ - if (_private->cleanupCount != 0) - return; - WebFileDatabase *fileDB = _private->fileDatabase; - if (!fileDB) { - LOG_ERROR("Couldn't update file database because it didn't exist"); - return; - } - - [fileDB setObject:[NSNumber numberWithInt:WebIconDatabaseCurrentVersion] forKey:WebIconDatabaseVersionKey]; - - // Erase icons that have been released that are on disk. - // Must remove icons before writing them to disk or else we could potentially remove the newly written ones. - NSEnumerator *enumerator = [_private->iconsToEraseWithURLs objectEnumerator]; - NSString *iconURLString; - - while ((iconURLString = [enumerator nextObject]) != nil) { - [fileDB removeObjectForKey:iconURLString]; - [_private->iconsOnDiskWithURLs removeObject:iconURLString]; - } - - // Save icons that have been retained that are not already on disk - enumerator = [_private->iconsToSaveWithURLs objectEnumerator]; - - while ((iconURLString = [enumerator nextObject]) != nil) { - NSMutableDictionary *icons = [_private->iconURLToIcons objectForKey:iconURLString]; - if (icons) { - // Save the 16 x 16 size icons as this is the only size that Safari uses. - // If we ever use larger sizes, we should save the largest size so icons look better when scaling up. - // This also works around the problem with cnet's blank 32x32 icon (3105486). - NSImage *icon = [icons objectForKey:[NSValue valueWithSize:NSMakeSize(16,16)]]; - if (!icon) { - // In case there is no 16 x 16 size. - icon = [self _largestIconFromDictionary:icons]; - } - NSData *iconData = [icon TIFFRepresentation]; - if (iconData) { - //NSLog(@"Writing icon: %@", iconURLString); - [fileDB setObject:iconData forKey:iconURLString]; - [_private->iconsOnDiskWithURLs addObject:iconURLString]; - } - } else if ([_private->iconURLsWithNoIcons containsObject:iconURLString]) { - [fileDB setObject:[NSNull null] forKey:iconURLString]; - [_private->iconsOnDiskWithURLs addObject:iconURLString]; - } - } - - [_private->iconsToEraseWithURLs removeAllObjects]; - [_private->iconsToSaveWithURLs removeAllObjects]; - - // Save the icon dictionaries to disk, after removing any values created during private browsing. - // Even if we weren't modifying the dictionary we'd still want to use a copy so that WebFileDatabase - // doesn't look at the original from a different thread. (We used to think this would fix 3566336 - // but that bug's progeny are still alive and kicking.) - NSMutableDictionary *pageURLToIconURLCopy = [_private->pageURLToIconURL mutableCopy]; - [pageURLToIconURLCopy removeObjectsForKeys:[_private->pageURLsBoundDuringPrivateBrowsing allObjects]]; - [fileDB setObject:pageURLToIconURLCopy forKey:WebURLToIconURLKey]; - [pageURLToIconURLCopy release]; -} - (void)_applicationWillTerminate:(NSNotification *)notification { - // Should only cause a write if user quit before 3 seconds after the last _updateFileDatabase - [_private->fileDatabase sync]; - #ifdef ICONDEBUG [_private->databaseBridge closeSharedDatabase]; [_private->databaseBridge release]; _private->databaseBridge = nil; #endif - _isClosing = YES; -} - -- (int)_totalRetainCountForIconURLString:(NSString *)iconURLString -{ - // Add up the retain counts for each associated page, plus the retain counts not associated - // with any page, which are stored in _private->iconURLToExtraRetainCount - WebNSUInteger result = (WebNSUInteger)(void *)CFDictionaryGetValue(_private->iconURLToExtraRetainCount, iconURLString); - - id URLStrings = [_private->iconURLToPageURLs objectForKey:iconURLString]; - if (URLStrings != nil) { - if ([URLStrings isKindOfClass:[NSMutableSet class]]) { - NSEnumerator *e = [(NSMutableSet *)URLStrings objectEnumerator]; - NSString *URLString; - while ((URLString = [e nextObject]) != nil) { - ASSERT([URLString isKindOfClass:[NSString class]]); - result += (WebNSUInteger)(void *)CFDictionaryGetValue(_private->pageURLToRetainCount, URLString); - } - } else { - ASSERT([URLStrings isKindOfClass:[NSString class]]); - result += (WebNSUInteger)(void *)CFDictionaryGetValue(_private->pageURLToRetainCount, URLStrings); - } - } - - return result; } -- (NSMutableDictionary *)_iconsForIconURLString:(NSString *)iconURLString -{ - ASSERT(iconURLString); - - if ([_private->iconURLsWithNoIcons containsObject:iconURLString]) - return nil; - - NSMutableDictionary *icons = [_private->iconURLToIcons objectForKey:iconURLString]; - - if (icons) - return icons; - - // Not in memory, check disk - if(![_private->iconsOnDiskWithURLs containsObject:iconURLString]) - return nil; - -#if !LOG_DISABLED - double start = CFAbsoluteTimeGetCurrent(); -#endif - NSData *iconData = [_private->fileDatabase objectForKey:iconURLString]; - - if ([iconData isKindOfClass:[NSNull class]]) { - [_private->iconURLsWithNoIcons addObject:iconURLString]; - return nil; - } - - if (iconData) { - NS_DURING - NSImage *icon = [[NSImage alloc] initWithData:iconData]; - icons = [self _iconsBySplittingRepresentationsOfIcon:icon]; - if (icons) { -#if !LOG_DISABLED - double duration = CFAbsoluteTimeGetCurrent() - start; - LOG(Timing, "loading and creating icon %@ took %f seconds", iconURLString, duration); -#endif - [_private->iconURLToIcons setObject:icons forKey:iconURLString]; - } - NS_HANDLER - icons = nil; - NS_ENDHANDLER - } - - return icons; -} - (NSImage *)_iconForFileURL:(NSString *)file withSize:(NSSize)size { @@ -808,120 +466,6 @@ NSSize WebIconLargeSize = {128, 128}; return icon; } -- (void)_retainIconForIconURLString:(NSString *)iconURLString -{ - ASSERT(iconURLString); - - WebNSUInteger retainCount = (WebNSUInteger)(void *)CFDictionaryGetValue(_private->iconURLToExtraRetainCount, iconURLString); - WebNSUInteger newRetainCount = retainCount + 1; - - CFDictionarySetValue(_private->iconURLToExtraRetainCount, iconURLString, (void *)newRetainCount); - - if (newRetainCount == 1 && !_private->privateBrowsingEnabled) { - - // Either we know nothing about this icon and need to save it to disk, or we were planning to remove it - // from disk (as set up in _forgetIconForIconURLString:) and should stop that process. - if ([_private->iconsOnDiskWithURLs containsObject:iconURLString]) { - ASSERT(![_private->iconsToSaveWithURLs containsObject:iconURLString]); - [_private->iconsToEraseWithURLs removeObject:iconURLString]; - } else { - ASSERT(![_private->iconsToEraseWithURLs containsObject:iconURLString]); - [_private->iconsToSaveWithURLs addObject:iconURLString]; - } - } -} - -- (void)_forgetIconForIconURLString:(NSString *)iconURLString -{ - ASSERT_ARG(iconURLString, iconURLString != nil); - if([_private->iconsOnDiskWithURLs containsObject:iconURLString]){ - [_private->iconsToEraseWithURLs addObject:iconURLString]; - [_private->iconsToSaveWithURLs removeObject:iconURLString]; - } - - // Remove the icon's images - [_private->iconURLToIcons removeObjectForKey:iconURLString]; - - // Remove negative cache item for icon, if any - [_private->iconURLsWithNoIcons removeObject:iconURLString]; - - // Remove the icon's associated site URLs, if any - [iconURLString retain]; - id URLs = [_private->iconURLToPageURLs objectForKey:iconURLString]; - if (URLs != nil) { - if ([URLs isKindOfClass:[NSMutableSet class]]) - [_private->pageURLToIconURL removeObjectsForKeys:[URLs allObjects]]; - else { - ASSERT([URLs isKindOfClass:[NSString class]]); - [_private->pageURLToIconURL removeObjectForKey:URLs]; - } - } - [_private->iconURLToPageURLs removeObjectForKey:iconURLString]; - CFDictionaryRemoveValue(_private->iconURLToExtraRetainCount, iconURLString); - [iconURLString release]; -} - -- (void)_releaseIconForIconURLString:(NSString *)iconURLString -{ - ASSERT(iconURLString); - - if (![self _isEnabled]) - return; - - WebNSUInteger retainCount = (WebNSUInteger)(void *)CFDictionaryGetValue(_private->iconURLToExtraRetainCount, iconURLString); - - // This error used to be an ASSERT() that was causing the build bot to fail. The build bot was getting itself into a reproducible - // situation of having an icon for 127.0.0.1:8000/favicon.ico registered in the database but not finding the file for it. This situation - // triggers a call to _forgetIconForIconURL which dumps everything about the icon - including the retain count. A later call to releaseIconForURL - // would then ASSERT and crash the test as the retain count had be internally reset to zero - // The reason the build bot was getting into this situation is not yet understood but the cause of the ASSERT is - and the condition was already - // handled gracefully in release builds. Therefore we're changing it to a LOG_ERROR with the understanding that the sqlite icon database will not - // have this issue due to its entirely different nature - if (retainCount <= 0) { - if (!_isClosing) - LOG_ERROR("Trying to release an icon whose retain-count is already non-positive"); - return; - } - - WebNSUInteger newRetainCount = retainCount - 1; - if (newRetainCount == 0) { - CFDictionaryRemoveValue(_private->iconURLToExtraRetainCount, iconURLString); - if ([self _totalRetainCountForIconURLString:iconURLString] == 0) { - [self _forgetIconForIconURLString:iconURLString]; - } - } else { - CFDictionarySetValue(_private->iconURLToExtraRetainCount, iconURLString, (void *)newRetainCount); - } -} - -- (void)_retainOriginalIconsOnDisk -{ - NSEnumerator *enumerator = [_private->originalIconsOnDiskWithURLs objectEnumerator];; - NSString *iconURLString; - while ((iconURLString = [enumerator nextObject]) != nil) { - [self _retainIconForIconURLString:iconURLString]; - } -} - -- (void)_releaseOriginalIconsOnDisk -{ - if (_private->cleanupCount > 0) { - _private->waitingToCleanup = YES; - return; - } - - NSEnumerator *enumerator = [_private->originalIconsOnDiskWithURLs objectEnumerator]; - NSString *iconURLString; - while ((iconURLString = [enumerator nextObject]) != nil) { - [self _releaseIconForIconURLString:iconURLString]; - } - - [_private->originalIconsOnDiskWithURLs release]; - _private->originalIconsOnDiskWithURLs = nil; - - _private->didCleanup = YES; -} - - (void)_resetCachedWebPreferences:(NSNotification *)notification { BOOL privateBrowsingEnabledNow = [[WebPreferences standardPreferences] privateBrowsingEnabled]; @@ -930,33 +474,6 @@ NSSize WebIconLargeSize = {128, 128}; [_private->databaseBridge setPrivateBrowsingEnabled:privateBrowsingEnabledNow]; return; #endif - - if (privateBrowsingEnabledNow == _private->privateBrowsingEnabled) - return; - - _private->privateBrowsingEnabled = privateBrowsingEnabledNow; - - // When private browsing is turned off, forget everything we learned while it was on - if (!_private->privateBrowsingEnabled) { - // Forget all of the icons whose existence we learned of during private browsing. - NSEnumerator *iconEnumerator = [_private->iconURLsBoundDuringPrivateBrowsing objectEnumerator]; - NSString *iconURLString; - while ((iconURLString = [iconEnumerator nextObject]) != nil) - [self _forgetIconForIconURLString:iconURLString]; - - // Forget the relationships between page and icon that we learned during private browsing. - NSEnumerator *pageEnumerator = [_private->pageURLsBoundDuringPrivateBrowsing objectEnumerator]; - NSString *pageURLString; - while ((pageURLString = [pageEnumerator nextObject]) != nil) { - [_private->pageURLToIconURL removeObjectForKey:pageURLString]; - // Tell clients that these pages' icons have changed (to generic). The notification is named - // WebIconDatabaseDidAddIconNotification but it really means just "did change icon". - [self _sendNotificationForURL:pageURLString]; - } - - [_private->iconURLsBoundDuringPrivateBrowsing removeAllObjects]; - [_private->pageURLsBoundDuringPrivateBrowsing removeAllObjects]; - } } - (NSImage *)_largestIconFromDictionary:(NSMutableDictionary *)icons diff --git a/WebKit/Misc/WebIconDatabasePrivate.h b/WebKit/Misc/WebIconDatabasePrivate.h index 8e23a517a7f7..3c8dd5e3efbe 100644 --- a/WebKit/Misc/WebIconDatabasePrivate.h +++ b/WebKit/Misc/WebIconDatabasePrivate.h @@ -92,7 +92,7 @@ extern NSString *WebIconDatabaseDidRemoveAllIconsNotification; - (BOOL)_isEnabled; // Called by WebIconLoader after loading an icon. -- (void)_setIcon:(NSImage *)icon forIconURL:(NSString *)iconURL; +- (void)_setIconData:(NSData *)data forIconURL:(NSString *)iconURL; - (void)_setHaveNoIconForIconURL:(NSString *)iconURL; // Called by WebDataSource to bind a web site URL to a icon URL and icon image. -- 2.36.0