Skip to content

Commit 084ad3e

Browse files
mjlazargarrettmoon
authored andcommitted
Update enumeration methods to allow a stop flag to be flipped by caller (#204)
* Update enumeration methods to allow a stop flag to be flipped by caller * Fix compiler warning * Add CHANGELOG entry * Changes to address garrettmoon's comments
1 parent 98348aa commit 084ad3e

File tree

7 files changed

+44
-18
lines changed

7 files changed

+44
-18
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

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

78
## 3.0.1 -- Beta 5

Source/PINCaching.h

+6
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ typedef void (^PINCacheBlock)(id<PINCaching> cache);
2424
*/
2525
typedef void (^PINCacheObjectBlock)(id<PINCaching> cache, NSString *key, id _Nullable object);
2626

27+
/**
28+
A callback block used for enumeration which provides the cache, key and object as arguments plus a stop flag that
29+
may be flipped by the caller.
30+
*/
31+
typedef void (^PINCacheObjectEnumerationBlock)(id<PINCaching> cache, NSString *key, id _Nullable object, BOOL *stop);
32+
2733
/**
2834
A callback block which provides a BOOL value as argument
2935
*/

Source/PINDiskCache.h

+8-2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ typedef void (^PINDiskCacheObjectBlock)(PINDiskCache *cache, NSString *key, id <
2525
*/
2626
typedef void (^PINDiskCacheFileURLBlock)(NSString *key, NSURL * _Nullable fileURL);
2727

28+
/**
29+
A callback block used for enumeration which provides the key and fileURL of the object plus a stop flag that
30+
may be flipped by the caller.
31+
*/
32+
typedef void (^PINDiskCacheFileURLEnumerationBlock)(NSString *key, NSURL * _Nullable fileURL, BOOL *stop);
33+
2834
/**
2935
A callback block which provides a BOOL value as argument
3036
*/
@@ -399,7 +405,7 @@ PIN_SUBCLASSING_RESTRICTED
399405
lock is held.
400406
401407
*/
402-
- (void)enumerateObjectsWithBlockAsync:(PINDiskCacheFileURLBlock)block completionBlock:(nullable PINCacheBlock)completionBlock;
408+
- (void)enumerateObjectsWithBlockAsync:(PINDiskCacheFileURLEnumerationBlock)block completionBlock:(nullable PINCacheBlock)completionBlock;
403409

404410
#pragma mark - Synchronous Methods
405411
/// @name Synchronous Methods
@@ -480,7 +486,7 @@ PIN_SUBCLASSING_RESTRICTED
480486
lock is held.
481487
482488
*/
483-
- (void)enumerateObjectsWithBlock:(PIN_NOESCAPE PINDiskCacheFileURLBlock)block;
489+
- (void)enumerateObjectsWithBlock:(PIN_NOESCAPE PINDiskCacheFileURLEnumerationBlock)block;
484490

485491
@end
486492

Source/PINDiskCache.m

+9-4
Original file line numberDiff line numberDiff line change
@@ -811,7 +811,7 @@ - (void)removeAllObjectsAsync:(PINCacheBlock)block
811811
} withPriority:PINOperationQueuePriorityLow];
812812
}
813813

814-
- (void)enumerateObjectsWithBlockAsync:(PINDiskCacheFileURLBlock)block completionBlock:(PINCacheBlock)completionBlock
814+
- (void)enumerateObjectsWithBlockAsync:(PINDiskCacheFileURLEnumerationBlock)block completionBlock:(PINCacheBlock)completionBlock
815815
{
816816
__weak PINDiskCache *weakSelf = self;
817817

@@ -1115,7 +1115,7 @@ - (void)removeAllObjects
11151115
[self unlock];
11161116
}
11171117

1118-
- (void)enumerateObjectsWithBlock:(PINDiskCacheFileURLBlock)block
1118+
- (void)enumerateObjectsWithBlock:(PINDiskCacheFileURLEnumerationBlock)block
11191119
{
11201120
if (!block)
11211121
return;
@@ -1128,7 +1128,10 @@ - (void)enumerateObjectsWithBlock:(PINDiskCacheFileURLBlock)block
11281128
// 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
11291129
NSDate *date = _metadata[key].date;
11301130
if (!self->_ttlCache || self->_ageLimit <= 0 || (date && fabs([date timeIntervalSinceDate:now]) < self->_ageLimit)) {
1131-
block(key, fileURL);
1131+
BOOL stop = NO;
1132+
block(key, fileURL, &stop);
1133+
if (stop)
1134+
break;
11321135
}
11331136
}
11341137
[self unlock];
@@ -1466,7 +1469,9 @@ - (void)removeAllObjects:(nullable PINDiskCacheBlock)block
14661469

14671470
- (void)enumerateObjectsWithBlock:(PINDiskCacheFileURLBlock)block completionBlock:(nullable PINDiskCacheBlock)completionBlock
14681471
{
1469-
[self enumerateObjectsWithBlockAsync:block completionBlock:completionBlock];
1472+
[self enumerateObjectsWithBlockAsync:^(NSString * _Nonnull key, NSURL * _Nullable fileURL, BOOL * _Nonnull stop) {
1473+
block(key, fileURL);
1474+
} completionBlock:completionBlock];
14701475
}
14711476

14721477
@end

Source/PINMemoryCache.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ PIN_SUBCLASSING_RESTRICTED
177177
@param block A block to be executed for every object in the cache.
178178
@param completionBlock An optional block to be executed concurrently when the enumeration is complete.
179179
*/
180-
- (void)enumerateObjectsWithBlockAsync:(PINCacheObjectBlock)block completionBlock:(nullable PINCacheBlock)completionBlock;
180+
- (void)enumerateObjectsWithBlockAsync:(PINCacheObjectEnumerationBlock)block completionBlock:(nullable PINCacheBlock)completionBlock;
181181

