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

Add ability to set an object level TTL #209

Merged
merged 39 commits into from
May 11, 2018
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
a08b66c
Add new `ageLimit` setters in PINCaching protocol
mjlazar Dec 5, 2017
3d7714e
Implement `ageLimit` methods in PINDiskCache
mjlazar Dec 5, 2017
d1c796a
Implement `ageLimit` methods in PINMemoryCache
mjlazar Dec 5, 2017
f7d6d3c
Implement `ageLimit` methods in PINCache
mjlazar Dec 5, 2017
336d401
Honor `ageLimit` (at both cache and object level) in -[PINDiskCache c…
mjlazar Dec 5, 2017
6be8d22
Honor `ageLimit` (at both cache and object level) in -[PINDiskCache c…
mjlazar Dec 5, 2017
c2dfcd6
Merge branch 'object-level-ttl-override' of github.com:mjlazar/PINCac…
mjlazar Dec 5, 2017
4b05c88
Update CHANGELOG
mjlazar Dec 16, 2017
0d4e71d
Add new NSDate category for swizzling +[NSDate date] in unit tests
mjlazar Feb 16, 2018
d4d7640
Change memory and disk caches to use +[NDate date] instead of -[NSDat…
mjlazar Feb 16, 2018
b4b7ac2
Add unit tests for object-level TTLs
mjlazar Feb 16, 2018
171de47
Update header documentation regarding object-level age limits
mjlazar Feb 16, 2018
723c326
Clear previously set object age limits if setting to zero
mjlazar Feb 16, 2018
06e331c
Add assertions to ttlCache is set to YES if object-level age limits a…
mjlazar Feb 16, 2018
3895432
Update header documentation to describe behavior of overridden object…
mjlazar Feb 16, 2018
a4466b6
Remove `hasAgeLimit` logic
mjlazar Feb 17, 2018
c762a84
Misc cleanup
mjlazar Feb 17, 2018
fd103ca
Handle failure on extended attribute read
mjlazar Feb 17, 2018
fb7694b
Make sure trim methods do not remove objects with overridden age limits
mjlazar Feb 19, 2018
e504b0b
New methods to remove expired objects from cache
mjlazar Feb 19, 2018
24ea58a
Remove expired objects from disk cache on initialization if any objec…
mjlazar Feb 19, 2018
f539d78
Remove expired objects from memory cache on memory warning
mjlazar Feb 19, 2018
a27d755
Fix expiration logic
mjlazar Feb 19, 2018
4b383a5
Add unit test for removeExpiredObjects
mjlazar Feb 19, 2018
662a7cb
Remove assert in -setObject:...
mjlazar Feb 23, 2018
7fa42e3
Call async version of -removeExpiredObjects in -initializeDiskProperties
mjlazar Feb 23, 2018
9c3b33b
Tweaks
mjlazar Feb 23, 2018
7d88344
Merge branch 'master' into object-level-ttl-override
garrettmoon Feb 23, 2018
92e1d59
Fix warnings
mjlazar Feb 24, 2018
71b7fb9
Make ttlCache a readonly property
mjlazar Feb 25, 2018
2d0ae4b
Changes to address feedback from @garrettmoon
mjlazar Mar 17, 2018
6a34a58
Merge branch 'master' into object-level-ttl-override
mjlazar Mar 17, 2018
a47eff1
Merge branch 'master' into object-level-ttl-override
garrettmoon Mar 27, 2018
b5a6640
Changes to address @garrettmoon's feedback
mjlazar Apr 16, 2018
fab908f
Fix indents.
mjlazar Apr 16, 2018
f7216ed
Merge branch 'master' into object-level-ttl-override
mjlazar Apr 19, 2018
60c83aa
Adding additional tests
mjlazar May 8, 2018
2655498
Fix race condition in unit tests
mjlazar May 9, 2018
871f503
Update CHANGELOG
mjlazar May 9, 2018
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 @@ -5,6 +5,7 @@
## 3.0.1 -- Beta 6
- [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)
- [new] Add ability to set an object level TTL: [#209](https://github.com/pinterest/PINCache/pull/209)
- [performance] Improves cache miss performance by ~2 orders of magnitude on device: [#202](https://github.com/pinterest/PINCache/pull/202)
- [performance] Significantly improve startup performance: [#203](https://github.com/pinterest/PINCache/pull/203)

Expand Down
28 changes: 24 additions & 4 deletions Source/PINCache.m
Original file line number Diff line number Diff line change
Expand Up @@ -134,18 +134,28 @@ - (void)setObjectAsync:(id <NSCoding>)object forKey:(NSString *)key completion:(
[self setObjectAsync:object forKey:key withCost:0 completion:block];
}

- (void)setObjectAsync:(id <NSCoding>)object forKey:(NSString *)key withAgeLimit:(NSTimeInterval)ageLimit completion:(PINCacheObjectBlock)block
{
[self setObjectAsync:object forKey:key withCost:0 ageLimit:ageLimit completion:block];
}

- (void)setObjectAsync:(id <NSCoding>)object forKey:(NSString *)key withCost:(NSUInteger)cost completion:(PINCacheObjectBlock)block
{
[self setObjectAsync:object forKey:key withCost:cost ageLimit:0.0 completion:block];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once this lands, I wonder if we could reduce the complexity of everything by changing this line to:
[self setObjectAsync:object forKey:key withCost:cost ageLimit:self.isTTLCache ? self.ageLimit : 0.0 completion:block]

Then we could get rid of any other logic that deals with isTTLCache?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that could certainly be done, but it would have to be in conjunction with some changes to the trim-to-date methods. Since this would essentially set object-level age limits all of the time, we could combine the current trimming logic with the new -removeExpiredObjects logic I'm proposing in this PR.

}

- (void)setObjectAsync:(nonnull id)object forKey:(nonnull NSString *)key withCost:(NSUInteger)cost ageLimit:(NSTimeInterval)ageLimit completion:(nullable PINCacheObjectBlock)block
{
if (!key || !object)
return;

PINOperationGroup *group = [PINOperationGroup asyncOperationGroupWithQueue:_operationQueue];

[group addOperation:^{
[_memoryCache setObject:object forKey:key withCost:cost];
[_memoryCache setObject:object forKey:key withCost:cost ageLimit:ageLimit];
}];
[group addOperation:^{
[_diskCache setObject:object forKey:key];
[_diskCache setObject:object forKey:key withAgeLimit:ageLimit];
}];

if (block) {
Expand Down Expand Up @@ -269,13 +279,23 @@ - (void)setObject:(id <NSCoding>)object forKey:(NSString *)key
[self setObject:object forKey:key withCost:0];
}

- (void)setObject:(id <NSCoding>)object forKey:(NSString *)key withAgeLimit:(NSTimeInterval)ageLimit
{
[self setObject:object forKey:key withCost:0 ageLimit:ageLimit];
}

- (void)setObject:(id <NSCoding>)object forKey:(NSString *)key withCost:(NSUInteger)cost
{
[self setObject:object forKey:key withCost:cost ageLimit:0.0];
}

- (void)setObject:(nullable id)object forKey:(nonnull NSString *)key withCost:(NSUInteger)cost ageLimit:(NSTimeInterval)ageLimit
{
if (!key || !object)
return;

[_memoryCache setObject:object forKey:key withCost:cost];
[_diskCache setObject:object forKey:key];
[_memoryCache setObject:object forKey:key withCost:cost ageLimit:ageLimit];
[_diskCache setObject:object forKey:key withAgeLimit:ageLimit];
}

- (nullable id)objectForKeyedSubscript:(NSString *)key
Expand Down
49 changes: 49 additions & 0 deletions Source/PINCaching.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,18 @@ typedef void (^PINCacheObjectContainmentBlock)(BOOL containsObject);
*/
- (void)setObjectAsync:(id)object forKey:(NSString *)key completion:(nullable PINCacheObjectBlock)block;

/**
Stores an object in the cache for the specified key and the specified age limit. This method returns immediately
and executes the passed block after the object has been stored, potentially in parallel with other blocks
on the <concurrentQueue>.

@param object An object to store in the cache.
@param key A key to associate with the object. This string will be copied.
@param ageLimit The age limit (in seconds) to associate with the object.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe mention 0 being no age limit here and in the other doc headers?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@param block A block to be executed concurrently after the object has been stored, or nil.
*/
- (void)setObjectAsync:(id)object forKey:(NSString *)key withAgeLimit:(NSTimeInterval)ageLimit completion:(nullable PINCacheObjectBlock)block;

/**
Stores an object in the cache for the specified key and the specified memory cost. If the cost causes the total
to go over the <memoryCache.costLimit> the cache is trimmed (oldest objects first). This method returns immediately
Expand All @@ -91,6 +103,20 @@ typedef void (^PINCacheObjectContainmentBlock)(BOOL containsObject);
*/
- (void)setObjectAsync:(id)object forKey:(NSString *)key withCost:(NSUInteger)cost completion:(nullable PINCacheObjectBlock)block;

/**
Stores an object in the cache for the specified key and the specified memory cost and age limit. If the cost causes the total
to go over the <memoryCache.costLimit> the cache is trimmed (oldest objects first). This method returns immediately
and executes the passed block after the object has been stored, potentially in parallel with other blocks
on the <concurrentQueue>.

@param object An object to store in the cache.
@param key A key to associate with the object. This string will be copied.
@param cost An amount to add to the <memoryCache.totalCost>.
@param ageLimit The age limit (in seconds) to associate with the object.
@param block A block to be executed concurrently after the object has been stored, or nil.
*/
- (void)setObjectAsync:(id)object forKey:(NSString *)key withCost:(NSUInteger)cost ageLimit:(NSTimeInterval)ageLimit completion:(nullable PINCacheObjectBlock)block;

/**
Removes the object for the specified key. This method returns immediately and executes the passed
block after the object has been removed, potentially in parallel with other blocks on the <concurrentQueue>.
Expand Down Expand Up @@ -150,6 +176,17 @@ typedef void (^PINCacheObjectContainmentBlock)(BOOL containsObject);
*/
- (void)setObject:(nullable id)object forKey:(NSString *)key;

/**
Stores an object in the cache for the specified key and age limit. This method blocks the calling thread until the
object has been set. Uses a lock to achieve synchronicity on the disk cache.

@see setObjectAsync:forKey:completion:
@param object An object to store in the cache.
@param key A key to associate with the object. This string will be copied.
@param ageLimit The age limit (in seconds) to associate with the object.
*/
- (void)setObject:(nullable id)object forKey:(NSString *)key withAgeLimit:(NSTimeInterval)ageLimit;

/**
Stores an object in the cache for the specified key and the specified memory cost. If the cost causes the total
to go over the <memoryCache.costLimit> the cache is trimmed (oldest objects first). This method blocks the calling thread
Expand All @@ -161,6 +198,18 @@ typedef void (^PINCacheObjectContainmentBlock)(BOOL containsObject);
*/
- (void)setObject:(nullable id)object forKey:(NSString *)key withCost:(NSUInteger)cost;

/**
Stores an object in the cache for the specified key and the specified memory cost and age limit. If the cost causes the total
to go over the <memoryCache.costLimit> the cache is trimmed (oldest objects first). This method blocks the calling thread
until the object has been stored.

@param object An object to store in the cache.
@param key A key to associate with the object. This string will be copied.
@param cost An amount to add to the <memoryCache.totalCost>.
@param ageLimit The age limit (in seconds) to associate with the object.
*/
- (void)setObject:(nullable id)object forKey:(NSString *)key withCost:(NSUInteger)cost ageLimit:(NSTimeInterval)ageLimit;

/**
Removes the object for the specified key. This method blocks the calling thread until the object
has been removed.
Expand Down
42 changes: 42 additions & 0 deletions Source/PINDiskCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,14 @@ NS_ASSUME_NONNULL_BEGIN
@class PINDiskCache;
@class PINOperationQueue;

extern NSString * const PINDiskCacheErrorDomain;
extern NSErrorUserInfoKey const PINDiskCacheErrorWriteFailureCodeKey;
extern NSString * const PINDiskCachePrefix;

typedef NS_ENUM(NSInteger, PINDiskCacheError) {
PINDiskCacheErrorWriteFailure = -1000,
};

/**
A callback block which provides the cache, key and object as arguments
*/
Expand Down Expand Up @@ -350,6 +356,17 @@ PIN_SUBCLASSING_RESTRICTED
*/
- (void)setObjectAsync:(id <NSCoding>)object forKey:(NSString *)key completion:(nullable PINDiskCacheObjectBlock)block;

/**
Stores an object in the cache for the specified key and age limit. This method returns immediately and executes the
passed block as soon as the object has been stored.

@param object An object to store in the cache.
@param key A key to associate with the object. This string will be copied.
@param ageLimit The age limit (in seconds) to associate with the object.
@param block A block to be executed serially after the object has been stored, or nil.
*/
- (void)setObjectAsync:(id <NSCoding>)object forKey:(NSString *)key withAgeLimit:(NSTimeInterval)ageLimit completion:(nullable PINDiskCacheObjectBlock)block;

/**
Stores an object in the cache for the specified key and the specified memory cost. If the cost causes the total
to go over the <memoryCache.costLimit> the cache is trimmed (oldest objects first). This method returns immediately
Expand All @@ -363,6 +380,20 @@ PIN_SUBCLASSING_RESTRICTED
*/
- (void)setObjectAsync:(id <NSCoding>)object forKey:(NSString *)key withCost:(NSUInteger)cost completion:(nullable PINCacheObjectBlock)block;

/**
Stores an object in the cache for the specified key and the specified memory cost and age limit. If the cost causes the total
to go over the <memoryCache.costLimit> the cache is trimmed (oldest objects first). This method returns immediately
and executes the passed block after the object has been stored, potentially in parallel with other blocks
on the <concurrentQueue>.

@param object An object to store in the cache.
@param key A key to associate with the object. This string will be copied.
@param cost An amount to add to the <memoryCache.totalCost>.
@param ageLimit The age limit (in seconds) to associate with the object.
@param block A block to be executed concurrently after the object has been stored, or nil.
*/
- (void)setObjectAsync:(id <NSCoding>)object forKey:(NSString *)key withCost:(NSUInteger)cost ageLimit:(NSTimeInterval)ageLimit completion:(nullable PINCacheObjectBlock)block;

/**
Removes the object for the specified key. This method returns immediately and executes the passed block
as soon as the object has been removed.
Expand Down Expand Up @@ -451,6 +482,17 @@ PIN_SUBCLASSING_RESTRICTED
*/
- (void)setObject:(nullable id <NSCoding>)object forKey:(NSString *)key;

/**
Stores an object in the cache for the specified key and age limit. This method blocks the calling thread until
the object has been stored.

@see setObjectAsync:forKey:completion:
@param object An object to store in the cache.
@param key A key to associate with the object. This string will be copied.
@param ageLimit The age limit (in seconds) to associate with the object.
*/
- (void)setObject:(nullable id <NSCoding>)object forKey:(NSString *)key withAgeLimit:(NSTimeInterval)ageLimit;

/**
Removes objects from the cache, largest first, until the cache is equal to or smaller than the
specified byteCount. This method blocks the calling thread until the cache has been trimmed.
Expand Down
Loading