1dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey/*
2dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey * Copyright (C) 2007 The Android Open Source Project
3dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey *
4dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License");
5dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey * you may not use this file except in compliance with the License.
6dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey * You may obtain a copy of the License at
7dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey *
8dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey *      http://www.apache.org/licenses/LICENSE-2.0
9dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey *
10dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey * Unless required by applicable law or agreed to in writing, software
11dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS,
12dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey * See the License for the specific language governing permissions and
14dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey * limitations under the License.
15dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey */
16dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
17dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkeypackage android.util;
18dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
19dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkeyimport com.android.internal.util.ArrayUtils;
20776abc24cdd18610232a50b997cce3cffa74609bAdam Lesinskiimport com.android.internal.util.GrowingArrayUtils;
21776abc24cdd18610232a50b997cce3cffa74609bAdam Lesinski
22776abc24cdd18610232a50b997cce3cffa74609bAdam Lesinskiimport libcore.util.EmptyArray;
23dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
24dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey/**
25dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey * Map of {@code long} to {@code long}. Unlike a normal array of longs, there
26b993f41eb2f165425dfdf0f93ea0b1e354eca837Dianne Hackborn * can be gaps in the indices. It is intended to be more memory efficient than using a
27b993f41eb2f165425dfdf0f93ea0b1e354eca837Dianne Hackborn * {@code HashMap}, both because it avoids
28b993f41eb2f165425dfdf0f93ea0b1e354eca837Dianne Hackborn * auto-boxing keys and values and its data structure doesn't rely on an extra entry object
29b993f41eb2f165425dfdf0f93ea0b1e354eca837Dianne Hackborn * for each mapping.
30b993f41eb2f165425dfdf0f93ea0b1e354eca837Dianne Hackborn *
31b993f41eb2f165425dfdf0f93ea0b1e354eca837Dianne Hackborn * <p>Note that this container keeps its mappings in an array data structure,
32b993f41eb2f165425dfdf0f93ea0b1e354eca837Dianne Hackborn * using a binary search to find keys.  The implementation is not intended to be appropriate for
33b993f41eb2f165425dfdf0f93ea0b1e354eca837Dianne Hackborn * data structures
34b993f41eb2f165425dfdf0f93ea0b1e354eca837Dianne Hackborn * that may contain large numbers of items.  It is generally slower than a traditional
35b993f41eb2f165425dfdf0f93ea0b1e354eca837Dianne Hackborn * HashMap, since lookups require a binary search and adds and removes require inserting
36b993f41eb2f165425dfdf0f93ea0b1e354eca837Dianne Hackborn * and deleting entries in the array.  For containers holding up to hundreds of items,
37b993f41eb2f165425dfdf0f93ea0b1e354eca837Dianne Hackborn * the performance difference is not significant, less than 50%.</p>
38dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey *
395771302ca13c31cb85f17bc58da8f6f8227c9b85Flavio Lerda * <p>It is possible to iterate over the items in this container using
405771302ca13c31cb85f17bc58da8f6f8227c9b85Flavio Lerda * {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using
415771302ca13c31cb85f17bc58da8f6f8227c9b85Flavio Lerda * <code>keyAt(int)</code> with ascending values of the index will return the
425771302ca13c31cb85f17bc58da8f6f8227c9b85Flavio Lerda * keys in ascending order, or the values corresponding to the keys in ascending
43ebb47950f21d3c41955a591000dfb1f195e746feNewton Allen * order in the case of <code>valueAt(int)</code>.</p>
445771302ca13c31cb85f17bc58da8f6f8227c9b85Flavio Lerda *
45dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey * @hide
46dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey */
47dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkeypublic class LongSparseLongArray implements Cloneable {
48dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    private long[] mKeys;
49dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    private long[] mValues;
50dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    private int mSize;
51dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
52dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    /**
53dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * Creates a new SparseLongArray containing no mappings.
54dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     */
55dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    public LongSparseLongArray() {
56dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        this(10);
57dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    }
58dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
59dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    /**
60dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * Creates a new SparseLongArray containing no mappings that will not
61dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * require any additional memory allocation to store the specified
62f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn     * number of mappings.  If you supply an initial capacity of 0, the
63f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn     * sparse array will be initialized with a light-weight representation
64f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn     * not requiring any additional array allocations.
65dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     */
66dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    public LongSparseLongArray(int initialCapacity) {
67f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        if (initialCapacity == 0) {
68776abc24cdd18610232a50b997cce3cffa74609bAdam Lesinski            mKeys = EmptyArray.LONG;
69776abc24cdd18610232a50b997cce3cffa74609bAdam Lesinski            mValues = EmptyArray.LONG;
70f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        } else {
71776abc24cdd18610232a50b997cce3cffa74609bAdam Lesinski            mKeys = ArrayUtils.newUnpaddedLongArray(initialCapacity);
72776abc24cdd18610232a50b997cce3cffa74609bAdam Lesinski            mValues = new long[mKeys.length];
73f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
74dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        mSize = 0;
75dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    }
76dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
77dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    @Override
78dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    public LongSparseLongArray clone() {
79dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        LongSparseLongArray clone = null;
80dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        try {
81dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey            clone = (LongSparseLongArray) super.clone();
82dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey            clone.mKeys = mKeys.clone();
83dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey            clone.mValues = mValues.clone();
84dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        } catch (CloneNotSupportedException cnse) {
85dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey            /* ignore */
86dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        }
87dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        return clone;
88dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    }
89dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
90dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    /**
91dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * Gets the long mapped from the specified key, or <code>0</code>
92dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * if no such mapping has been made.
93dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     */
94dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    public long get(long key) {
95dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        return get(key, 0);
96dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    }
97dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
98dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    /**
99dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * Gets the long mapped from the specified key, or the specified value
100dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * if no such mapping has been made.
101dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     */
102dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    public long get(long key, long valueIfKeyNotFound) {
1033e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn        int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
104dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
105dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        if (i < 0) {
106dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey            return valueIfKeyNotFound;
107dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        } else {
108dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey            return mValues[i];
109dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        }
110dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    }
111dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
112dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    /**
113dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * Removes the mapping from the specified key, if there was any.
114dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     */
115dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    public void delete(long key) {
1163e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn        int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
117dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
118dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        if (i >= 0) {
119dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey            removeAt(i);
120dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        }
121dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    }
122dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
123dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    /**
124dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * Removes the mapping at the given index.
125dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     */
126dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    public void removeAt(int index) {
127dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        System.arraycopy(mKeys, index + 1, mKeys, index, mSize - (index + 1));
128dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        System.arraycopy(mValues, index + 1, mValues, index, mSize - (index + 1));
129dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        mSize--;
130dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    }
131dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
132dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    /**
133dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * Adds a mapping from the specified key to the specified value,
134dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * replacing the previous mapping from the specified key if there
135dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * was one.
136dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     */
137dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    public void put(long key, long value) {
1383e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn        int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
139dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
140dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        if (i >= 0) {
141dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey            mValues[i] = value;
142dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        } else {
143dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey            i = ~i;
144dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
145776abc24cdd18610232a50b997cce3cffa74609bAdam Lesinski            mKeys = GrowingArrayUtils.insert(mKeys, mSize, i, key);
146776abc24cdd18610232a50b997cce3cffa74609bAdam Lesinski            mValues = GrowingArrayUtils.insert(mValues, mSize, i, value);
147dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey            mSize++;
148dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        }
149dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    }
150dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
151dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    /**
152dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * Returns the number of key-value mappings that this SparseIntArray
153dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * currently stores.
154dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     */
155dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    public int size() {
156dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        return mSize;
157dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    }
158dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
159dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    /**
160dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * Given an index in the range <code>0...size()-1</code>, returns
161dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * the key from the <code>index</code>th key-value mapping that this
162dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * SparseLongArray stores.
1635771302ca13c31cb85f17bc58da8f6f8227c9b85Flavio Lerda     *
1645771302ca13c31cb85f17bc58da8f6f8227c9b85Flavio Lerda     * <p>The keys corresponding to indices in ascending order are guaranteed to
1655771302ca13c31cb85f17bc58da8f6f8227c9b85Flavio Lerda     * be in ascending order, e.g., <code>keyAt(0)</code> will return the
1665771302ca13c31cb85f17bc58da8f6f8227c9b85Flavio Lerda     * smallest key and <code>keyAt(size()-1)</code> will return the largest
1675771302ca13c31cb85f17bc58da8f6f8227c9b85Flavio Lerda     * key.</p>
168dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     */
169dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    public long keyAt(int index) {
170dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        return mKeys[index];
171dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    }
172dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
173dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    /**
174dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * Given an index in the range <code>0...size()-1</code>, returns
175dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * the value from the <code>index</code>th key-value mapping that this
176dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * SparseLongArray stores.
1775771302ca13c31cb85f17bc58da8f6f8227c9b85Flavio Lerda     *
1785771302ca13c31cb85f17bc58da8f6f8227c9b85Flavio Lerda     * <p>The values corresponding to indices in ascending order are guaranteed
1795771302ca13c31cb85f17bc58da8f6f8227c9b85Flavio Lerda     * to be associated with keys in ascending order, e.g.,
1805771302ca13c31cb85f17bc58da8f6f8227c9b85Flavio Lerda     * <code>valueAt(0)</code> will return the value associated with the
1815771302ca13c31cb85f17bc58da8f6f8227c9b85Flavio Lerda     * smallest key and <code>valueAt(size()-1)</code> will return the value
1825771302ca13c31cb85f17bc58da8f6f8227c9b85Flavio Lerda     * associated with the largest key.</p>
183dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     */
184dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    public long valueAt(int index) {
185dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        return mValues[index];
186dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    }
187dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
188dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    /**
189dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * Returns the index for which {@link #keyAt} would return the
190dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * specified key, or a negative number if the specified
191dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * key is not mapped.
192dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     */
193dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    public int indexOfKey(long key) {
1943e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn        return ContainerHelpers.binarySearch(mKeys, mSize, key);
195dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    }
196dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
197dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    /**
198dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * Returns an index for which {@link #valueAt} would return the
199dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * specified key, or a negative number if no keys map to the
200dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * specified value.
201dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * Beware that this is a linear search, unlike lookups by key,
202dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * and that multiple keys can map to the same value and this will
203dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * find only one of them.
204dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     */
205dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    public int indexOfValue(long value) {
206dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        for (int i = 0; i < mSize; i++)
207dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey            if (mValues[i] == value)
208dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey                return i;
209dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
210dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        return -1;
211dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    }
212dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
213dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    /**
214dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * Removes all key-value mappings from this SparseIntArray.
215dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     */
216dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    public void clear() {
217dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        mSize = 0;
218dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    }
219dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
220dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    /**
221dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * Puts a key/value pair into the array, optimizing for the case where
222dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * the key is greater than all existing keys in the array.
223dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     */
224dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    public void append(long key, long value) {
225dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        if (mSize != 0 && key <= mKeys[mSize - 1]) {
226dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey            put(key, value);
227dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey            return;
228dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        }
229dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
230776abc24cdd18610232a50b997cce3cffa74609bAdam Lesinski        mKeys = GrowingArrayUtils.append(mKeys, mSize, key);
231776abc24cdd18610232a50b997cce3cffa74609bAdam Lesinski        mValues = GrowingArrayUtils.append(mValues, mSize, value);
232776abc24cdd18610232a50b997cce3cffa74609bAdam Lesinski        mSize++;
233dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    }
2343e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn
2353e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn    /**
2363e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn     * {@inheritDoc}
2373e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn     *
2383e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn     * <p>This implementation composes a string by iterating over its mappings.
2393e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn     */
2403e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn    @Override
2413e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn    public String toString() {
2423e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn        if (size() <= 0) {
2433e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn            return "{}";
2443e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn        }
2453e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn
2463e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn        StringBuilder buffer = new StringBuilder(mSize * 28);
2473e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn        buffer.append('{');
2483e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn        for (int i=0; i<mSize; i++) {
2493e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn            if (i > 0) {
2503e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn                buffer.append(", ");
2513e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn            }
2523e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn            long key = keyAt(i);
2533e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn            buffer.append(key);
2543e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn            buffer.append('=');
2553e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn            long value = valueAt(i);
2563e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn            buffer.append(value);
2573e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn        }
2583e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn        buffer.append('}');
2593e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn        return buffer.toString();
2603e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn    }
261dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey}
262