Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update enumeration methods to allow a stop flag to be flipped by caller #204

Merged
merged 5 commits into from
Oct 4, 2017
Merged
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

* Add your own contributions to the next release on the line below this with your name.
- [fix] Add some sane limits to the disk cache: [#201]https://github.com/pinterest/PINCache/pull/201
- [new] Update enumeration methods to allow a stop flag to be flipped by caller: [#204](https://github.com/pinterest/PINCache/pull/204)
- [performance] Improves cache miss performance by ~2 orders of magnitude on device: [#202](https://github.com/pinterest/PINCache/pull/202)

## 3.0.1 -- Beta 5
Expand Down
6 changes: 6 additions & 0 deletions Source/PINCaching.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ typedef void (^PINCacheBlock)(id<PINCaching> cache);
*/
typedef void (^PINCacheObjectBlock)(id<PINCaching> cache, NSString *key, id _Nullable object);

/**
A callback block used for enumeration which provides the cache, key and object as arguments plus a stop flag that
may be flipped by the caller.
*/
typedef void (^PINCacheObjectEnumerationBlock)(id<PINCaching> cache, NSString *key, id _Nullable object, BOOL *stop);

/**
A callback block which provides a BOOL value as argument
*/
Expand Down
10 changes: 8 additions & 2 deletions Source/PINDiskCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ typedef void (^PINDiskCacheObjectBlock)(PINDiskCache *cache, NSString *key, id <
*/
typedef void (^PINDiskCacheFileURLBlock)(NSString *key, NSURL * _Nullable fileURL);

/**
A callback block used for enumeration which provides the key and fileURL of the object plus a stop flag that
may be flipped by the caller.
*/
typedef void (^PINDiskCacheFileURLEnumerationBlock)(NSString *key, NSURL * _Nullable fileURL, BOOL *stop);

/**
A callback block which provides a BOOL value as argument
*/
Expand Down Expand Up @@ -399,7 +405,7 @@ PIN_SUBCLASSING_RESTRICTED
lock is held.

*/
- (void)enumerateObjectsWithBlockAsync:(PINDiskCacheFileURLBlock)block completionBlock:(nullable PINCacheBlock)completionBlock;
- (void)enumerateObjectsWithBlockAsync:(PINDiskCacheFileURLEnumerationBlock)block completionBlock:(nullable PINCacheBlock)completionBlock;

#pragma mark - Synchronous Methods
/// @name Synchronous Methods
Expand Down Expand Up @@ -480,7 +486,7 @@ PIN_SUBCLASSING_RESTRICTED
lock is held.

*/
- (void)enumerateObjectsWithBlock:(PIN_NOESCAPE PINDiskCacheFileURLBlock)block;
- (void)enumerateObjectsWithBlock:(PIN_NOESCAPE PINDiskCacheFileURLEnumerationBlock)block;

@end

Expand Down
13 changes: 9 additions & 4 deletions Source/PINDiskCache.m
Original file line number Diff line number Diff line change
Expand Up @@ -811,7 +811,7 @@ - (void)removeAllObjectsAsync:(PINCacheBlock)block
} withPriority:PINOperationQueuePriorityLow];
}

- (void)enumerateObjectsWithBlockAsync:(PINDiskCacheFileURLBlock)block completionBlock:(PINCacheBlock)completionBlock
- (void)enumerateObjectsWithBlockAsync:(PINDiskCacheFileURLEnumerationBlock)block completionBlock:(PINCacheBlock)completionBlock
{
__weak PINDiskCache *weakSelf = self;

Expand Down Expand Up @@ -1115,7 +1115,7 @@ - (void)removeAllObjects
[self unlock];
}

- (void)enumerateObjectsWithBlock:(PINDiskCacheFileURLBlock)block
- (void)enumerateObjectsWithBlock:(PINDiskCacheFileURLEnumerationBlock)block
{
if (!block)
return;
Expand All @@ -1128,7 +1128,10 @@ - (void)enumerateObjectsWithBlock:(PINDiskCacheFileURLBlock)block
// If the cache should behave like a TTL cache, then only fetch the object if there's a valid ageLimit and the object is still alive
NSDate *date = _metadata[key].date;
if (!self->_ttlCache || self->_ageLimit <= 0 || (date && fabs([date timeIntervalSinceDate:now]) < self->_ageLimit)) {
block(key, fileURL);
BOOL stop = NO;
block(key, fileURL, &stop);
if (stop)
break;
}
}
[self unlock];
Expand Down Expand Up @@ -1466,7 +1469,9 @@ - (void)removeAllObjects:(nullable PINDiskCacheBlock)block

- (void)enumerateObjectsWithBlock:(PINDiskCacheFileURLBlock)block completionBlock:(nullable PINDiskCacheBlock)completionBlock
{
[self enumerateObjectsWithBlockAsync:block completionBlock:completionBlock];
[self enumerateObjectsWithBlockAsync:^(NSString * _Nonnull key, NSURL * _Nullable fileURL, BOOL * _Nonnull stop) {
block(key, fileURL);
} completionBlock:completionBlock];
}

@end
Expand Down
4 changes: 2 additions & 2 deletions Source/PINMemoryCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ PIN_SUBCLASSING_RESTRICTED
@param block A block to be executed for every object in the cache.
@param completionBlock An optional block to be executed concurrently when the enumeration is complete.
*/
- (void)enumerateObjectsWithBlockAsync:(PINCacheObjectBlock)block completionBlock:(nullable PINCacheBlock)completionBlock;
- (void)enumerateObjectsWithBlockAsync:(PINCacheObjectEnumerationBlock)block completionBlock:(nullable PINCacheBlock)completionBlock;

#pragma mark - Synchronous Methods
/// @name Synchronous Methods
Expand Down Expand Up @@ -212,7 +212,7 @@ PIN_SUBCLASSING_RESTRICTED
Instead use the asynchronous version, <enumerateObjectsWithBlock:completionBlock:>.

*/
- (void)enumerateObjectsWithBlock:(PIN_NOESCAPE PINCacheObjectBlock)block;
- (void)enumerateObjectsWithBlock:(PIN_NOESCAPE PINCacheObjectEnumerationBlock)block;

@end

Expand Down
16 changes: 12 additions & 4 deletions Source/PINMemoryCache.m
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ - (void)removeAllObjectsAsync:(PINCacheBlock)block
} withPriority:PINOperationQueuePriorityHigh];
}

