Skip to content

Commit

Permalink
Merge pull request #500 from kean/fix-499
Browse files Browse the repository at this point in the history
Fix data cache overwrite issue
  • Loading branch information
kean authored Aug 18, 2021
2 parents 3bd3a17 + b9bf227 commit facf483
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 8 deletions.
18 changes: 10 additions & 8 deletions Sources/Internal/Tasks/TaskLoadImage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ final class TaskLoadImage: ImagePipelineTask<ImageResponse> {

private func didDecodeCachedData(_ response: ImageResponse?) {
if let response = response {
decompressImage(response, isCompleted: true)
decompressImage(response, isCompleted: true, isFromDiskCache: true)
} else {
fetchImage()
}
Expand Down Expand Up @@ -187,14 +187,14 @@ final class TaskLoadImage: ImagePipelineTask<ImageResponse> {
// MARK: Decompression

#if os(macOS)
private func decompressImage(_ response: ImageResponse, isCompleted: Bool) {
storeImageInCaches(response)
private func decompressImage(_ response: ImageResponse, isCompleted: Bool, isFromDiskCache: Bool = false) {
storeImageInCaches(response, isFromDiskCache: isFromDiskCache)
send(value: response, isCompleted: isCompleted) // There is no decompression on macOS
}
#else
private func decompressImage(_ response: ImageResponse, isCompleted: Bool) {
private func decompressImage(_ response: ImageResponse, isCompleted: Bool, isFromDiskCache: Bool = false) {
guard isDecompressionNeeded(for: response) else {
storeImageInCaches(response)
storeImageInCaches(response, isFromDiskCache: isFromDiskCache)
send(value: response, isCompleted: isCompleted)
return
}
Expand All @@ -215,7 +215,7 @@ final class TaskLoadImage: ImagePipelineTask<ImageResponse> {
}

self.async {
self.storeImageInCaches(response)
self.storeImageInCaches(response, isFromDiskCache: isFromDiskCache)
self.send(value: response, isCompleted: isCompleted)
}
}
Expand All @@ -230,14 +230,16 @@ final class TaskLoadImage: ImagePipelineTask<ImageResponse> {

// MARK: Caching

private func storeImageInCaches(_ response: ImageResponse) {
private func storeImageInCaches(_ response: ImageResponse, isFromDiskCache: Bool) {
guard subscribers.contains(where: { $0 is ImageTask }) else {
return // Only store for direct requests
}
// Memory cache (ImageCaching)
pipeline.cache[request] = response.container
// Disk cache (DataCaching)
storeImageInDataCache(response)
if !isFromDiskCache {
storeImageInDataCache(response)
}
}

private func storeImageInDataCache(_ response: ImageResponse) {
Expand Down
25 changes: 25 additions & 0 deletions Tests/ImagePipelineTests/ImagePipelineImageCacheTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,31 @@ class ImagePipelineCacheLayerPriorityTests: XCTestCase {
XCTAssertEqual(dataLoader.createdTaskCount, 0)
}

func testPolicyStoreEncodedImagesGivenDataAlreadyStored() {
// GIVEN
pipeline = pipeline.reconfigured {
$0.dataCachePolicy = .storeEncodedImages
}

let request = ImageRequest(url: Test.url, processors: [MockImageProcessor(id: "p1")])
pipeline.cache.storeCachedImage(Test.container, for: request, caches: [.disk])
dataCache.resetCounters()
imageCache.resetCounters()

// WHEN
let record = expect(pipeline).toLoadImage(with: request)
wait()
XCTAssertNotNil(record.image)
XCTAssertEqual(record.response?.cacheType, .disk)

// THEN
XCTAssertEqual(imageCache.readCount, 1)
XCTAssertEqual(imageCache.writeCount, 1)
XCTAssertEqual(dataCache.readCount, 1)
XCTAssertEqual(dataCache.writeCount, 0)
XCTAssertEqual(dataLoader.createdTaskCount, 0)
}

// MARK: ImageRequest.Options

func testGivenOriginalImageInDiskCacheAndDiskReadsDisabled() {
Expand Down
5 changes: 5 additions & 0 deletions Tests/MockDataCache.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ final class MockDataCache: DataCaching {
var readCount = 0
var writeCount = 0

func resetCounters() {
readCount = 0
writeCount = 0
}

func cachedData(for key: String) -> Data? {
readCount += 1
return store[key]
Expand Down
5 changes: 5 additions & 0 deletions Tests/MockImageCache.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ class MockImageCache: ImageCaching {

init() {}

func resetCounters() {
readCount = 0
writeCount = 0
}

subscript(key: ImageCacheKey) -> ImageContainer? {
get {
queue.sync {
Expand Down

0 comments on commit facf483

Please sign in to comment.