LongSparseLongArray.java revision 3e82ba1a67b0c756ab6a289985f4cfc53725b311
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;
20dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
21dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkeyimport java.util.Arrays;
22dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
23dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey/**
24dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey * Map of {@code long} to {@code long}. Unlike a normal array of longs, there
25b993f41eb2f165425dfdf0f93ea0b1e354eca837Dianne Hackborn * can be gaps in the indices. It is intended to be more memory efficient than using a
26b993f41eb2f165425dfdf0f93ea0b1e354eca837Dianne Hackborn * {@code HashMap}, both because it avoids
27b993f41eb2f165425dfdf0f93ea0b1e354eca837Dianne Hackborn * auto-boxing keys and values and its data structure doesn't rely on an extra entry object
28b993f41eb2f165425dfdf0f93ea0b1e354eca837Dianne Hackborn * for each mapping.
29b993f41eb2f165425dfdf0f93ea0b1e354eca837Dianne Hackborn *
30b993f41eb2f165425dfdf0f93ea0b1e354eca837Dianne Hackborn * <p>Note that this container keeps its mappings in an array data structure,
31b993f41eb2f165425dfdf0f93ea0b1e354eca837Dianne Hackborn * using a binary search to find keys.  The implementation is not intended to be appropriate for
32b993f41eb2f165425dfdf0f93ea0b1e354eca837Dianne Hackborn * data structures
33b993f41eb2f165425dfdf0f93ea0b1e354eca837Dianne Hackborn * that may contain large numbers of items.  It is generally slower than a traditional
34b993f41eb2f165425dfdf0f93ea0b1e354eca837Dianne Hackborn * HashMap, since lookups require a binary search and adds and removes require inserting
35b993f41eb2f165425dfdf0f93ea0b1e354eca837Dianne Hackborn * and deleting entries in the array.  For containers holding up to hundreds of items,
36b993f41eb2f165425dfdf0f93ea0b1e354eca837Dianne Hackborn * the performance difference is not significant, less than 50%.</p>
37dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey *
38dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey * @hide
39dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey */
40dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkeypublic class LongSparseLongArray implements Cloneable {
41dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    private long[] mKeys;
42dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    private long[] mValues;
43dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    private int mSize;
44dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
45dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    /**
46dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * Creates a new SparseLongArray containing no mappings.
47dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     */
48dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    public LongSparseLongArray() {
49dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        this(10);
50dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    }
51dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
52dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    /**
53dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * Creates a new SparseLongArray containing no mappings that will not
54dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * require any additional memory allocation to store the specified
55f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn     * number of mappings.  If you supply an initial capacity of 0, the
56f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn     * sparse array will be initialized with a light-weight representation
57f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn     * not requiring any additional array allocations.
58dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     */
59dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    public LongSparseLongArray(int initialCapacity) {
60f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        if (initialCapacity == 0) {
613e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn            mKeys = ContainerHelpers.EMPTY_LONGS;
623e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn            mValues = ContainerHelpers.EMPTY_LONGS;
63f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        } else {
64f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            initialCapacity = ArrayUtils.idealLongArraySize(initialCapacity);
65f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            mKeys = new long[initialCapacity];
66f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            mValues = new long[initialCapacity];
67f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
68dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        mSize = 0;
69dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    }
70dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
71dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    @Override
72dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    public LongSparseLongArray clone() {
73dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        LongSparseLongArray clone = null;
74dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        try {
75dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey            clone = (LongSparseLongArray) super.clone();
76dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey            clone.mKeys = mKeys.clone();
77dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey            clone.mValues = mValues.clone();
78dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        } catch (CloneNotSupportedException cnse) {
79dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey            /* ignore */
80dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        }
81dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        return clone;
82dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    }
83dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
84dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    /**
85dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * Gets the long mapped from the specified key, or <code>0</code>
86dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * if no such mapping has been made.
87dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     */
88dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    public long get(long key) {
89dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        return get(key, 0);
90dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    }
91dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
92dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    /**
93dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * Gets the long mapped from the specified key, or the specified value
94dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * if no such mapping has been made.
95dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     */
96dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    public long get(long key, long valueIfKeyNotFound) {
973e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn        int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
98dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
99dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        if (i < 0) {
100dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey            return valueIfKeyNotFound;
101dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        } else {
102dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey            return mValues[i];
103dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        }
104dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    }
105dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
106dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    /**
107dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * Removes the mapping from the specified key, if there was any.
108dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     */
109dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    public void delete(long key) {
1103e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn        int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
111dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
112dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        if (i >= 0) {
113dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey            removeAt(i);
114dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        }
115dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    }
116dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
117dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    /**
118dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * Removes the mapping at the given index.
119dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     */
120dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    public void removeAt(int index) {
121dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        System.arraycopy(mKeys, index + 1, mKeys, index, mSize - (index + 1));
122dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        System.arraycopy(mValues, index + 1, mValues, index, mSize - (index + 1));
123dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        mSize--;
124dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    }
125dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
126dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    /**
127dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * Adds a mapping from the specified key to the specified value,
128dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * replacing the previous mapping from the specified key if there
129dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * was one.
130dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     */
131dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    public void put(long key, long value) {
1323e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn        int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
133dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
134dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        if (i >= 0) {
135dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey            mValues[i] = value;
136dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        } else {
137dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey            i = ~i;
138dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
139dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey            if (mSize >= mKeys.length) {
140dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey                growKeyAndValueArrays(mSize + 1);
141dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey            }
142dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
143dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey            if (mSize - i != 0) {
144dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey                System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);
145dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey                System.arraycopy(mValues, i, mValues, i + 1, mSize - i);
146dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey            }
147dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
148dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey            mKeys[i] = key;
149dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey            mValues[i] = value;
150dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey            mSize++;
151dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        }
152dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    }
153dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
154dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    /**
155dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * Returns the number of key-value mappings that this SparseIntArray
156dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * currently stores.
157dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     */
158dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    public int size() {
159dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        return mSize;
160dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    }
161dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
162dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    /**
163dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * Given an index in the range <code>0...size()-1</code>, returns
164dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * the key from the <code>index</code>th key-value mapping that this
165dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * SparseLongArray stores.
166dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     */
167dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    public long keyAt(int index) {
168dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        return mKeys[index];
169dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    }
170dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
171dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    /**
172dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * Given an index in the range <code>0...size()-1</code>, returns
173dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * the value from the <code>index</code>th key-value mapping that this
174dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * SparseLongArray stores.
175dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     */
176dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    public long valueAt(int index) {
177dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        return mValues[index];
178dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    }
179dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
180dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    /**
181dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * Returns the index for which {@link #keyAt} would return the
182dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * specified key, or a negative number if the specified
183dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * key is not mapped.
184dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     */
185dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    public int indexOfKey(long key) {
1863e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn        return ContainerHelpers.binarySearch(mKeys, mSize, key);
187dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    }
188dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
189dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    /**
190dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * Returns an index for which {@link #valueAt} would return the
191dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * specified key, or a negative number if no keys map to the
192dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * specified value.
193dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * Beware that this is a linear search, unlike lookups by key,
194dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * and that multiple keys can map to the same value and this will
195dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * find only one of them.
196dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     */
197dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    public int indexOfValue(long value) {
198dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        for (int i = 0; i < mSize; i++)
199dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey            if (mValues[i] == value)
200dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey                return i;
201dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
202dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        return -1;
203dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    }
204dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
205dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    /**
206dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * Removes all key-value mappings from this SparseIntArray.
207dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     */
208dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    public void clear() {
209dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        mSize = 0;
210dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    }
211dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
212dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    /**
213dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * Puts a key/value pair into the array, optimizing for the case where
214dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     * the key is greater than all existing keys in the array.
215dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey     */
216dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    public void append(long key, long value) {
217dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        if (mSize != 0 && key <= mKeys[mSize - 1]) {
218dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey            put(key, value);
219dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey            return;
220dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        }
221dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
222dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        int pos = mSize;
223dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        if (pos >= mKeys.length) {
224dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey            growKeyAndValueArrays(pos + 1);
225dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        }
226dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
227dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        mKeys[pos] = key;
228dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        mValues[pos] = value;
229dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        mSize = pos + 1;
230dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    }
231dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
232dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    private void growKeyAndValueArrays(int minNeededSize) {
233dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        int n = ArrayUtils.idealLongArraySize(minNeededSize);
234dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
235dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        long[] nkeys = new long[n];
236dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        long[] nvalues = new long[n];
237dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
238dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
239dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
240dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey
241dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        mKeys = nkeys;
242dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey        mValues = nvalues;
243dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey    }
2443e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn
2453e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn    /**
2463e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn     * {@inheritDoc}
2473e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn     *
2483e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn     * <p>This implementation composes a string by iterating over its mappings.
2493e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn     */
2503e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn    @Override
2513e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn    public String toString() {
2523e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn        if (size() <= 0) {
2533e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn            return "{}";
2543e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn        }
2553e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn
2563e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn        StringBuilder buffer = new StringBuilder(mSize * 28);
2573e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn        buffer.append('{');
2583e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn        for (int i=0; i<mSize; i++) {
2593e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn            if (i > 0) {
2603e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn                buffer.append(", ");
2613e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn            }
2623e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn            long key = keyAt(i);
2633e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn            buffer.append(key);
2643e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn            buffer.append('=');
2653e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn            long value = valueAt(i);
2663e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn            buffer.append(value);
2673e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn        }
2683e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn        buffer.append('}');
2693e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn        return buffer.toString();
2703e82ba1a67b0c756ab6a289985f4cfc53725b311Dianne Hackborn    }
271dda73b5dcd92006762a1c71e2fb352e64fa265efJeff Sharkey}
272