37 - (void)cache:(
CPCache)cache willEvictObject:(
id)obj;
63 unsigned _implementedDelegateMethods;
73 #pragma mark Initialization
81 if (
self = [super
init])
86 _implementedDelegateMethods = 0;
99 #pragma mark Managing cache
106 - (id)objectForKey:(
id)aKey
108 return [[_items objectForKey:aKey] object];
116 - (void)setObject:(
id)anObject forKey:(
id)aKey
127 - (void)setObject:(
id)anObject forKey:(
id)aKey cost:(
int)aCost
130 if ([_items objectForKey:aKey])
134 [_items setObject:[_CPCacheItem cacheItemWithObject:anObject cost:aCost position:++_currentPosition] forKey:aKey];
137 _totalCostCache = -1;
147 - (void)removeObjectForKey:(
id)aKey
150 [
self _sendDelegateWillEvictObjectForKey:aKey];
153 [_items removeObjectForKey:aKey];
156 _totalCostCache = -1;
162 - (void)removeAllObjects
165 var enumerator = [_items keyEnumerator],
168 while (key = [enumerator nextObject])
169 [
self _sendDelegateWillEvictObjectForKey:key]
172 [_items removeAllObjects];
175 _totalCostCache = -1;
176 _currentPosition = 0;
188 - (void)setCountLimit:(
int)aCountLimit
190 _countLimit = aCountLimit;
199 - (void)setTotalCostLimit:(
int)aTotalCostLimit
201 _totalCostLimit = aTotalCostLimit;
209 - (void)setDelegate:(
id)aDelegate
211 if (_delegate === aDelegate)
214 _delegate = aDelegate;
215 _implementedDelegateMethods = 0;
217 if ([_delegate respondsToSelector:
@selector(cache:willEvictObject:)])
223 #pragma mark Privates
230 return [_items count];
238 if (_totalCostCache >= 0)
239 return _totalCostCache;
241 var enumerator = [_items objectEnumerator],
246 while (value = [enumerator nextObject])
247 _totalCostCache += [value cost];
249 return _totalCostCache;
256 - (void)_resequencePosition
258 _currentPosition = 1;
261 var sortedKeys = [[_items allKeys] sortedArrayUsingFunction:
263 return [[[_items objectForKey:k1] position] compare:[[_items objectForKey:k2] position]]; }];
266 for (var i = 0; i < sortedKeys.length; ++i)
267 [[_items objectForKey:sortedKeys[i]] setPosition:_currentPosition++];
273 - (BOOL)_isTotalCostLimitExceeded
275 return ([
self _totalCost] > _totalCostLimit && _totalCostLimit > 0);
281 - (BOOL)_isCountLimitExceeded
283 return ([
self _count] > _countLimit && _countLimit > 0);
293 if (![
self _isTotalCostLimitExceeded] && ![
self _isCountLimitExceeded])
297 var sortedKeys = [[_items allKeys] sortedArrayUsingFunction:
299 return [[[_items objectForKey:k1] position] compare:[[_items objectForKey:k2] position]]; }];
302 for (var i = 0; i < sortedKeys.length; ++i)
304 if (![
self _isTotalCostLimitExceeded] && ![
self _isCountLimitExceeded])
308 [
self _sendDelegateWillEvictObjectForKey:sortedKeys[i]];
311 [_items removeObjectForKey: sortedKeys[i]];
314 _totalCostCache = -1;
318 [
self _resequencePosition];
326 - (void)_sendDelegateWillEvictObjectForKey:(
id)aKey
329 [_delegate cache:
self willEvictObject:[[_items objectForKey:aKey]
object]];
345 @implementation _CPCacheItem :
CPObject
352 + (id)cacheItemWithObject:(
CPObject)anObject cost:(
int)aCost position:(
int)aPosition
354 var cacheItem = [[
self alloc] init];
358 [cacheItem setObject:anObject];
359 [cacheItem setCost:aCost];
360 [cacheItem setPosition:aPosition];
397 - (void)setCountLimit:(
int)aValue
399 _countLimit = aValue;
405 - (int)totalCostLimit
407 return _totalCostLimit;
413 - (void)setTotalCostLimit:(
int)aValue
415 _totalCostLimit = aValue;