- (void)enumerateObjectsWithBlockAsync:(PINCacheObjectBlock)block completionBlock:(PINCacheBlock)completionBlock
- (void)enumerateObjectsWithBlockAsync:(PINCacheObjectEnumerationBlock)block completionBlock:(PINCacheBlock)completionBlock
{
__weak PINMemoryCache *weakSelf = self;

Expand Down Expand Up @@ -550,7 +550,7 @@ - (void)removeAllObjects

}

- (void)enumerateObjectsWithBlock:(PINCacheObjectBlock)block
- (void)enumerateObjectsWithBlock:(PINCacheObjectEnumerationBlock)block
{
if (!block)
return;
Expand All @@ -562,7 +562,10 @@ - (void)enumerateObjectsWithBlock:(PINCacheObjectBlock)block
for (NSString *key in keysSortedByDate) {
// If the cache should behave like a TTL cache, then only fetch the object if there's a valid ageLimit and the object is still alive
if (!self->_ttlCache || self->_ageLimit <= 0 || fabs([[_dates objectForKey:key] timeIntervalSinceDate:now]) < self->_ageLimit) {
block(self, key, _dictionary[key]);
BOOL stop = NO;
block(self, key, _dictionary[key], &stop);
if (stop)
break;
}
}
[self unlock];
Expand Down Expand Up @@ -827,7 +830,12 @@ - (void)removeAllObjects:(nullable PINMemoryCacheBlock)block

- (void)enumerateObjectsWithBlock:(PINMemoryCacheObjectBlock)block completionBlock:(nullable PINMemoryCacheBlock)completionBlock
{
[self enumerateObjectsWithBlockAsync:block completionBlock:completionBlock];
[self enumerateObjectsWithBlockAsync:^(id<PINCaching> _Nonnull cache, NSString * _Nonnull key, id _Nullable object, BOOL * _Nonnull stop) {
if ([cache isKindOfClass:[PINMemoryCache class]]) {
PINMemoryCache *memoryCache = (PINMemoryCache *)cache;
block(memoryCache, key, object);
}
} completionBlock:completionBlock];
}

@end
12 changes: 6 additions & 6 deletions Tests/PINCacheTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,7 @@ - (void)testMemoryCacheEnumerationWithWarning
__block NSUInteger enumCount = 0;

self.cache.memoryCache.didReceiveMemoryWarningBlock = ^(PINMemoryCache *cache) {
[cache enumerateObjectsWithBlockAsync:^(PINMemoryCache *cache, NSString *key, id object) {
[cache enumerateObjectsWithBlockAsync:^(PINMemoryCache *cache, NSString *key, id object, BOOL *stop) {
@synchronized (self) {
enumCount++;
}
Expand Down Expand Up @@ -543,7 +543,7 @@ - (void)testDiskCacheEnumeration

__block NSUInteger enumCount = 0;

[self.cache.diskCache enumerateObjectsWithBlockAsync:^(NSString *key, NSURL *fileURL) {
[self.cache.diskCache enumerateObjectsWithBlockAsync:^(NSString *key, NSURL *fileURL, BOOL *stop) {
@synchronized (self) {
enumCount++;
}
Expand Down Expand Up @@ -798,14 +798,14 @@ - (void)_testTTLCacheObjectEnumeration {
// With the TTL cache enabled, we expect enumerating over the caches to yield 0 objects
NSUInteger expectedObjCount = 0;
__block NSUInteger objCount = 0;
[self.cache.diskCache enumerateObjectsWithBlock:^(NSString * _Nonnull key, NSURL * _Nullable fileURL) {
[self.cache.diskCache enumerateObjectsWithBlock:^(NSString * _Nonnull key, NSURL * _Nullable fileURL, BOOL *stop) {
objCount++;
}];

XCTAssertEqual(objCount, expectedObjCount, @"Expected %lu objects in the cache", (unsigned long)expectedObjCount);

objCount = 0;
[self.cache.memoryCache enumerateObjectsWithBlock:^(PINMemoryCache *cache, NSString *key, id _Nullable object) {
[self.cache.memoryCache enumerateObjectsWithBlock:^(PINMemoryCache *cache, NSString *key, id _Nullable object, BOOL *stop) {
objCount++;
}];

Expand All @@ -824,14 +824,14 @@ - (void)_testTTLCacheObjectEnumeration {
// With the TTL cache disabled, we expect enumerating over the caches to yield 1 object each, since the 2nd cache clearing hasn't happened yet
expectedObjCount = 1;
objCount = 0;
[self.cache.diskCache enumerateObjectsWithBlock:^(NSString * _Nonnull key, NSURL * _Nullable fileURL) {
[self.cache.diskCache enumerateObjectsWithBlock:^(NSString * _Nonnull key, NSURL * _Nullable fileURL, BOOL *stop) {
objCount++;
}];

XCTAssertEqual(objCount, expectedObjCount, @"Expected %lu objects in the cache", (unsigned long)expectedObjCount);

objCount = 0;
[self.cache.memoryCache enumerateObjectsWithBlock:^(PINMemoryCache * _Nonnull cache, NSString * _Nonnull key, id _Nullable object) {
[self.cache.memoryCache enumerateObjectsWithBlock:^(PINMemoryCache * _Nonnull cache, NSString * _Nonnull key, id _Nullable object, BOOL *stop) {
objCount++;
}];

Expand Down