From 7664c826ef2a55c67a4b55fbe61e33203355f2ee Mon Sep 17 00:00:00 2001 From: paulsowden Date: Thu, 8 Feb 2018 11:58:11 -0800 Subject: [PATCH] Create a CachedHashCodeArrayMap subclass to speed up EngineKey hashing. EngineKey is hashed frequently and caches its own hashCode, however for every request a new EngineKey is created and it rehashes the options and transformations. It's common to cache RequestBuilders for generating multiple requests that have the same options so a handy optimisation is to use an ArrayMap subclass that caches the hashCode to prevent recomputing it every time. This is one of the more expensive atoms in starting a glide request. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=185029279 --- .../java/com/bumptech/glide/load/Options.java | 3 +- .../glide/request/RequestOptions.java | 6 +-- .../glide/util/CachedHashCodeArrayMap.java | 48 +++++++++++++++++++ 3 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 library/src/main/java/com/bumptech/glide/util/CachedHashCodeArrayMap.java diff --git a/library/src/main/java/com/bumptech/glide/load/Options.java b/library/src/main/java/com/bumptech/glide/load/Options.java index bf2685323e..6609a080f6 100644 --- a/library/src/main/java/com/bumptech/glide/load/Options.java +++ b/library/src/main/java/com/bumptech/glide/load/Options.java @@ -4,13 +4,14 @@ import android.support.annotation.Nullable; import android.support.v4.util.ArrayMap; import android.support.v4.util.SimpleArrayMap; +import com.bumptech.glide.util.CachedHashCodeArrayMap; import java.security.MessageDigest; /** * A set of {@link Option Options} to apply to in memory and disk cache keys. */ public final class Options implements Key { - private final ArrayMap, Object> values = new ArrayMap<>(); + private final ArrayMap, Object> values = new CachedHashCodeArrayMap<>(); public void putAll(@NonNull Options other) { values.putAll((SimpleArrayMap, Object>) other.values); diff --git a/library/src/main/java/com/bumptech/glide/request/RequestOptions.java b/library/src/main/java/com/bumptech/glide/request/RequestOptions.java index 4e416b6490..81da8c75ce 100644 --- a/library/src/main/java/com/bumptech/glide/request/RequestOptions.java +++ b/library/src/main/java/com/bumptech/glide/request/RequestOptions.java @@ -32,9 +32,9 @@ import com.bumptech.glide.load.resource.gif.GifDrawableTransformation; import com.bumptech.glide.load.resource.gif.GifOptions; import com.bumptech.glide.signature.EmptySignature; +import com.bumptech.glide.util.CachedHashCodeArrayMap; import com.bumptech.glide.util.Preconditions; import com.bumptech.glide.util.Util; -import java.util.HashMap; import java.util.Map; /** @@ -106,7 +106,7 @@ public class RequestOptions implements Cloneable { @NonNull private Options options = new Options(); @NonNull - private Map, Transformation> transformations = new HashMap<>(); + private Map, Transformation> transformations = new CachedHashCodeArrayMap<>(); @NonNull private Class resourceClass = Object.class; private boolean isLocked; @@ -822,7 +822,7 @@ public RequestOptions clone() { RequestOptions result = (RequestOptions) super.clone(); result.options = new Options(); result.options.putAll(options); - result.transformations = new HashMap<>(); + result.transformations = new CachedHashCodeArrayMap<>(); result.transformations.putAll(transformations); result.isLocked = false; result.isAutoCloneEnabled = false; diff --git a/library/src/main/java/com/bumptech/glide/util/CachedHashCodeArrayMap.java b/library/src/main/java/com/bumptech/glide/util/CachedHashCodeArrayMap.java new file mode 100644 index 0000000000..6d6b2fbf71 --- /dev/null +++ b/library/src/main/java/com/bumptech/glide/util/CachedHashCodeArrayMap.java @@ -0,0 +1,48 @@ +package com.bumptech.glide.util; + +import android.support.v4.util.ArrayMap; +import android.support.v4.util.SimpleArrayMap; + +/** An {@link ArrayMap} that caches its hashCode to support efficient lookup. */ +public final class CachedHashCodeArrayMap extends ArrayMap { + + private int hashCode; + + @Override + public void clear() { + hashCode = 0; + super.clear(); + } + + @Override + public V setValueAt(int index, V value) { + hashCode = 0; + return super.setValueAt(index, value); + } + + @Override + public V put(K key, V value) { + hashCode = 0; + return super.put(key, value); + } + + @Override + public void putAll(SimpleArrayMap simpleArrayMap) { + hashCode = 0; + super.putAll(simpleArrayMap); + } + + @Override + public V removeAt(int index) { + hashCode = 0; + return super.removeAt(index); + } + + @Override + public int hashCode() { + if (hashCode == 0) { + hashCode = super.hashCode(); + } + return hashCode; + } +}