Repository: SDWebImage/SDWebImage
File: SDWebImage/SDDiskCache.h (C/C++)

Code before:
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

#import "SDWebImageCompat.h"

@class SDImageCacheConfig;
// A protocol to allow custom disk cache used in SDImageCache.
@protocol SDDiskCache <NSObject>

// All of these method are called from the same global queue to avoid blocking on main queue and thread-safe problem. But it's also recommend to ensure thread-safe yourself using lock or other ways.
@required
/**
 Create a new disk cache based on the specified path.
 
 @param cachePath Full path of a directory in which the cache will write data.
 Once initialized you should not read and write to this directory.
 @param config The cache config to be used to create the cache.
 
 @return A new cache object, or nil if an error occurs.
 */
- (nullable instancetype)initWithCachePath:(nonnull NSString *)cachePath config:(nonnull SDImageCacheConfig *)config;

/**
 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 data. If nil, just return NO.
 @return Whether the key is in cache.
 */
- (BOOL)containsDataForKey:(nonnull NSString *)key;

/**
 Returns the data associated with a given key.
 This method may blocks the calling thread until file read finished.
 
 @param key A string identifying the data. If nil, just return nil.
 @return The value associated with key, or nil if no value is associated with key.
 */
- (nullable NSData *)dataForKey:(nonnull NSString *)key;

/**
 Sets the value of the specified key in the cache.
 This method may blocks the calling thread until file write finished.
 
 @param data The data to be stored in the cache.
 @param key    The key with which to associate the value. If nil, this method has no effect.
 */
- (void)setData:(nullable NSData *)data forKey:(nonnull NSString *)key;

/**
 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)removeDataForKey:(nonnull NSString *)key;

/**
 Empties the cache.
 This method may blocks the calling thread until file delete finished.
 */
- (void)removeAllData;

/**
 Removes the expired data from the cache. You can choose the data to remove base on `ageLimit`, `countLimit` and `sizeLimit` options.
 */
- (void)removeExpiredData;

/**
 The cache path for key

 @param key A string identifying the value
 @return The cache path for key. Or nil if the key can not associate to a path
 */
- (nullable NSString *)cachePathForKey:(nonnull NSString *)key;

/**
 Returns the number of data in this cache.
 This method may blocks the calling thread until file read finished.
 
 @return The total data count.
 */
- (NSInteger)totalCount;

/**
 Returns the total size (in bytes) of data in this cache.
 This method may blocks the calling thread until file read finished.
 
 @return The total data size in bytes.
 */
- (NSInteger)totalSize;

@end

// The built-in disk cache
@interface SDDiskCache : NSObject <SDDiskCache>

@property (nonatomic, strong, readonly, nonnull) SDImageCacheConfig *config;

- (nonnull instancetype)init NS_UNAVAILABLE;

@end


Review comment (performance):
@dreampiggy I updated the `PR` I make. The good thing is we reached the decision for the most of the code. The only difference is wether we should make this method public. 

If you decide to make it public and make it for common use, I think maybe can make some changes:
1. What if `dstPath` not exist, and `dstPath` has non-existent parent directories, your code can't handle correctly.
2. If `dstPath` is not a directory but exist, should we need to delete the file directly? maybe it needs to think a bit more.
3.  For the merge operation, what if the `dstFile` exist? for the current code, it would raise the error and skip this movement of file, it's the user want? Can we provide overwrite operation?
4. Should we need to provide any feedback, like move successful or error parameter to the user?
5. The movement operation maybe not related with the `SDDiskCahce`, it only use `filemanager` of `SDDiskCache`, I think it maybe more suitable for `NSFileManager` category.

Otherwise, if you think we can make it private, I think my `PR` can handle very well, we only handle our own default cache migration.
At last, it's up to you to make the decision, I'm ok for these two `PR`s.

Code after:
 Returns the total size (in bytes) of data in this cache.
 This method may blocks the calling thread until file read finished.
 
 @return The total data size in bytes.
 */
- (NSInteger)totalSize;

@end

// The built-in disk cache
@interface SDDiskCache : NSObject <SDDiskCache>

@property (nonatomic, strong, readonly, nonnull) SDImageCacheConfig *config;

- (nonnull instancetype)init NS_UNAVAILABLE;

/**
 Move the cache directory from old location to new location, the old location will be removed after finish.
 If the old location does not exist, does nothing.
 If the new location does not exist, only do a movement of directory.
 If the new location does exist, will move and merge the files from old location.

 @param srcPath old location of cache directory
 @param dstPath new location of cache directory
 */
- (void)moveCacheDirectoryFromPath:(nonnull NSString *)srcPath toPath:(nonnull NSString *)dstPath;

@end