Bug 962968 - Replace HashMap with SparseArray in ICODecoder (r=rnewman)
authorLucas Rocha <lucasr@mozilla.com>
Thu, 23 Jan 2014 19:00:05 +0000
changeset 180978 65bfef117974dcc3fd6c145642b1e3664c13e0a6
parent 180977 7d6daa084033cf2afb3fa8c37e4cd75db37cd6ac
child 180979 4d79320f696efdc04a6a581d5411fb9166e2ae7f
push id3343
push userffxbld
push dateMon, 17 Mar 2014 21:55:32 +0000
treeherdermozilla-beta@2f7d3415f79f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrnewman
bugs962968
milestone29.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 962968 - Replace HashMap with SparseArray in ICODecoder (r=rnewman)
mobile/android/base/favicons/decoders/ICODecoder.java
--- a/mobile/android/base/favicons/decoders/ICODecoder.java
+++ b/mobile/android/base/favicons/decoders/ICODecoder.java
@@ -3,18 +3,19 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.favicons.decoders;
 
 import android.graphics.Bitmap;
 import org.mozilla.gecko.favicons.Favicons;
 import org.mozilla.gecko.gfx.BitmapUtils;
 
+import android.util.SparseArray;
+
 import java.util.Collection;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
 
 /**
  * Utility class for determining the region of a provided array which contains the largest bitmap,
  * assuming the provided array is a valid ICO and the bitmap desired is square, and for pruning
  * unwanted entries from ICO files, if desired.
  *
@@ -147,17 +148,17 @@ public class ICODecoder implements Itera
 
         // We now iterate over the Icon Directory, decoding each entry as we go. We also need to
         // discard all entries except one >= the maximum interesting size.
 
         // Size of the smallest image larger than the limit encountered.
         int minimumMaximum = Integer.MAX_VALUE;
 
         // Used to track the best entry for each size. The entries we want to keep.
-        HashMap<Integer, IconDirectoryEntry> preferenceMap = new HashMap<Integer, IconDirectoryEntry>();
+        SparseArray<IconDirectoryEntry> preferenceArray = new SparseArray<IconDirectoryEntry>();
 
         for (int i = 0; i < numEncodedImages; i++, bufferIndex += ICO_ICONDIRENTRY_LENGTH_BYTES) {
             // Decode the Icon Directory Entry at this offset.
             IconDirectoryEntry newEntry = IconDirectoryEntry.createFromBuffer(mDecodand, mOffset, mLen, bufferIndex);
             newEntry.mIndex = i;
 
             if (newEntry.mIsErroneous) {
                 continue;
@@ -167,52 +168,49 @@ public class ICODecoder implements Itera
                 // If we already have a smaller image larger than the maximum size of interest, we
                 // don't care about the new one which is larger than the smallest image larger than
                 // the maximum size.
                 if (newEntry.mWidth >= minimumMaximum) {
                     continue;
                 }
 
                 // Remove the previous minimum-maximum.
-                if (preferenceMap.containsKey(minimumMaximum)) {
-                    preferenceMap.remove(minimumMaximum);
-                }
+                preferenceArray.delete(minimumMaximum);
 
                 minimumMaximum = newEntry.mWidth;
             }
 
-            IconDirectoryEntry oldEntry = preferenceMap.get(newEntry.mWidth);
+            IconDirectoryEntry oldEntry = preferenceArray.get(newEntry.mWidth);
             if (oldEntry == null) {
-                preferenceMap.put(newEntry.mWidth, newEntry);
+                preferenceArray.put(newEntry.mWidth, newEntry);
                 continue;
             }
 
             if (oldEntry.compareTo(newEntry) < 0) {
-                preferenceMap.put(newEntry.mWidth, newEntry);
+                preferenceArray.put(newEntry.mWidth, newEntry);
             }
         }
 
-        Collection<IconDirectoryEntry> entriesRetained = preferenceMap.values();
+        final int count = preferenceArray.size();
 
         // Abort if no entries are desired (Perhaps all are corrupt?)
-        if (entriesRetained.isEmpty()) {
+        if (count == 0) {
             return false;
         }
 
         // Allocate space for the icon directory entries in the decoded directory.
-        mIconDirectory = new IconDirectoryEntry[entriesRetained.size()];
+        mIconDirectory = new IconDirectoryEntry[count];
 
         // The size of the data in the buffer that we find useful.
         int retainedSpace = ICO_HEADER_LENGTH_BYTES;
 
-        int dirInd = 0;
-        for (IconDirectoryEntry e : entriesRetained) {
+        for (int i = 0; i < count; i++) {
+            IconDirectoryEntry e = preferenceArray.valueAt(i);
             retainedSpace += ICO_ICONDIRENTRY_LENGTH_BYTES + e.mPayloadSize;
-            mIconDirectory[dirInd] = e;
-            dirInd++;
+            mIconDirectory[i] = e;
         }
 
         mIsValid = true;
 
         // Set the number of images field in the buffer to reflect the number of retained entries.
         mDecodand[mOffset + 4] = (byte) mIconDirectory.length;
         mDecodand[mOffset + 5] = (byte) (mIconDirectory.length >>> 8);