Skip to content
This repository has been archived by the owner on Mar 4, 2020. It is now read-only.

LRU Caching on Disk #343

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions MKNetworkKit/MKNetworkEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand Down
59 changes: 58 additions & 1 deletion MKNetworkKit/MKNetworkEngine.m
Original file line number Diff line number Diff line change
Expand Up @@ -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])
Expand Down Expand Up @@ -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

Expand All @@ -749,12 +760,37 @@ -(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;

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;
Expand All @@ -763,4 +799,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
1 change: 1 addition & 0 deletions MKNetworkKit/MKNetworkKit.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down