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 Original line Diff line number Diff line
@@ -16,15 +16,12 @@


package android.os;
package android.os;


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


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


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


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


    // Invariant - exactly one of mMap / mParcelledData will be null
    // Invariant - exactly one of mMap / mParcelledData will be null
    // (except inside a call to unparcel)
    // (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
     * 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.
     * Constructs a new, empty Bundle.
     */
     */
    public Bundle() {
    public Bundle() {
        mMap = new HashMap<String, Object>();
        mMap = new ArrayMap<String, Object>();
        mClassLoader = getClass().getClassLoader();
        mClassLoader = getClass().getClassLoader();
    }
    }


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


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


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


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


import android.text.TextUtils;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Log;
import android.util.SparseArray;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
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(),
     * Flatten a Bundle into the parcel at the current dataPosition(),
     * growing dataCapacity() if needed.
     * 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,
    private void readListInternal(List outVal, int N,
        ClassLoader loader) {
        ClassLoader loader) {
        while (N > 0) {
        while (N > 0) {
+42 −1
Original line number Original line 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;
    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
     * Caches of small array objects to avoid spamming garbage.  The cache
     * Object[] variable is a pointer to a linked list of array objects.
     * 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 Object[] mTwiceBaseCache;
    static int mTwiceBaseCacheSize;
    static int mTwiceBaseCacheSize;


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

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


    private void allocArrays(final int size) {
    private void allocArrays(final int size) {
        if (mHashes == EMPTY_IMMUTABLE_INTS) {
            throw new UnsupportedOperationException("ArrayMap is immutable");
        }
        if (size == (BASE_SIZE*2)) {
        if (size == (BASE_SIZE*2)) {
            synchronized (ArrayMap.class) {
            synchronized (ArrayMap.class) {
                if (mTwiceBaseCache != null) {
                if (mTwiceBaseCache != null) {
@@ -204,6 +217,12 @@ public final class ArrayMap<K, V> implements Map<K, V> {
        mSize = 0;
        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.
     * 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
    @Override
    public void clear() {
    public void clear() {
        if (mSize != 0) {
        if (mSize > 0) {
            freeArrays(mHashes, mArray, mSize);
            freeArrays(mHashes, mArray, mSize);
            mHashes = ContainerHelpers.EMPTY_INTS;
            mHashes = ContainerHelpers.EMPTY_INTS;
            mArray = ContainerHelpers.EMPTY_OBJECTS;
            mArray = ContainerHelpers.EMPTY_OBJECTS;
@@ -390,6 +409,28 @@ public final class ArrayMap<K, V> implements Map<K, V> {
        return null;
        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>
     * 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.
     * @param array The array whose contents are to be retrieved.