123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413 |
- //
- // YYDiskCache.h
- // YYKit <https://github.com/ibireme/YYKit>
- //
- // 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
|