-
Notifications
You must be signed in to change notification settings - Fork 6.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
move key generator to its own class and add test
- Loading branch information
Showing
3 changed files
with
199 additions
and
81 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
128 changes: 128 additions & 0 deletions
128
library/src/com/bumptech/glide/resize/SafeKeyGenerator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
package com.bumptech.glide.resize; | ||
|
||
import android.os.Build; | ||
import com.bumptech.glide.resize.load.Downsampler; | ||
import com.bumptech.glide.resize.load.Transformation; | ||
import com.bumptech.glide.util.Util; | ||
|
||
import java.io.UnsupportedEncodingException; | ||
import java.nio.ByteBuffer; | ||
import java.security.MessageDigest; | ||
import java.security.NoSuchAlgorithmException; | ||
import java.util.ArrayDeque; | ||
import java.util.HashMap; | ||
import java.util.LinkedList; | ||
import java.util.Map; | ||
import java.util.Queue; | ||
|
||
public class SafeKeyGenerator { | ||
private final Map<LoadId, String> loadIdToSafeHash = new HashMap<LoadId, String>(); | ||
private final ByteBuffer byteBuffer = ByteBuffer.allocate(8); | ||
private final LoadIdPool loadIdPool = new LoadIdPool(); | ||
private MessageDigest messageDigest; | ||
|
||
public SafeKeyGenerator() { | ||
try { | ||
messageDigest = MessageDigest.getInstance("SHA-256"); | ||
} catch (NoSuchAlgorithmException e) { | ||
e.printStackTrace(); | ||
} | ||
} | ||
|
||
public String getSafeKey(String id, Transformation transformation, Downsampler downsampler, int width, int height) { | ||
LoadId loadId = loadIdPool.get(id, transformation.getId(), downsampler.getId(), width, height); | ||
String safeKey = loadIdToSafeHash.get(loadId); | ||
if (safeKey == null) { | ||
try { | ||
safeKey = loadId.generateSafeKey(); | ||
} catch (UnsupportedEncodingException e) { | ||
e.printStackTrace(); | ||
} | ||
loadIdToSafeHash.put(loadId, safeKey); | ||
} else { | ||
loadIdPool.offer(loadId); | ||
} | ||
return safeKey; | ||
} | ||
|
||
private class LoadIdPool { | ||
private static final int MAX_SIZE = 20; | ||
private Queue<LoadId> loadIdQueue; | ||
|
||
public LoadIdPool() { | ||
if (Build.VERSION.SDK_INT >= 9) { | ||
loadIdQueue = new ArrayDeque<LoadId>(MAX_SIZE); | ||
} else { | ||
loadIdQueue = new LinkedList<LoadId>(); | ||
} | ||
} | ||
|
||
public LoadId get(String id, String transformationId, String downsamplerId, int width, int height) { | ||
LoadId loadId = loadIdQueue.poll(); | ||
if (loadId == null) { | ||
loadId = new LoadId(); | ||
} | ||
loadId.init(id, transformationId, downsamplerId, width, height); | ||
return loadId; | ||
} | ||
|
||
public void offer(LoadId loadId) { | ||
if (loadIdQueue.size() < MAX_SIZE) { | ||
loadIdQueue.offer(loadId); | ||
} | ||
} | ||
} | ||
|
||
private class LoadId { | ||
private String id; | ||
private String transformationId; | ||
private String downsamplerId; | ||
private int width; | ||
private int height; | ||
|
||
public void init(String id, String transformationId, String downsamplerId, int width, int height) { | ||
this.id = id; | ||
this.transformationId = transformationId; | ||
this.downsamplerId = downsamplerId; | ||
this.width = width; | ||
this.height = height; | ||
} | ||
|
||
public String generateSafeKey() throws UnsupportedEncodingException { | ||
messageDigest.update(id.getBytes("UTF-8")); | ||
messageDigest.update(transformationId.getBytes("UTF-8")); | ||
messageDigest.update(downsamplerId.getBytes("UTF-8")); | ||
byteBuffer.position(0); | ||
byteBuffer.putInt(width); | ||
byteBuffer.putInt(height); | ||
messageDigest.update(byteBuffer.array()); | ||
return Util.sha256BytesToHex(messageDigest.digest()); | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) return true; | ||
if (o == null || getClass() != o.getClass()) return false; | ||
|
||
LoadId loadId = (LoadId) o; | ||
|
||
if (height != loadId.height) return false; | ||
if (width != loadId.width) return false; | ||
if (!downsamplerId.equals(loadId.downsamplerId)) return false; | ||
if (!id.equals(loadId.id)) return false; | ||
if (!transformationId.equals(loadId.transformationId)) return false; | ||
|
||
return true; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
int result = id.hashCode(); | ||
result = 31 * result + transformationId.hashCode(); | ||
result = 31 * result + downsamplerId.hashCode(); | ||
result = 31 * result + width; | ||
result = 31 * result + height; | ||
return result; | ||
} | ||
} | ||
} |
71 changes: 71 additions & 0 deletions
71
library/tests/src/com/bumptech/glide/KeyGeneratorTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package com.bumptech.glide; | ||
|
||
import android.graphics.Bitmap; | ||
import android.test.AndroidTestCase; | ||
import com.bumptech.glide.resize.SafeKeyGenerator; | ||
import com.bumptech.glide.resize.bitmap_recycle.BitmapPool; | ||
import com.bumptech.glide.resize.load.Downsampler; | ||
import com.bumptech.glide.resize.load.Transformation; | ||
|
||
import java.util.UUID; | ||
import java.util.regex.Matcher; | ||
import java.util.regex.Pattern; | ||
|
||
public class KeyGeneratorTest extends AndroidTestCase { | ||
private SafeKeyGenerator keyGenerator; | ||
|
||
@Override | ||
protected void setUp() throws Exception { | ||
super.setUp(); | ||
keyGenerator = new SafeKeyGenerator(); | ||
} | ||
|
||
public void testKeysAreValidForDiskCache() { | ||
String key; | ||
final Pattern diskCacheRegex = Pattern.compile("[a-z0-9_-]{64}"); | ||
for (int i = 0; i < 1000; i++) { | ||
key = getRandomKeyFromGenerator(); | ||
final Matcher matcher = diskCacheRegex.matcher(key); | ||
assertTrue(matcher.matches()); | ||
} | ||
} | ||
|
||
private String getRandomKeyFromGenerator() { | ||
return keyGenerator.getSafeKey(getRandomId(), new RandomTransformation(), new RandomDownsampler(), | ||
getRandomDimen(), getRandomDimen()); | ||
} | ||
|
||
private static int getRandomDimen() { | ||
return (int) Math.round(Math.random() * 1000); | ||
} | ||
|
||
private static String getRandomId() { | ||
return UUID.randomUUID().toString(); | ||
} | ||
|
||
private static class RandomDownsampler extends Downsampler { | ||
|
||
@Override | ||
protected int getSampleSize(int inWidth, int inHeight, int outWidth, int outHeight) { | ||
return 0; | ||
} | ||
|
||
@Override | ||
public String getId() { | ||
return getRandomId(); | ||
} | ||
} | ||
|
||
private static class RandomTransformation extends Transformation { | ||
|
||
@Override | ||
public Bitmap transform(Bitmap bitmap, BitmapPool pool, int outWidth, int outHeight) { | ||
return null; | ||
} | ||
|
||
@Override | ||
public String getId() { | ||
return getRandomId(); | ||
} | ||
} | ||
} |