GSFileURLHandle: Use NSCache and limit cache size

This commit is contained in:
hmelder 2024-05-06 10:38:07 +02:00
parent 21a48f6136
commit e1fcc2db35
4 changed files with 81 additions and 54 deletions

View file

@ -35,6 +35,7 @@
#import "Foundation/NSURLHandle.h"
#import "Foundation/NSRunLoop.h"
#import "Foundation/NSFileManager.h"
#import "Foundation/NSCache.h"
@class GSFTPURLHandle;
@ -48,7 +49,11 @@
{
NSString *_path;
NSMutableDictionary *_attributes;
BOOL _cached;
BOOL _didLoad;
}
- (void) _setFileCacheSize: (NSUInteger) size;
@end
/**
@ -604,8 +609,13 @@ static Class NSURLHandleClass = 0;
*/
@implementation GSFileURLHandle
static NSMutableDictionary *fileCache = nil;
static NSLock *fileLock = nil;
static NSCache *fileCache = nil;
static NSUInteger defaultCacheSize = 4 * 1024 * 1024;
- (void) _setFileCacheSize: (NSUInteger) size
{
[fileCache setTotalCostLimit: size];
}
+ (NSURLHandle*) cachedHandleForURL: (NSURL*)url
{
@ -616,19 +626,8 @@ static NSLock *fileLock = nil;
NSString *path = [url path];
path = [path stringByStandardizingPath];
[fileLock lock];
NS_DURING
{
obj = [fileCache objectForKey: path];
IF_NO_ARC([[obj retain] autorelease];)
}
NS_HANDLER
{
[fileLock unlock];
[localException raise];
}
NS_ENDHANDLER
[fileLock unlock];
obj = [fileCache objectForKey: path];
IF_NO_ARC([[obj retain] autorelease];)
}
return obj;
}
@ -644,10 +643,10 @@ static NSLock *fileLock = nil;
+ (void) initialize
{
fileCache = [NSMutableDictionary new];
fileCache = [NSCache new];
[fileCache setName: @"org.gnustep.GSFileURLHandle.cache"];
[fileCache setTotalCostLimit: defaultCacheSize];
[[NSObject leakAt: &fileCache] release];
fileLock = [NSLock new];
[[NSObject leakAt: &fileLock] release];
}
- (NSData*) availableResourceData
@ -704,52 +703,24 @@ static NSLock *fileLock = nil;
path = [url path];
path = [path stringByStandardizingPath];
_didLoad = NO;
_cached = cached;
if (cached == YES)
{
id obj;
[fileLock lock];
NS_DURING
{
obj = [fileCache objectForKey: path];
if (obj != nil)
{
DESTROY(self);
IF_NO_ARC([obj retain];)
}
}
NS_HANDLER
{
obj = nil;
[fileLock unlock];
[localException raise];
}
NS_ENDHANDLER
[fileLock unlock];
obj = [fileCache objectForKey: path];
if (obj != nil)
{
return obj;
}
{
DESTROY(self);
IF_NO_ARC([obj retain];)
return obj;
}
}
if ((self = [super initWithURL: url cached: cached]) != nil)
{
_path = [path copy];
if (cached == YES)
{
[fileLock lock];
NS_DURING
{
[fileCache setObject: self forKey: _path];
}
NS_HANDLER
{
[fileLock unlock];
[localException raise];
}
NS_ENDHANDLER
[fileLock unlock];
}
}
return self;
}
@ -763,6 +734,13 @@ static NSLock *fileLock = nil;
traverseLink: YES];
RELEASE(_attributes);
_attributes = [dict mutableCopy];
if (_cached && !_didLoad)
{
[fileCache setObject: self forKey: _path cost: [d length]];
}
_didLoad = YES;
[self didLoadBytes: d loadComplete: YES];
return d;
}