182182
#pragma mark - Synchronous Methods
183183
/// @name Synchronous Methods
@@ -212,7 +212,7 @@ PIN_SUBCLASSING_RESTRICTED
212212
Instead use the asynchronous version, <enumerateObjectsWithBlock:completionBlock:>.
213213
214214
*/
215-
- (void)enumerateObjectsWithBlock:(PIN_NOESCAPE PINCacheObjectBlock)block;
215+
- (void)enumerateObjectsWithBlock:(PIN_NOESCAPE PINCacheObjectEnumerationBlock)block;
216216

217217
@end
218218

Source/PINMemoryCache.m

+12-4
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ - (void)removeAllObjectsAsync:(PINCacheBlock)block
395395
} withPriority:PINOperationQueuePriorityHigh];
396396
}
397397

398-
- (void)enumerateObjectsWithBlockAsync:(PINCacheObjectBlock)block completionBlock:(PINCacheBlock)completionBlock
398+
- (void)enumerateObjectsWithBlockAsync:(PINCacheObjectEnumerationBlock)block completionBlock:(PINCacheBlock)completionBlock
399399
{
400400
__weak PINMemoryCache *weakSelf = self;
401401

@@ -550,7 +550,7 @@ - (void)removeAllObjects
550550

551551
}
552552

553-
- (void)enumerateObjectsWithBlock:(PINCacheObjectBlock)block
553+
- (void)enumerateObjectsWithBlock:(PINCacheObjectEnumerationBlock)block
554554
{
555555
if (!block)
556556
return;
@@ -562,7 +562,10 @@ - (void)enumerateObjectsWithBlock:(PINCacheObjectBlock)block
562562
for (NSString *key in keysSortedByDate) {
563563
// 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
564564
if (!self->_ttlCache || self->_ageLimit <= 0 || fabs([[_dates objectForKey:key] timeIntervalSinceDate:now]) < self->_ageLimit) {
565-
block(self, key, _dictionary[key]);
565+
BOOL stop = NO;
566+
block(self, key, _dictionary[key], &stop);
567+
if (stop)
568+
break;
566569
}
567570
}
568571
[self unlock];
@@ -827,7 +830,12 @@ - (void)removeAllObjects:(nullable PINMemoryCacheBlock)block
827830

828831
- (void)enumerateObjectsWithBlock:(PINMemoryCacheObjectBlock)block completionBlock:(nullable PINMemoryCacheBlock)completionBlock
829832
{
830-
[self enumerateObjectsWithBlockAsync:block completionBlock:completionBlock];
833+
[self enumerateObjectsWithBlockAsync:^(id<PINCaching> _Nonnull cache, NSString * _Nonnull key, id _Nullable object, BOOL * _Nonnull stop) {
834+
if ([cache isKindOfClass:[PINMemoryCache class]]) {
835+
PINMemoryCache *memoryCache = (PINMemoryCache *)cache;
836+
block(memoryCache, key, object);
837+
}
838+
} completionBlock:completionBlock];
831839
}
832840

833841
@end

Tests/PINCacheTests.m

+6-6
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,7 @@ - (void)testMemoryCacheEnumerationWithWarning
503503
__block NSUInteger enumCount = 0;
504504

505505
self.cache.memoryCache.didReceiveMemoryWarningBlock = ^(PINMemoryCache *cache) {
506-
[cache enumerateObjectsWithBlockAsync:^(PINMemoryCache *cache, NSString *key, id object) {
506+
[cache enumerateObjectsWithBlockAsync:^(PINMemoryCache *cache, NSString *key, id object, BOOL *stop) {
507507
@synchronized (self) {
508508
enumCount++;
509509
}
@@ -543,7 +543,7 @@ - (void)testDiskCacheEnumeration
543543

544544
__block NSUInteger enumCount = 0;
545545

546-
[self.cache.diskCache enumerateObjectsWithBlockAsync:^(NSString *key, NSURL *fileURL) {
546+
[self.cache.diskCache enumerateObjectsWithBlockAsync:^(NSString *key, NSURL *fileURL, BOOL *stop) {
547547
@synchronized (self) {
548548
enumCount++;
549549
}
@@ -798,14 +798,14 @@ - (void)_testTTLCacheObjectEnumeration {
798798
// With the TTL cache enabled, we expect enumerating over the caches to yield 0 objects
799799
NSUInteger expectedObjCount = 0;
800800
__block NSUInteger objCount = 0;
801-
[self.cache.diskCache enumerateObjectsWithBlock:^(NSString * _Nonnull key, NSURL * _Nullable fileURL) {
801+
[self.cache.diskCache enumerateObjectsWithBlock:^(NSString * _Nonnull key, NSURL * _Nullable fileURL, BOOL *stop) {
802802
objCount++;
803803
}];
804804

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

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

@@ -824,14 +824,14 @@ - (void)_testTTLCacheObjectEnumeration {
824824
// 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
825825
expectedObjCount = 1;
826826
objCount = 0;
827-
[self.cache.diskCache enumerateObjectsWithBlock:^(NSString * _Nonnull key, NSURL * _Nullable fileURL) {
827+
[self.cache.diskCache enumerateObjectsWithBlock:^(NSString * _Nonnull key, NSURL * _Nullable fileURL, BOOL *stop) {
828828
objCount++;
829829
}];
830830

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

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

0 commit comments

Comments
 (0)