Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disk Cache: Add a Sensible Default for Key Encoder #160

Closed
AndrewBarba opened this issue May 11, 2018 · 11 comments
Closed

Disk Cache: Add a Sensible Default for Key Encoder #160

AndrewBarba opened this issue May 11, 2018 · 11 comments
Labels
Milestone

Comments

@AndrewBarba
Copy link

AndrewBarba commented May 11, 2018

In the current example for enableExperimentalAggressiveDiskCaching you are using a sha1 hash as the filename based on the images url, can you think of any reason we can't just use String.hashValue? Asking because it's just more accessible in my opinion

ImagePipeline.shared = ImagePipeline {
    $0.enableExperimentalAggressiveDiskCaching { String($0.hashValue) }
}
@kean
Copy link
Owner

kean commented May 11, 2018

Hey @AndrewBarba. Yes, you do need to use one of the cryptographic hash functions which guarantee that the probability of two URLs having the same hash value (which is used as a filename) is so low that you can ignore it. sha1 is a good candidate.

The hashValue uses a different kind of hash function which is designed to be extremely fast (much faster than cryptographic hash functions) but doesn't give many guarantees in terms of collisions. These types of hash functions are designed to be used primarily by hash tables in which keys are eventually tested for equality. If you were to use hashValue as a filename you are guaranteed to encounter a situation where you produce the same filename for two different URLs.

Another alternative that I've explored is percent encoding URLs to produce valid filenames. The problem with that approach is that filenames have size limits. The maximum filename size on HFS+ is 255 characters and I'm not yet sure what the limit is on APFS.

@kean
Copy link
Owner

kean commented May 11, 2018

There is another option, if you know that you can extract some ID from a URL which uniquely identifies an image and can be used as a filename (or you can percent encode it if necessary), you can use it as a filename.

@AndrewBarba
Copy link
Author

AndrewBarba commented May 11, 2018

I thought about doing that but most of the images I'm using are going through a service like Imgix which has sizing params in the url so the id doesn't do me much good. Thanks for the explanation though! Will most likely stick with sha1 for now. Feel free to close or rename if you end up exploring other options

@AndrewBarba
Copy link
Author

AndrewBarba commented May 11, 2018

I also use Apple's pure Swift implementation of SHA256 in a few other projects, not sure if this is helpful here to lower the barrier to entry: swift-package-manager/SHA256.swift

I just remove the init(_: ByteString) initializer and it works out of the box:

ImagePipeline.shared = ImagePipeline {
    $0.enableExperimentalAggressiveDiskCaching { SHA256($0).digestString() }
}
@kean
Copy link
Owner

kean commented May 11, 2018

Yep, this is perfect. I’m going to provide a sensible default in one of the upcoming versions.

@kean kean added the question label May 11, 2018
@kean kean changed the title [QUESTION] Aggressive Disk Cache Simpler Cache Key? May 11, 2018
@kean kean added feature and removed question labels May 11, 2018
@kean
Copy link
Owner

kean commented May 23, 2018

It would be nice to add a default hash function to the project. The SHA256 from the SPM project takes almost a whole second to compile. And I haven't tested how fast it is.

700.40ms	Nuke/Sources/Internal.swift:655:18	private final func process(_ block: ArraySlice<UInt8>)
176.70ms	Nuke/Sources/Internal.swift:622:17	public final func digest() -> [UInt8]
@AndrewBarba
Copy link
Author

I don’t have hard numbers for you, but the app I work on (recently updated to nuke 7, disk cache with sha256) has been scrolling with no hiccups at all. In the main table view there are 3 images loaded by nuke per cell and it fits 4 cells on screen. The perceived performance has been excellent.

@kean
Copy link
Owner

kean commented May 23, 2018

I'm not really expecting any differences in perceived performance, but I prefer to use the fastest stuff available anyway 😃 The compile time is a real concern though. I wouldn't want users to measure compile time at some point and find out that there are some Nuke's functions at the top (700 ms for a single function is a lot).

@AndrewBarba
Copy link
Author

Yes totally get it. And that’s why I use Nuke over everything else :)

@kean
Copy link
Owner

kean commented Jun 5, 2018

Swift 4.2 finally seems to come with CommonCrypto https://twitter.com/mxcl/status/1003789764884140038. Just in time.

@kean
Copy link
Owner

kean commented Jun 27, 2018

I've implemented a default FilenameGenerator which uses SHA1. It's going to ship in v7.3 and is going to be available in Swift 4.2.

@kean kean closed this as completed Jun 27, 2018
@kean kean added this to the 7.3 milestone Jun 29, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2 participants