//
|
// YYDiskCache.h
|
// YYCache <https://github.com/ibireme/YYCache>
|
//
|
// Created by ibireme on 15/2/11.
|
// Copyright (c) 2015 ibireme.
|
//
|
// This source code is licensed under the MIT-style license found in the
|
// LICENSE file in the root directory of this source tree.
|
//
|
|
#import <Foundation/Foundation.h>
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
/**
|
YYDiskCache is a thread-safe cache that stores key-value pairs backed by SQLite
|
and file system (similar to NSURLCache's disk cache).
|
|
YYDiskCache has these features:
|
|
* It use LRU (least-recently-used) to remove objects.
|
* It can be controlled by cost, count, and age.
|
* It can be configured to automatically evict objects when there's no free disk space.
|
* It can automatically decide the storage type (sqlite/file) for each object to get
|
better performance.
|
|
You may compile the latest version of sqlite and ignore the libsqlite3.dylib in
|
iOS system to get 2x~4x speed up.
|
*/
|
@interface YYDiskCache : NSObject
|
|
#pragma mark - Attribute
|
///=============================================================================
|
/// @name Attribute
|
///=============================================================================
|
|
/** The name of the cache. Default is nil. */
|
@property (nullable, copy) NSString *name;
|
|
/** The path of the cache (read-only). */
|
@property (readonly) NSString *path;
|
|
/**
|
If the object's data size (in bytes) is larger than this value, then object will
|
be stored as a file, otherwise the object will be stored in sqlite.
|
|
0 means all objects will be stored as separated files, NSUIntegerMax means all
|
objects will be stored in sqlite.
|
|
The default value is 20480 (20KB).
|
*/
|
@property (readonly) NSUInteger inlineThreshold;
|
|
/**
|
If this block is not nil, then the block will be used to archive object instead
|
of NSKeyedArchiver. You can use this block to support the objects which do not
|
conform to the `NSCoding` protocol.
|
|
The default value is nil.
|
*/
|
@property (nullable, copy) NSData *(^customArchiveBlock)(id object);
|
|
/**
|
If this block is not nil, then the block will be used to unarchive object instead
|
of NSKeyedUnarchiver. You can use this block to support the objects which do not
|
conform to the `NSCoding` protocol.
|
|
The default value is nil.
|
*/
|
@property (nullable, copy) id (^customUnarchiveBlock)(NSData *data);
|
|
/**
|
When an object needs to be saved as a file, this block will be invoked to generate
|
a file name for a specified key. If the block is nil, the cache use md5(key) as
|
default file name.
|
|
The default value is nil.
|
*/
|
@property (nullable, copy) NSString *(^customFileNameBlock)(NSString *key);
|
|
|
|
#pragma mark - Limit
|
///=============================================================================
|
/// @name Limit
|
///=============================================================================
|
|
/**
|
The maximum number of objects the cache should hold.
|
|
@discussion The default value is NSUIntegerMax, which means no limit.
|
This is not a strict limit — if the cache goes over the limit, some objects in the
|
cache could be evicted later in background queue.
|
*/
|
@property NSUInteger countLimit;
|
|
/**
|
The maximum total cost that the cache can hold before it starts evicting objects.
|
|
@discussion The default value is NSUIntegerMax, which means no limit.
|
This is not a strict limit — if the cache goes over the limit, some objects in the
|
cache could be evicted later in background queue.
|
*/
|
@property NSUInteger costLimit;
|
|
/**
|
The maximum expiry time of objects in cache.
|
|
@discussion The default value is DBL_MAX, which means no limit.
|
This is not a strict limit — if an object goes over the limit, the objects could
|
be evicted later in background queue.
|
*/
|
@property NSTimeInterval ageLimit;
|
|
/**
|
The minimum free disk space (in bytes) which the cache should kept.
|
|
@discussion The default value is 0, which means no limit.
|
If the free disk space is lower than this value, the cache will remove objects
|
to free some disk space. This is not a strict limit—if the free disk space goes
|
over the limit, the objects could be evicted later in background queue.
|
*/
|
@property NSUInteger freeDiskSpaceLimit;
|
|
/**
|
The auto trim check time interval in seconds. Default is 60 (1 minute).
|
|
@discussion The cache holds an internal timer to check whether the cache reaches
|
its limits, and if the limit is reached, it begins to evict objects.
|
*/
|
@property NSTimeInterval autoTrimInterval;
|
|
/**
|
Set `YES` to enable error logs for debug.
|
*/
|
@property BOOL errorLogsEnabled;
|
|
#pragma mark - Initializer
|
///=============================================================================
|
/// @name Initializer
|
///=============================================================================
|
- (instancetype)init UNAVAILABLE_ATTRIBUTE;
|
+ (instancetype)new UNAVAILABLE_ATTRIBUTE;
|
|
/**
|
Create a new cache based on the specified path.
|
|
@param path Full path of a directory in which the cache will write data.
|
Once initialized you should not read and write to this directory.
|
|
@return A new cache object, or nil if an error occurs.
|
|
@warning If the cache instance for the specified path already exists in memory,
|
this method will return it directly, instead of creating a new instance.
|
*/
|
- (nullable instancetype)initWithPath:(NSString *)path;
|
|
/**
|
The designated initializer.
|
|
@param path Full path of a directory in which the cache will write data.
|
Once initialized you should not read and write to this directory.
|
|
@param threshold The data store inline threshold in bytes. If the object's data
|
size (in bytes) is larger than this value, then object will be stored as a
|
file, otherwise the object will be stored in sqlite. 0 means all objects will
|
be stored as separated files, NSUIntegerMax means all objects will be stored
|
in sqlite. If you don't know your object's size, 20480 is a good choice.
|
After first initialized you should not change this value of the specified path.
|
|
@return A new cache object, or nil if an error occurs.
|
|
@warning If the cache instance for the specified path already exists in memory,
|
this method will return it directly, instead of creating a new instance.
|
*/
|
- (nullable instancetype)initWithPath:(NSString *)path
|
inlineThreshold:(NSUInteger)threshold NS_DESIGNATED_INITIALIZER;
|
|
|
#pragma mark - Access Methods
|
///=============================================================================
|
/// @name Access Methods
|
///=============================================================================
|
|
/**
|
Returns a boolean value that indicates whether a given key is in cache.
|
This method may blocks the calling thread until file read finished.
|
|
@param key A string identifying the value. If nil, just return NO.
|
@return Whether the key is in cache.
|
*/
|
- (BOOL)containsObjectForKey:(NSString *)key;
|
|
/**
|
Returns a boolean value with the block that indicates whether a given key is in cache.
|
This method returns immediately and invoke the passed block in background queue
|
when the operation finished.
|
|
@param key A string identifying the value. If nil, just return NO.
|
@param block A block which will be invoked in background queue when finished.
|
*/
|
- (void)containsObjectForKey:(NSString *)key withBlock:(void(^)(NSString *key, BOOL contains))block;
|
|
/**
|
Returns the value associated with a given key.
|
This method may blocks the calling thread until file read finished.
|
|
@param key A string identifying the value. If nil, just return nil.
|
@return The value associated with key, or nil if no value is associated with key.
|
*/
|
- (nullable id<NSCoding>)objectForKey:(NSString *)key;
|
|
/**
|
Returns the value associated with a given key.
|
This method returns immediately and invoke the passed block in background queue
|
when the operation finished.
|
|
@param key A string identifying the value. If nil, just return nil.
|
@param block A block which will be invoked in background queue when finished.
|
*/
|
- (void)objectForKey:(NSString *)key withBlock:(void(^)(NSString *key, id<NSCoding> _Nullable object))block;
|
|
/**
|
Sets the value of the specified key in the cache.
|
This method may blocks the calling thread until file write finished.
|
|
@param object The object to be stored in the cache. If nil, it calls `removeObjectForKey:`.
|
@param key The key with which to associate the value. If nil, this method has no effect.
|
*/
|
- (void)setObject:(nullable id<NSCoding>)object forKey:(NSString *)key;
|
|
/**
|
Sets the value of the specified key in the cache.
|
This method returns immediately and invoke the passed block in background queue
|
when the operation finished.
|
|
@param object The object to be stored in the cache. If nil, it calls `removeObjectForKey:`.
|
@param block A block which will be invoked in background queue when finished.
|
*/
|
- (void)setObject:(nullable id<NSCoding>)object forKey:(NSString *)key withBlock:(void(^)(void))block;
|
|
/**
|
Removes the value of the specified key in the cache.
|
This method may blocks the calling thread until file delete finished.
|
|
@param key The key identifying the value to be removed. If nil, this method has no effect.
|
*/
|
- (void)removeObjectForKey:(NSString *)key;
|
|
/**
|
Removes the value of the specified key in the cache.
|
This method returns immediately and invoke the passed block in background queue
|
when the operation finished.
|
|
@param key The key identifying the value to be removed. If nil, this method has no effect.
|
@param block A block which will be invoked in background queue when finished.
|
*/
|
- (void)removeObjectForKey:(NSString *)key withBlock:(void(^)(NSString *key))block;
|
|
/**
|
Empties the cache.
|
This method may blocks the calling thread until file delete finished.
|
*/
|
- (void)removeAllObjects;
|
|
/**
|
Empties the cache.
|
This method returns immediately and invoke the passed block in background queue
|
when the operation finished.
|
|
@param block A block which will be invoked in background queue when finished.
|
*/
|
- (void)removeAllObjectsWithBlock:(void(^)(void))block;
|
|
/**
|
Empties the cache with block.
|
This method returns immediately and executes the clear operation with block in background.
|
|
@warning You should not send message to this instance in these blocks.
|
@param progress This block will be invoked during removing, pass nil to ignore.
|
@param end This block will be invoked at the end, pass nil to ignore.
|
*/
|
- (void)removeAllObjectsWithProgressBlock:(nullable void(^)(int removedCount, int totalCount))progress
|
endBlock:(nullable void(^)(BOOL error))end;
|
|
|
/**
|
Returns the number of objects in this cache.
|
This method may blocks the calling thread until file read finished.
|
|
@return The total objects count.
|
*/
|
- (NSInteger)totalCount;
|
|
/**
|
Get the number of objects in this cache.
|
This method returns immediately and invoke the passed block in background queue
|
when the operation finished.
|
|
@param block A block which will be invoked in background queue when finished.
|
*/
|
- (void)totalCountWithBlock:(void(^)(NSInteger totalCount))block;
|
|
/**
|
Returns the total cost (in bytes) of objects in this cache.
|
This method may blocks the calling thread until file read finished.
|
|
@return The total objects cost in bytes.
|
*/
|
- (NSInteger)totalCost;
|
|
/**
|
Get the total cost (in bytes) of objects in this cache.
|
This method returns immediately and invoke the passed block in background queue
|
when the operation finished.
|
|
@param block A block which will be invoked in background queue when finished.
|
*/
|
- (void)totalCostWithBlock:(void(^)(NSInteger totalCost))block;
|
|
|
#pragma mark - Trim
|
///=============================================================================
|
/// @name Trim
|
///=============================================================================
|
|
/**
|
Removes objects from the cache use LRU, until the `totalCount` is below the specified value.
|
This method may blocks the calling thread until operation finished.
|
|
@param count The total count allowed to remain after the cache has been trimmed.
|
*/
|
- (void)trimToCount:(NSUInteger)count;
|
|
/**
|
Removes objects from the cache use LRU, until the `totalCount` is below the specified value.
|
This method returns immediately and invoke the passed block in background queue
|
when the operation finished.
|
|
@param count The total count allowed to remain after the cache has been trimmed.
|
@param block A block which will be invoked in background queue when finished.
|
*/
|
- (void)trimToCount:(NSUInteger)count withBlock:(void(^)(void))block;
|
|
/**
|
Removes objects from the cache use LRU, until the `totalCost` is below the specified value.
|
This method may blocks the calling thread until operation finished.
|
|
@param cost The total cost allowed to remain after the cache has been trimmed.
|
*/
|
- (void)trimToCost:(NSUInteger)cost;
|
|
/**
|
Removes objects from the cache use LRU, until the `totalCost` is below the specified value.
|
This method returns immediately and invoke the passed block in background queue
|
when the operation finished.
|
|
@param cost The total cost allowed to remain after the cache has been trimmed.
|
@param block A block which will be invoked in background queue when finished.
|
*/
|
- (void)trimToCost:(NSUInteger)cost withBlock:(void(^)(void))block;
|
|
/**
|
Removes objects from the cache use LRU, until all expiry objects removed by the specified value.
|
This method may blocks the calling thread until operation finished.
|
|
@param age The maximum age of the object.
|
*/
|
- (void)trimToAge:(NSTimeInterval)age;
|
|
/**
|
Removes objects from the cache use LRU, until all expiry objects removed by the specified value.
|
This method returns immediately and invoke the passed block in background queue
|
when the operation finished.
|
|
@param age The maximum age of the object.
|
@param block A block which will be invoked in background queue when finished.
|
*/
|
- (void)trimToAge:(NSTimeInterval)age withBlock:(void(^)(void))block;
|
|
|
#pragma mark - Extended Data
|
///=============================================================================
|
/// @name Extended Data
|
///=============================================================================
|
|
/**
|
Get extended data from an object.
|
|
@discussion See 'setExtendedData:toObject:' for more information.
|
|
@param object An object.
|
@return The extended data.
|
*/
|
+ (nullable NSData *)getExtendedDataFromObject:(id)object;
|
|
/**
|
Set extended data to an object.
|
|
@discussion You can set any extended data to an object before you save the object
|
to disk cache. The extended data will also be saved with this object. You can get
|
the extended data later with "getExtendedDataFromObject:".
|
|
@param extendedData The extended data (pass nil to remove).
|
@param object The object.
|
*/
|
+ (void)setExtendedData:(nullable NSData *)extendedData toObject:(id)object;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|