1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  contributor license agreements.  See the NOTICE file distributed with
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  this work for additional information regarding copyright ownership.
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  (the "License"); you may not use this file except in compliance with
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  the License.  You may obtain a copy of the License at
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  See the License for the specific language governing permissions and
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  limitations under the License.
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.util;
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.lang.ref.ReferenceQueue;
21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.lang.ref.WeakReference;
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WeakHashMap is an implementation of Map with keys which are WeakReferences. A
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * key/value mapping is removed when the key is no longer referenced. All
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * optional operations (adding and removing) are supported. Keys and values can
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * be any objects. Note that the garbage collector acts similar to a second
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * thread on this collection, possibly removing keys.
29f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson *
30f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @since 1.2
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see HashMap
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see WeakReference
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class WeakHashMap<K, V> extends AbstractMap<K, V> implements Map<K, V> {
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final int DEFAULT_SIZE = 16;
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private final ReferenceQueue<K> referenceQueue;
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    int elementCount;
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    Entry<K, V>[] elementData;
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private final int loadFactor;
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private int threshold;
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    volatile int modCount;
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Simple utility method to isolate unchecked cast for array creation
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @SuppressWarnings("unchecked")
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static <K, V> Entry<K, V>[] newEntryArray(int size) {
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return new Entry[size];
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final class Entry<K, V> extends WeakReference<K> implements
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Map.Entry<K, V> {
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int hash;
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        boolean isNull;
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        V value;
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Entry<K, V> next;
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        interface Type<R, K, V> {
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            R get(Map.Entry<K, V> entry);
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Entry(K key, V object, ReferenceQueue<K> queue) {
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            super(key, queue);
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            isNull = key == null;
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            hash = isNull ? 0 : key.hashCode();
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            value = object;
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public K getKey() {
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return super.get();
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public V getValue() {
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return value;
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public V setValue(V object) {
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            V result = value;
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            value = object;
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return result;
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public boolean equals(Object other) {
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!(other instanceof Map.Entry)) {
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return false;
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Map.Entry<?, ?> entry = (Map.Entry<?, ?>) other;
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Object key = super.get();
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return (key == null ? key == entry.getKey() : key.equals(entry
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    .getKey()))
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    && (value == null ? value == entry.getValue() : value
101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            .equals(entry.getValue()));
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public int hashCode() {
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return hash + (value == null ? 0 : value.hashCode());
107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public String toString() {
111f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            return super.get() + "=" + value;
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    class HashIterator<R> implements Iterator<R> {
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private int position = 0, expectedModCount;
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private Entry<K, V> currentEntry, nextEntry;
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private K nextKey;
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        final Entry.Type<R, K, V> type;
123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        HashIterator(Entry.Type<R, K, V> type) {
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.type = type;
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            expectedModCount = modCount;
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public boolean hasNext() {
130f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            if (nextEntry != null && (nextKey != null || nextEntry.isNull)) {
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return true;
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            while (true) {
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (nextEntry == null) {
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    while (position < elementData.length) {
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        if ((nextEntry = elementData[position++]) != null) {
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            break;
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        }
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (nextEntry == null) {
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        return false;
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // ensure key of next entry is not gc'ed
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                nextKey = nextEntry.get();
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (nextKey != null || nextEntry.isNull) {
147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return true;
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                nextEntry = nextEntry.next;
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public R next() {
154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (expectedModCount == modCount) {
155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (hasNext()) {
156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    currentEntry = nextEntry;
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    nextEntry = currentEntry.next;
158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    R result = type.get(currentEntry);
159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // free the key
160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    nextKey = null;
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return result;
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new NoSuchElementException();
164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new ConcurrentModificationException();
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void remove() {
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (expectedModCount == modCount) {
170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (currentEntry != null) {
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    removeEntry(currentEntry);
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    currentEntry = null;
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    expectedModCount++;
174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // cannot poll() as that would change the expectedModCount
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else {
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    throw new IllegalStateException();
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else {
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new ConcurrentModificationException();
180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new empty {@code WeakHashMap} instance.
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public WeakHashMap() {
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this(DEFAULT_SIZE);
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new {@code WeakHashMap} instance with the specified
193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * capacity.
194f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param capacity
196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the initial capacity of this map.
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *                if the capacity is less than zero.
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public WeakHashMap(int capacity) {
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (capacity >= 0) {
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            elementCount = 0;
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            elementData = newEntryArray(capacity == 0 ? 1 : capacity);
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            loadFactor = 7500; // Default load factor of 0.75
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            computeMaxSize();
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            referenceQueue = new ReferenceQueue<K>();
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IllegalArgumentException();
209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new {@code WeakHashMap} instance with the specified capacity
214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * and load factor.
215f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param capacity
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the initial capacity of this map.
218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param loadFactor
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the initial load factor.
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the capacity is less than zero or the load factor is less
222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             or equal to zero.
223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public WeakHashMap(int capacity, float loadFactor) {
225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (capacity >= 0 && loadFactor > 0) {
226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            elementCount = 0;
227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            elementData = newEntryArray(capacity == 0 ? 1 : capacity);
228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.loadFactor = (int) (loadFactor * 10000);
229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            computeMaxSize();
230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            referenceQueue = new ReferenceQueue<K>();
231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IllegalArgumentException();
233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new {@code WeakHashMap} instance containing the mappings
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * from the specified map.
239f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param map
241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the mappings to add.
242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public WeakHashMap(Map<? extends K, ? extends V> map) {
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this(map.size() < 6 ? 11 : map.size() * 2);
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        putAllImpl(map);
246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Removes all mappings from this map, leaving it empty.
250f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #isEmpty()
252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #size()
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void clear() {
256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (elementCount > 0) {
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            elementCount = 0;
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Arrays.fill(elementData, null);
259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            modCount++;
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            while (referenceQueue.poll() != null) {
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // do nothing
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void computeMaxSize() {
267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        threshold = (int) ((long) elementData.length * loadFactor / 10000);
268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this map contains the specified key.
272f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param key
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the key to search for.
275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if this map contains the specified key,
276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code false} otherwise.
277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean containsKey(Object key) {
280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return getEntry(key) != null;
281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a set containing all of the mappings in this map. Each mapping is
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * an instance of {@link Map.Entry}. As the set is backed by this map,
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * changes in one will be reflected in the other. It does not support adding
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * operations.
288f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a set of the mappings.
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Set<Map.Entry<K, V>> entrySet() {
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        poll();
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return new AbstractSet<Map.Entry<K, V>>() {
295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            @Override
296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            public int size() {
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return WeakHashMap.this.size();
298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            @Override
301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            public void clear() {
302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                WeakHashMap.this.clear();
303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            @Override
306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            public boolean remove(Object object) {
307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (contains(object)) {
308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    WeakHashMap.this
309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            .remove(((Map.Entry<?, ?>) object).getKey());
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return true;
311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return false;
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            @Override
316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            public boolean contains(Object object) {
317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (object instanceof Map.Entry) {
318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    Entry<?, ?> entry = getEntry(((Map.Entry<?, ?>) object)
319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            .getKey());
320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (entry != null) {
321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        Object key = entry.get();
322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        if (key != null || entry.isNull) {
323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            return object.equals(entry);
324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        }
325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return false;
328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            @Override
331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            public Iterator<Map.Entry<K, V>> iterator() {
332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return new HashIterator<Map.Entry<K, V>>(
333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        new Entry.Type<Map.Entry<K, V>, K, V>() {
334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            public Map.Entry<K, V> get(Map.Entry<K, V> entry) {
335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                return entry;
336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            }
337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        });
338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        };
340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a set of the keys contained in this map. The set is backed by
344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * this map so changes to one are reflected by the other. The set does not
345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * support adding.
346f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a set of the keys.
348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Set<K> keySet() {
351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        poll();
352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (keySet == null) {
353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            keySet = new AbstractSet<K>() {
354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                @Override
355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                public boolean contains(Object object) {
356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return containsKey(object);
357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                @Override
360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                public int size() {
361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return WeakHashMap.this.size();
362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                @Override
365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                public void clear() {
366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    WeakHashMap.this.clear();
367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                @Override
370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                public boolean remove(Object key) {
371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (containsKey(key)) {
372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        WeakHashMap.this.remove(key);
373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        return true;
374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return false;
376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                @Override
379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                public Iterator<K> iterator() {
380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return new HashIterator<K>(new Entry.Type<K, K, V>() {
381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        public K get(Map.Entry<K, V> entry) {
382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            return entry.getKey();
383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        }
384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    });
385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
386f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
387f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                @Override
388f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                public Object[] toArray() {
389f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                    Collection<K> coll = new ArrayList<K>(size());
390f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
391f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                    for (Iterator<K> iter = iterator(); iter.hasNext();) {
392f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                        coll.add(iter.next());
393f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                    }
394f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                    return coll.toArray();
395f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                }
396f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
397f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                @Override
398f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                public <T> T[] toArray(T[] contents) {
399f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                    Collection<K> coll = new ArrayList<K>(size());
400f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
401f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                    for (Iterator<K> iter = iterator(); iter.hasNext();) {
402f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                        coll.add(iter.next());
403f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                    }
404f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                    return coll.toArray(contents);
405f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                }
406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            };
407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return keySet;
409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a collection of the values contained in this map. The collection
413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * is backed by this map so changes to one are reflected by the other. The
414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * collection supports remove, removeAll, retainAll and clear operations,
415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * and it does not support add or addAll operations.
416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * This method returns a collection which is the subclass of
418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * AbstractCollection. The iterator method of this subclass returns a
419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * "wrapper object" over the iterator of map's entrySet(). The size method
420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * wraps the map's size method and the contains method wraps the map's
421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * containsValue method.
422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The collection is created when this method is called at first time and
424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * returned in response to all subsequent calls. This method may return
425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * different Collection when multiple calls to this method, since it has no
426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * synchronization performed.
427f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a collection of the values contained in this map.
429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Collection<V> values() {
432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        poll();
433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (valuesCollection == null) {
434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            valuesCollection = new AbstractCollection<V>() {
435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                @Override
436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                public int size() {
437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return WeakHashMap.this.size();
438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                @Override
441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                public void clear() {
442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    WeakHashMap.this.clear();
443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                @Override
446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                public boolean contains(Object object) {
447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return containsValue(object);
448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                @Override
451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                public Iterator<V> iterator() {
452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return new HashIterator<V>(new Entry.Type<V, K, V>() {
453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        public V get(Map.Entry<K, V> entry) {
454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            return entry.getValue();
455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        }
456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    });
457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            };
459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return valuesCollection;
461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the value of the mapping with the specified key.
465f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param key
467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the key.
468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the value of the mapping with the specified key, or {@code null}
469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         if no mapping for the specified key is found.
470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public V get(Object key) {
473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        poll();
474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (key != null) {
475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int index = (key.hashCode() & 0x7FFFFFFF) % elementData.length;
476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Entry<K, V> entry = elementData[index];
477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            while (entry != null) {
478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (key.equals(entry.get())) {
479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return entry.value;
480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                entry = entry.next;
482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Entry<K, V> entry = elementData[0];
486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        while (entry != null) {
487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (entry.isNull) {
488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return entry.value;
489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            entry = entry.next;
491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return null;
493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    Entry<K, V> getEntry(Object key) {
496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        poll();
497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (key != null) {
498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int index = (key.hashCode() & 0x7FFFFFFF) % elementData.length;
499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Entry<K, V> entry = elementData[index];
500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            while (entry != null) {
501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (key.equals(entry.get())) {
502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return entry;
503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                entry = entry.next;
505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Entry<K, V> entry = elementData[0];
509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        while (entry != null) {
510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (entry.isNull) {
511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return entry;
512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            entry = entry.next;
514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return null;
516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this map contains the specified value.
520f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param value
522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the value to search for.
523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if this map contains the specified value,
524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code false} otherwise.
525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean containsValue(Object value) {
528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        poll();
529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (value != null) {
530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (int i = elementData.length; --i >= 0;) {
531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Entry<K, V> entry = elementData[i];
532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                while (entry != null) {
533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    K key = entry.get();
534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if ((key != null || entry.isNull)
535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            && value.equals(entry.value)) {
536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        return true;
537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    entry = entry.next;
539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (int i = elementData.length; --i >= 0;) {
543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Entry<K, V> entry = elementData[i];
544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                while (entry != null) {
545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    K key = entry.get();
546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if ((key != null || entry.isNull) && entry.value == null) {
547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        return true;
548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    entry = entry.next;
550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return false;
554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the number of elements in this map.
558f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the number of elements in this map.
560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isEmpty() {
563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return size() == 0;
564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @SuppressWarnings("unchecked")
567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    void poll() {
568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Entry<K, V> toRemove;
569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        while ((toRemove = (Entry<K, V>) referenceQueue.poll()) != null) {
570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            removeEntry(toRemove);
571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    void removeEntry(Entry<K, V> toRemove) {
575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Entry<K, V> entry, last = null;
576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int index = (toRemove.hash & 0x7FFFFFFF) % elementData.length;
577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        entry = elementData[index];
578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Ignore queued entries which cannot be found, the user could
579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // have removed them before they were queued, i.e. using clear()
580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        while (entry != null) {
581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (toRemove == entry) {
582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                modCount++;
583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (last == null) {
584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    elementData[index] = entry.next;
585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else {
586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    last.next = entry.next;
587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                elementCount--;
589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            last = entry;
592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            entry = entry.next;
593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Maps the specified key to the specified value.
598f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param key
600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the key.
601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param value
602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the value.
603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the value of any previous mapping with the specified key or
604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code null} if there was no mapping.
605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public V put(K key, V value) {
608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        poll();
609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int index = 0;
610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Entry<K, V> entry;
611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (key != null) {
612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            index = (key.hashCode() & 0x7FFFFFFF) % elementData.length;
613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            entry = elementData[index];
614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            while (entry != null && !key.equals(entry.get())) {
615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                entry = entry.next;
616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            entry = elementData[0];
619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            while (entry != null && !entry.isNull) {
620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                entry = entry.next;
621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (entry == null) {
624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            modCount++;
625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (++elementCount > threshold) {
626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                rehash();
627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                index = key == null ? 0 : (key.hashCode() & 0x7FFFFFFF)
628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        % elementData.length;
629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            entry = new Entry<K, V>(key, value, referenceQueue);
631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            entry.next = elementData[index];
632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            elementData[index] = entry;
633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        V result = entry.value;
636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        entry.value = value;
637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result;
638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void rehash() {
641b5bde2fd72189192b52e726a2d606d70c3c8a34bElliott Hughes        int length = elementData.length * 2;
642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (length == 0) {
643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            length = 1;
644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Entry<K, V>[] newData = newEntryArray(length);
646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (int i = 0; i < elementData.length; i++) {
647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Entry<K, V> entry = elementData[i];
648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            while (entry != null) {
649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                int index = entry.isNull ? 0 : (entry.hash & 0x7FFFFFFF)
650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        % length;
651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Entry<K, V> next = entry.next;
652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                entry.next = newData[index];
653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                newData[index] = entry;
654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                entry = next;
655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        elementData = newData;
658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        computeMaxSize();
659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Copies all the mappings in the given map to this map. These mappings will
663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * replace all mappings that this map had for any of the keys currently in
664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the given map.
665f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param map
667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the map to copy mappings from.
668f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws NullPointerException
669f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *             if {@code map} is {@code null}.
670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void putAll(Map<? extends K, ? extends V> map) {
673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        putAllImpl(map);
674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Removes the mapping with the specified key from this map.
678f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param key
680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the key of the mapping to remove.
681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the value of the removed mapping or {@code null} if no mapping
682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         for the specified key was found.
683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public V remove(Object key) {
686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        poll();
687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int index = 0;
688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Entry<K, V> entry, last = null;
689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (key != null) {
690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            index = (key.hashCode() & 0x7FFFFFFF) % elementData.length;
691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            entry = elementData[index];
692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            while (entry != null && !key.equals(entry.get())) {
693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                last = entry;
694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                entry = entry.next;
695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            entry = elementData[0];
698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            while (entry != null && !entry.isNull) {
699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                last = entry;
700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                entry = entry.next;
701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (entry != null) {
704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            modCount++;
705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (last == null) {
706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                elementData[index] = entry.next;
707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else {
708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                last.next = entry.next;
709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            elementCount--;
711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return entry.value;
712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return null;
714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the number of elements in this map.
718f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the number of elements in this map.
720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int size() {
723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        poll();
724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return elementCount;
725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void putAllImpl(Map<? extends K, ? extends V> map) {
728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (map.entrySet() != null) {
729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            super.putAll(map);
730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
733