Merge pull request #2417 from dreampiggy/feature_disk_cache_migration_from_4.x

Feature disk cache migration from 4.x
This commit is contained in:
Bogdan Poplauschi 2018-08-08 12:47:20 +03:00 committed by GitHub
commit 83b5d22a56
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 83 additions and 3 deletions

View File

@ -104,4 +104,15 @@
- (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

View File

@ -228,6 +228,39 @@
return [path stringByAppendingPathComponent:filename];
}
- (void)moveCacheDirectoryFromPath:(nonnull NSString *)srcPath toPath:(nonnull NSString *)dstPath {
NSParameterAssert(srcPath);
NSParameterAssert(dstPath);
// Check if old path is equal to new path
if ([srcPath isEqualToString:dstPath]) {
return;
}
BOOL isDirectory;
// Check if old path is directory
if (![self.fileManager fileExistsAtPath:srcPath isDirectory:&isDirectory] || !isDirectory) {
return;
}
// Check if new path is directory
if (![self.fileManager fileExistsAtPath:dstPath isDirectory:&isDirectory] || !isDirectory) {
if (!isDirectory) {
// New path is not directory, remove file
[self.fileManager removeItemAtPath:dstPath error:nil];
}
// New directory does not exist, rename directory
[self.fileManager moveItemAtPath:srcPath toPath:dstPath error:nil];
} else {
// New directory exist, merge the files
NSDirectoryEnumerator *dirEnumerator = [self.fileManager enumeratorAtPath:srcPath];
NSString *file;
while ((file = [dirEnumerator nextObject])) {
// Don't handle error, just try to move.
[self.fileManager moveItemAtPath:[srcPath stringByAppendingPathComponent:file] toPath:[dstPath stringByAppendingPathComponent:file] error:nil];
}
// Remove the old path
[self.fileManager removeItemAtPath:srcPath error:nil];
}
}
#pragma mark - Hash
static inline NSString * _Nullable SDDiskCacheFileNameForKey(NSString * _Nullable key) {

View File

@ -86,6 +86,9 @@
NSAssert([config.diskCacheClass conformsToProtocol:@protocol(SDDiskCache)], @"Custom disk cache class must conform to `SDDiskCache` protocol");
_diskCache = [[config.diskCacheClass alloc] initWithCachePath:_diskCachePath config:_config];
// Check and migrate disk cache directory if need
[self migrateDiskCacheDirectory];
#if SD_UIKIT
// Subscribe to app events
@ -123,9 +126,22 @@
return [self.diskCache cachePathForKey:key];
}
- (nullable NSString *)makeDiskCachePath:(nonnull NSString*)fullNamespace {
- (nullable NSString *)makeDiskCachePath:(nonnull NSString *)fullNamespace {
NSArray<NSString *> *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
return [paths[0] stringByAppendingPathComponent:fullNamespace];
return [paths.firstObject stringByAppendingPathComponent:fullNamespace];
}
- (void)migrateDiskCacheDirectory {
if ([self.diskCache isKindOfClass:[SDDiskCache class]]) {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSString *newDefaultPath = [[self makeDiskCachePath:@"default"] stringByAppendingPathComponent:@"com.hackemist.SDImageCache.default"];
NSString *oldDefaultPath = [[self makeDiskCachePath:@"default"] stringByAppendingPathComponent:@"com.hackemist.SDWebImageCache.default"];
dispatch_async(self.ioQueue, ^{
[((SDDiskCache *)self.diskCache) moveCacheDirectoryFromPath:oldDefaultPath toPath:newDefaultPath];
});
});
}
}
#pragma mark - Store Ops

View File

@ -21,7 +21,8 @@ static NSString *kTestImageKeyPNG = @"TestImageKey.png";
@end
@interface SDImageCacheTests : SDTestCase
@interface SDImageCacheTests : SDTestCase <NSFileManagerDelegate>
@end
@implementation SDImageCacheTests
@ -359,6 +360,25 @@ static NSString *kTestImageKeyPNG = @"TestImageKey.png";
expect([diskCache isKindOfClass:[SDWebImageTestDiskCache class]]).to.beTruthy();
}
- (void)test44DiskCacheMigrationFromOldVersion {
SDImageCacheConfig *config = [[SDImageCacheConfig alloc] init];
NSFileManager *fileManager = [[NSFileManager alloc] init];
config.fileManager = fileManager;
// Fake to store a.png into old path
NSString *newDefaultPath = [[self makeDiskCachePath:@"default"] stringByAppendingPathComponent:@"com.hackemist.SDImageCache.default"];
NSString *oldDefaultPath = [[self makeDiskCachePath:@"default"] stringByAppendingPathComponent:@"com.hackemist.SDWebImageCache.default"];
[fileManager createDirectoryAtPath:oldDefaultPath withIntermediateDirectories:YES attributes:nil error:nil];
[fileManager createFileAtPath:[oldDefaultPath stringByAppendingPathComponent:@"a.png"] contents:[NSData dataWithContentsOfFile:[self testPNGPath]] attributes:nil];
// Call migration
SDDiskCache *diskCache = [[SDDiskCache alloc] initWithCachePath:newDefaultPath config:config];
[diskCache moveCacheDirectoryFromPath:oldDefaultPath toPath:newDefaultPath];
// Expect a.png into new path
BOOL exist = [fileManager fileExistsAtPath:[newDefaultPath stringByAppendingPathComponent:@"a.png"]];
expect(exist).beTruthy();
}
#pragma mark - SDImageCache & SDImageCachesManager
- (void)test50SDImageCacheQueryOp {
XCTestExpectation *expectation = [self expectationWithDescription:@"SDImageCache query op works"];