From d6252ada3fd3580d01102e31c7c323ea3551549a Mon Sep 17 00:00:00 2001 From: Muneeb Ali Date: Mon, 27 May 2013 14:04:01 +0500 Subject: [PATCH 1/2] LRU caching on disk implemented --- MKNetworkKit/MKNetworkEngine.h | 24 +++++++++++++ MKNetworkKit/MKNetworkEngine.m | 61 +++++++++++++++++++++++++++++++++- MKNetworkKit/MKNetworkKit.h | 1 + 3 files changed, 85 insertions(+), 1 deletion(-) diff --git a/MKNetworkKit/MKNetworkEngine.h b/MKNetworkKit/MKNetworkEngine.h index 1b42664..b515ce8 100644 --- a/MKNetworkKit/MKNetworkEngine.h +++ b/MKNetworkKit/MKNetworkEngine.h @@ -384,6 +384,18 @@ */ -(int) cacheMemoryCost; + +/*! + * @abstract Cache Directory In Disk Size + * + * @discussion + * This method can be over-ridden by subclasses to provide an alternative in disk cache size. + * By default, MKNetworkKit caches MKNETWORKCACHE_DEFAULT_DISK_SIZE bytes in disk cache + * The default size is MKNETWORKCACHE_DEFAULT_DISK_SIZE + * Overriding this method is optional + */ +-(unsigned long long int) cacheDiskSize; + /*! * @abstract Enable Caching * @@ -413,6 +425,18 @@ */ -(BOOL) isReachable; +/*! + * @abstract Empties previously cached data + * + * @discussion + * This method is a handy helper that you can use to clear cached data that is exceeding the limit + * specified by cacheDiskSize method. + * By default, MKNetworkKit doens't cache your requests. Use this only when you enabled caching + * @seealso + * useLRUCache + */ +-(void) emptyCacheWRTDiskSize; + /*! * @abstract Boolean variable that states whether the request should automatically include an Accept-Language header. * @property shouldSendAcceptLanguageHeader diff --git a/MKNetworkKit/MKNetworkEngine.m b/MKNetworkKit/MKNetworkEngine.m index a238f97..345a0aa 100644 --- a/MKNetworkKit/MKNetworkEngine.m +++ b/MKNetworkKit/MKNetworkEngine.m @@ -618,6 +618,11 @@ -(int) cacheMemoryCost { return MKNETWORKCACHE_DEFAULT_COST; } +-(unsigned long long int) cacheDiskSize{ + + return MKNETWORKCACHE_DEFAULT_DISK_SIZE; +} + -(void) saveCache { for(NSString *cacheKey in [self.memoryCache allKeys]) @@ -723,6 +728,12 @@ -(void) useCache { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(saveCache) name:UIApplicationWillTerminateNotification object:nil]; + + //check for emptyCache whenever coming to app + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(emptyCache) + name:UIApplicationDidBecomeActiveNotification + object:nil]; #elif TARGET_OS_MAC @@ -749,12 +760,39 @@ -(void) emptyCache { contentsOfDirectoryAtPath:[self cacheDirectoryName] error:&error]; if(error) DLog(@"%@", error); - error = nil; + error = nil; + + unsigned long long int folderSize = [self folderSize:[self cacheDirectoryName]]; + unsigned long long int sizeToRemove = folderSize - [self cacheDiskSize]; + + if (folderSize <= 0) { + //return if we have not exceeded the limit + return; + } + + unsigned long long int fileSize = 0; + + int i = 0; + for(NSString *fileName in directoryContents) { NSString *path = [[self cacheDirectoryName] stringByAppendingPathComponent:fileName]; + + //calcualte size and add to count + NSDictionary *fileDictionary = [[NSFileManager defaultManager] + attributesOfItemAtPath:path + error:&error]; + + fileSize += [fileDictionary fileSize]; + + //remove file [[NSFileManager defaultManager] removeItemAtPath:path error:&error]; if(error) DLog(@"%@", error); + + //break if we are back in limit + if (fileSize > sizeToRemove) { + break; + } } error = nil; @@ -763,4 +801,25 @@ -(void) emptyCache { if(error) DLog(@"%@", error); } +- (unsigned long long int)folderSize:(NSString *)folderPath { + NSArray *filesArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:folderPath error:nil]; + NSEnumerator *filesEnumerator = [filesArray objectEnumerator]; + NSString *fileName; + unsigned long long int fileSize = 0; + + while (fileName = [filesEnumerator nextObject]) { + + NSString *path = [[self cacheDirectoryName] stringByAppendingPathComponent:fileName]; + NSError *error = nil; + + NSDictionary *fileDictionary = [[NSFileManager defaultManager] + attributesOfItemAtPath:path + error:&error]; + + fileSize += [fileDictionary fileSize]; + } + + return fileSize; +} + @end diff --git a/MKNetworkKit/MKNetworkKit.h b/MKNetworkKit/MKNetworkKit.h index 523e6ab..250e6c8 100644 --- a/MKNetworkKit/MKNetworkKit.h +++ b/MKNetworkKit/MKNetworkKit.h @@ -82,6 +82,7 @@ #define kMKNetworkEngineOperationCountChanged @"kMKNetworkEngineOperationCountChanged" #define MKNETWORKCACHE_DEFAULT_COST 10 +#define MKNETWORKCACHE_DEFAULT_DISK_SIZE 100*1024*1024 //100 MB #define MKNETWORKCACHE_DEFAULT_DIRECTORY @"MKNetworkKitCache" #define kMKNetworkKitDefaultCacheDuration 60 // 1 minute #define kMKNetworkKitDefaultImageHeadRequestDuration 3600*24*1 // 1 day (HEAD requests with eTag are sent only after expiry of this. Not that these are not RFC compliant, but needed for performance tuning) From 089a0a81b1a92ffc521bba9670809dd023e6def0 Mon Sep 17 00:00:00 2001 From: Muneeb Ali Date: Mon, 3 Jun 2013 10:29:19 +0500 Subject: [PATCH 2/2] unused code removed --- MKNetworkKit/MKNetworkEngine.h | 12 ------------ MKNetworkKit/MKNetworkEngine.m | 4 +--- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/MKNetworkKit/MKNetworkEngine.h b/MKNetworkKit/MKNetworkEngine.h index b515ce8..3eb94ab 100644 --- a/MKNetworkKit/MKNetworkEngine.h +++ b/MKNetworkKit/MKNetworkEngine.h @@ -425,18 +425,6 @@ */ -(BOOL) isReachable; -/*! - * @abstract Empties previously cached data - * - * @discussion - * This method is a handy helper that you can use to clear cached data that is exceeding the limit - * specified by cacheDiskSize method. - * By default, MKNetworkKit doens't cache your requests. Use this only when you enabled caching - * @seealso - * useLRUCache - */ --(void) emptyCacheWRTDiskSize; - /*! * @abstract Boolean variable that states whether the request should automatically include an Accept-Language header. * @property shouldSendAcceptLanguageHeader diff --git a/MKNetworkKit/MKNetworkEngine.m b/MKNetworkKit/MKNetworkEngine.m index 345a0aa..ba3dcc3 100644 --- a/MKNetworkKit/MKNetworkEngine.m +++ b/MKNetworkKit/MKNetworkEngine.m @@ -771,9 +771,7 @@ -(void) emptyCache { } unsigned long long int fileSize = 0; - - int i = 0; - + for(NSString *fileName in directoryContents) { NSString *path = [[self cacheDirectoryName] stringByAppendingPathComponent:fileName];