Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 20bf1225 authored by Dianne Hackborn's avatar Dianne Hackborn Committed by Android (Google) Code Review
Browse files

Merge "Switch Bundle's implementation over to ArrayMap."

parents fbf4ce04 b87655b3
Loading
Loading
Loading
Loading
+13 −17
Original line number Diff line number Diff line
@@ -16,15 +16,12 @@

package android.os;

import android.util.ArrayMap;
import android.util.Log;
import android.util.SparseArray;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
@@ -37,13 +34,13 @@ public final class Bundle implements Parcelable, Cloneable {

    static {
        EMPTY = new Bundle();
        EMPTY.mMap = Collections.unmodifiableMap(new HashMap<String, Object>());
        EMPTY.mMap = ArrayMap.EMPTY;
    }

    // Invariant - exactly one of mMap / mParcelledData will be null
    // (except inside a call to unparcel)

    /* package */ Map<String, Object> mMap = null;
    /* package */ ArrayMap<String, Object> mMap = null;

    /*
     * If mParcelledData is non-null, then mMap will be null and the
@@ -65,7 +62,7 @@ public final class Bundle implements Parcelable, Cloneable {
     * Constructs a new, empty Bundle.
     */
    public Bundle() {
        mMap = new HashMap<String, Object>();
        mMap = new ArrayMap<String, Object>();
        mClassLoader = getClass().getClassLoader();
    }

@@ -91,7 +88,7 @@ public final class Bundle implements Parcelable, Cloneable {
     * inside of the Bundle.
     */
    public Bundle(ClassLoader loader) {
        mMap = new HashMap<String, Object>();
        mMap = new ArrayMap<String, Object>();
        mClassLoader = loader;
    }

@@ -102,7 +99,7 @@ public final class Bundle implements Parcelable, Cloneable {
     * @param capacity the initial capacity of the Bundle
     */
    public Bundle(int capacity) {
        mMap = new HashMap<String, Object>(capacity);
        mMap = new ArrayMap<String, Object>(capacity);
        mClassLoader = getClass().getClassLoader();
    }

@@ -122,7 +119,7 @@ public final class Bundle implements Parcelable, Cloneable {
        }

        if (b.mMap != null) {
            mMap = new HashMap<String, Object>(b.mMap);
            mMap = new ArrayMap<String, Object>(b.mMap);
        } else {
            mMap = null;
        }
@@ -162,7 +159,7 @@ public final class Bundle implements Parcelable, Cloneable {
        if (size == 0) {
            return null;
        }
        Object o = mMap.values().iterator().next();
        Object o = mMap.valueAt(0);
        try {
            return (String) o;
        } catch (ClassCastException e) {
@@ -218,9 +215,9 @@ public final class Bundle implements Parcelable, Cloneable {
            return;
        }
        if (mMap == null) {
            mMap = new HashMap<String, Object>(N);
            mMap = new ArrayMap<String, Object>(N);
        }
        mParcelledData.readMapInternal(mMap, N, mClassLoader);
        mParcelledData.readArrayMapInternal(mMap, N, mClassLoader);
        mParcelledData.recycle();
        mParcelledData = null;
    }
@@ -331,9 +328,8 @@ public final class Bundle implements Parcelable, Cloneable {
                }
            } else {
                // It's been unparcelled, so we need to walk the map
                Iterator<Map.Entry<String, Object>> iter = mMap.entrySet().iterator();
                while (!fdFound && iter.hasNext()) {
                    Object obj = iter.next().getValue();
                for (int i=mMap.size()-1; i>=0; i--) {
                    Object obj = mMap.valueAt(i);
                    if (obj instanceof Parcelable) {
                        if ((((Parcelable)obj).describeContents()
                                & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0) {
@@ -1643,7 +1639,7 @@ public final class Bundle implements Parcelable, Cloneable {
                parcel.writeInt(0x4C444E42); // 'B' 'N' 'D' 'L'
    
                int oldPos = parcel.dataPosition();
                parcel.writeMapInternal(mMap);
                parcel.writeArrayMapInternal(mMap);
                int newPos = parcel.dataPosition();
    
                // Backpatch length
+29 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.os;

import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
@@ -592,6 +593,23 @@ public final class Parcel {
        }
    }

    /**
     * Flatten an ArrayMap into the parcel at the current dataPosition(),
     * growing dataCapacity() if needed.  The Map keys must be String objects.
     */
    /* package */ void writeArrayMapInternal(ArrayMap<String,Object> val) {
        if (val == null) {
            writeInt(-1);
            return;
        }
        final int N = val.size();
        writeInt(N);
        for (int i=0; i<N; i++) {
            writeValue(val.keyAt(i));
            writeValue(val.valueAt(i));
        }
    }

    /**
     * Flatten a Bundle into the parcel at the current dataPosition(),
     * growing dataCapacity() if needed.
@@ -2258,6 +2276,16 @@ public final class Parcel {
        }
    }

    /* package */ void readArrayMapInternal(ArrayMap outVal, int N,
        ClassLoader loader) {
        while (N > 0) {
            Object key = readValue(loader);
            Object value = readValue(loader);
            outVal.append(key, value);
            N--;
        }
    }

    private void readListInternal(List outVal, int N,
        ClassLoader loader) {
        while (N > 0) {
+42 −1
Original line number Diff line number Diff line
@@ -60,6 +60,11 @@ public final class ArrayMap<K, V> implements Map<K, V> {
     */
    private static final int CACHE_SIZE = 10;

    /**
     * @hide Special immutable empty ArrayMap.
     */
    public static final ArrayMap EMPTY = new ArrayMap(true);

    /**
     * Caches of small array objects to avoid spamming garbage.  The cache
     * Object[] variable is a pointer to a linked list of array objects.
@@ -71,6 +76,11 @@ public final class ArrayMap<K, V> implements Map<K, V> {
    static Object[] mTwiceBaseCache;
    static int mTwiceBaseCacheSize;

    /**
     * Special hash array value that indicates the container is immutable.
     */
    static final int[] EMPTY_IMMUTABLE_INTS = new int[0];

    int[] mHashes;
    Object[] mArray;
    int mSize;
@@ -115,6 +125,9 @@ public final class ArrayMap<K, V> implements Map<K, V> {
    }

    private void allocArrays(final int size) {
        if (mHashes == EMPTY_IMMUTABLE_INTS) {
            throw new UnsupportedOperationException("ArrayMap is immutable");
        }
        if (size == (BASE_SIZE*2)) {
            synchronized (ArrayMap.class) {
                if (mTwiceBaseCache != null) {
@@ -204,6 +217,12 @@ public final class ArrayMap<K, V> implements Map<K, V> {
        mSize = 0;
    }

    private ArrayMap(boolean immutable) {
        mHashes = EMPTY_IMMUTABLE_INTS;
        mArray = ContainerHelpers.EMPTY_OBJECTS;
        mSize = 0;
    }

    /**
     * Create a new ArrayMap with the mappings from the given ArrayMap.
     */
@@ -219,7 +238,7 @@ public final class ArrayMap<K, V> implements Map<K, V> {
     */
    @Override
    public void clear() {
        if (mSize != 0) {
        if (mSize > 0) {
            freeArrays(mHashes, mArray, mSize);
            mHashes = ContainerHelpers.EMPTY_INTS;
            mArray = ContainerHelpers.EMPTY_OBJECTS;
@@ -390,6 +409,28 @@ public final class ArrayMap<K, V> implements Map<K, V> {
        return null;
    }

    /**
     * Special fast path for appending items to the end of the array without validation.
     * The array must already be large enough to contain the item.
     * @hide
     */
    public void append(K key, V value) {
        int index = mSize;
        final int hash = key.hashCode();
        if (index >= mHashes.length) {
            throw new IllegalStateException("Array is full");
        }
        if (index > 0 && mHashes[index-1] > hash) {
            throw new IllegalArgumentException("New hash " + hash
                    + " is before end of array hash " + mHashes[index-1]);
        }
        mSize = index+1;
        mHashes[index] = hash;
        index <<= 1;
        mArray[index] = key;
        mArray[index+1] = value;
    }

    /**
     * Perform a {@link #put(Object, Object)} of all key/value pairs in <var>array</var>
     * @param array The array whose contents are to be retrieved.