Hashtable.java revision 438d9883775e6ee31c097e2103a25571d2426cd9
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
18c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch// BEGIN android-note
19c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch// Completely different implementation from harmony.  Runs much faster.
20c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch// BEGIN android-note
21c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.util;
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException;
25c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Blochimport java.io.InvalidObjectException;
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.ObjectInputStream;
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.ObjectOutputStream;
28c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Blochimport java.io.ObjectStreamField;
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.Serializable;
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
32438d9883775e6ee31c097e2103a25571d2426cd9Elliott Hughes * Hashtable is a synchronized implementation of {@link Map}. All optional operations are supported.
33438d9883775e6ee31c097e2103a25571d2426cd9Elliott Hughes *
34438d9883775e6ee31c097e2103a25571d2426cd9Elliott Hughes * <p>Neither keys nor values can be null. (Use {@code HashMap} or {@code LinkedHashMap} if you
35438d9883775e6ee31c097e2103a25571d2426cd9Elliott Hughes * need null keys or values.)
36438d9883775e6ee31c097e2103a25571d2426cd9Elliott Hughes *
37c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch * @param <K> the type of keys maintained by this map
38c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch * @param <V> the type of mapped values
39438d9883775e6ee31c097e2103a25571d2426cd9Elliott Hughes * @see HashMap
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
41c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Blochpublic class Hashtable<K, V> extends Dictionary<K, V>
42c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        implements Map<K, V>, Cloneable, Serializable {
43c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    /**
44c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * Min capacity (other than zero) for a Hashtable. Must be a power of two
45c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * greater than 1 (and less than 1 << 30).
46c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     */
47c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    private static final int MINIMUM_CAPACITY = 4;
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
49c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    /**
50c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * Max capacity for a Hashtable. Must be a power of two >= MINIMUM_CAPACITY.
51c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     */
52c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    private static final int MAXIMUM_CAPACITY = 1 << 30;
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
54c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    /**
55c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * An empty table shared by all zero-capacity maps (typically from default
56c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * constructor). It is never written to, and replaced on first put. Its size
57c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * is set to half the minimum, so that the first resize will create a
58c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * minimum-sized table.
59c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     */
60c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    private static final Entry[] EMPTY_TABLE
61c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            = new HashtableEntry[MINIMUM_CAPACITY >>> 1];
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
63c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    /**
64c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * The default load factor. Note that this implementation ignores the
65c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * load factor, but cannot do away with it entirely because it's
66438d9883775e6ee31c097e2103a25571d2426cd9Elliott Hughes     * mentioned in the API.
67c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     *
68c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * <p>Note that this constant has no impact on the behavior of the program,
69c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * but it is emitted as part of the serialized form. The load factor of
70c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * .75 is hardwired into the program, which uses cheap shifts in place of
71c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * expensive division.
72c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     */
73c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    private static final float DEFAULT_LOAD_FACTOR = .75F;
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
75c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    /**
76c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * The hash table.
77c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     */
78c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    private transient HashtableEntry<K, V>[] table;
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
80c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    /**
81c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * The number of mappings in this hash map.
82c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     */
83c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    private transient int size;
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
85c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    /**
86c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * Incremented by "structural modifications" to allow (best effort)
87c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * detection of concurrent modification.
88c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     */
89c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    private transient int modCount;
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
91c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    /**
92c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * The table is rehashed when its size exceeds this threshold.
93c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * The value of this field is generally .75 * capacity, except when
94c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * the capacity is zero, as described in the EMPTY_TABLE declaration
95c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * above.
96c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     */
97c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    private transient int threshold;
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
99c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    // Views - lazily initialized
100c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    private transient Set<K> keySet;
101c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    private transient Set<Entry<K, V>> entrySet;
102c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    private transient Collection<V> values;
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new {@code Hashtable} using the default capacity and load
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * factor.
107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
108c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    @SuppressWarnings("unchecked")
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Hashtable() {
110c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        table = (HashtableEntry<K, V>[]) EMPTY_TABLE;
111c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        threshold = -1; // Forces first put invocation to replace EMPTY_TABLE
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new {@code Hashtable} using the specified capacity and the
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * default load factor.
117f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param capacity
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the initial capacity.
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Hashtable(int capacity) {
122c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        if (capacity < 0) {
123c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            throw new IllegalArgumentException("Capacity: " + capacity);
124c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
125c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
126c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        if (capacity == 0) {
127c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            @SuppressWarnings("unchecked")
128c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            HashtableEntry<K, V>[] tab = (HashtableEntry<K, V>[]) EMPTY_TABLE;
129c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            table = tab;
130c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            threshold = -1; // Forces first put() to replace EMPTY_TABLE
131c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            return;
132c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
133c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
134c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        if (capacity < MINIMUM_CAPACITY) {
135c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            capacity = MINIMUM_CAPACITY;
136c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        } else if (capacity > MAXIMUM_CAPACITY) {
137c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            capacity = MAXIMUM_CAPACITY;
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
139c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            capacity = roundUpToPowerOfTwo(capacity);
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
141c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        makeTable(capacity);
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new {@code Hashtable} using the specified capacity and load
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * factor.
147f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param capacity
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the initial capacity.
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param loadFactor
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the initial load factor.
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Hashtable(int capacity, float loadFactor) {
154c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        this(capacity);
155c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
156c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        if (loadFactor <= 0 || Float.isNaN(loadFactor)) {
157c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            throw new IllegalArgumentException("Load factor: " + loadFactor);
158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
159c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
160c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        /*
161c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch         * Note that this implementation ignores loadFactor; it always uses
162438d9883775e6ee31c097e2103a25571d2426cd9Elliott Hughes         * a load factor of 3/4. This simplifies the code and generally
163c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch         * improves performance.
164c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch         */
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new instance of {@code Hashtable} containing the mappings
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * from the specified map.
170f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param map
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the mappings to add.
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Hashtable(Map<? extends K, ? extends V> map) {
175c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        this(capacityForInitSize(map.size()));
176c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        constructorPutAll(map);
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
179c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    /**
180c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * Inserts all of the elements of map into this Hashtable in a manner
181438d9883775e6ee31c097e2103a25571d2426cd9Elliott Hughes     * suitable for use by constructors and pseudo-constructors (i.e., clone,
182c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * readObject).
183c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     */
184c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    private void constructorPutAll(Map<? extends K, ? extends V> map) {
185c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        for (Entry<? extends K, ? extends V> e : map.entrySet()) {
186c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            constructorPut(e.getKey(), e.getValue());
187c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
191c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * Returns an appropriate capacity for the specified initial size. Does
192c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * not round the result up to a power of two; the caller must do this!
193c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * The returned value will be between 0 and MAXIMUM_CAPACITY (inclusive).
194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
195c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    private static int capacityForInitSize(int size) {
196c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        int result = (size >> 1) + size; // Multiply by 3/2 to allow for growth
197c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
198c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        // boolean expr is equivalent to result >= 0 && result<MAXIMUM_CAPACITY
199c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        return (result & ~(MAXIMUM_CAPACITY-1))==0 ? result : MAXIMUM_CAPACITY;
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new {@code Hashtable} with the same key/value pairs, capacity
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * and load factor.
205f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a shallow copy of this {@code Hashtable}.
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see java.lang.Cloneable
208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @SuppressWarnings("unchecked")
210c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    @Override public synchronized Object clone() {
211c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        /*
212c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch         * This could be made more efficient. It unnecessarily hashes all of
213c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch         * the elements in the map.
214c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch         */
215c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        Hashtable<K, V> result;
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
217c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            result = (Hashtable<K, V>) super.clone();
218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (CloneNotSupportedException e) {
219c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            throw new AssertionError(e);
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
222c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        // Restore clone to empty state, retaining our capacity and threshold
223c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        result.makeTable(table.length);
224c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        result.size = 0;
225c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        result.keySet = null;
226c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        result.entrySet = null;
227c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        result.values = null;
228c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
229c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        result.constructorPutAll(this);
230c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        return result;
231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
234c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * Returns true if this {@code Hashtable} has no key/value pairs.
235f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
236c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @return {@code true} if this {@code Hashtable} has no key/value pairs,
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code false} otherwise.
238c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @see #size
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
240c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    public synchronized boolean isEmpty() {
241c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        return size == 0;
242c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    }
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
244c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    /**
245c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * Returns the number of key/value pairs in this {@code Hashtable}.
246c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     *
247c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @return the number of key/value pairs in this {@code Hashtable}.
248c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @see #elements
249c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @see #keys
250c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     */
251c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    public synchronized int size() {
252c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        return size;
253c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    }
254c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
255c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    /**
256c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * Returns the value associated with the specified key in this
257c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * {@code Hashtable}.
258c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     *
259c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @param key
260c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     *            the key of the value returned.
261c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @return the value associated with the specified key, or {@code null} if
262c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     *         the specified key does not exist.
263c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @see #put
264c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     */
265c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    public synchronized V get(Object key) {
266c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        // Doug Lea's supplemental secondaryHash function (inlined)
267c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        int hash = key.hashCode();
268c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        hash ^= (hash >>> 20) ^ (hash >>> 12);
269c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        hash ^= (hash >>> 7) ^ (hash >>> 4);
270c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
271c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        HashtableEntry<K, V>[] tab = table;
272c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        for (HashtableEntry<K, V> e = tab[hash & (tab.length - 1)];
273c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                e != null; e = e.next) {
274c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            K eKey = e.key;
275c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            if (eKey == key || (e.hash == hash && key.equals(eKey))) {
276c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                return e.value;
277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
279c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        return null;
280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns true if this {@code Hashtable} contains the specified object as a
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * key of one of the key/value pairs.
285f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param key
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the object to look for as a key in this {@code Hashtable}.
288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if object is a key in this {@code Hashtable},
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code false} otherwise.
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #contains
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see java.lang.Object#equals
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized boolean containsKey(Object key) {
294c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        // Doug Lea's supplemental secondaryHash function (inlined)
295c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        int hash = key.hashCode();
296c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        hash ^= (hash >>> 20) ^ (hash >>> 12);
297c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        hash ^= (hash >>> 7) ^ (hash >>> 4);
298c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
299c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        HashtableEntry<K, V>[] tab = table;
300c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        for (HashtableEntry<K, V> e = tab[hash & (tab.length - 1)];
301c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                e != null; e = e.next) {
302c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            K eKey = e.key;
303c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            if (eKey == key || (e.hash == hash && key.equals(eKey))) {
304c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                return true;
305c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            }
306c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
307c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        return false;
308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Searches this {@code Hashtable} for the specified value.
312f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param value
314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the object to search for.
315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if {@code value} is a value of this
316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code Hashtable}, {@code false} otherwise.
317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
318c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    public synchronized boolean containsValue(Object value) {
319c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        if (value == null) {
320c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            throw new NullPointerException();
321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
322c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
323c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        HashtableEntry[] tab = table;
324c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        int len = tab.length;
325c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
326c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        for (int i = 0; i < len; i++) {
327c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            for (HashtableEntry e = tab[i]; e != null; e = e.next) {
328c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                if (value.equals(e.value)) {
329c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                    return true;
330c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                }
331f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            }
332c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
333c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        return false;
334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
337c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * Returns true if this {@code Hashtable} contains the specified object as
338c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * the value of at least one of the key/value pairs.
339f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
340c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @param value
341c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     *            the object to look for as a value in this {@code Hashtable}.
342c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @return {@code true} if object is a value in this {@code Hashtable},
343c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     *         {@code false} otherwise.
344c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @see #containsKey
345c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @see java.lang.Object#equals
346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
347c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    public boolean contains(Object value) {
348c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        return containsValue(value);
349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
352c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * Associate the specified value with the specified key in this
353c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * {@code Hashtable}. If the key already exists, the old value is replaced.
354c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * The key and value cannot be null.
355f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
356c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @param key
357c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     *            the key to add.
358c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @param value
359c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     *            the value to add.
360c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @return the old value associated with the specified key, or {@code null}
361c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     *         if the key did not exist.
362c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @see #elements
363c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @see #get
364c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @see #keys
365c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @see java.lang.Object#equals
366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
367c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    public synchronized V put(K key, V value) {
368c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        if (value == null) {
369c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            throw new NullPointerException();
370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
371c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        int hash = secondaryHash(key.hashCode());
372c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        HashtableEntry<K, V>[] tab = table;
373c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        int index = hash & (tab.length - 1);
374c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        HashtableEntry<K, V> first = tab[index];
375c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        for (HashtableEntry<K, V> e = first; e != null; e = e.next) {
376c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            if (e.hash == hash && key.equals(e.key)) {
377c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                V oldValue = e.value;
378c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                e.value = value;
379c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                return oldValue;
380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
381c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
383c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        // No entry for key is present; create one
384c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        modCount++;
385c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        if (size++ > threshold) {
386c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            rehash();  // Does nothing!!
387c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            tab = doubleCapacity();
388c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            index = hash & (tab.length - 1);
389c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            first = tab[index];
390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
391c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        tab[index] = new HashtableEntry<K, V>(key, value, hash, first);
392c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        return null;
393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
396c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * This method is just like put, except that it doesn't do things that
397c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * are inappropriate or unnecessary for constructors and pseudo-constructors
398c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * (i.e., clone, readObject). In particular, this method does not check to
399c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * ensure that capacity is sufficient, and does not increment modCount.
400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
401c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    private void constructorPut(K key, V value) {
402c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        if (value == null) {
403c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            throw new NullPointerException();
404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
405c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        int hash = secondaryHash(key.hashCode());
406c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        HashtableEntry<K, V>[] tab = table;
407c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        int index = hash & (tab.length - 1);
408c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        HashtableEntry<K, V> first = tab[index];
409c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        for (HashtableEntry<K, V> e = first; e != null; e = e.next) {
410c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            if (e.hash == hash && key.equals(e.key)) {
411c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                e.value = value;
412c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                return;
413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
416c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        // No entry for key is present; create one
417c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        tab[index] = new HashtableEntry<K, V>(key, value, hash, first);
418c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        size++;
419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
422c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * Copies every mapping to this {@code Hashtable} from the specified map.
423f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
424c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @param map
425c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     *            the map to copy mappings from.
426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
427c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    public synchronized void putAll(Map<? extends K, ? extends V> map) {
428c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        ensureCapacity(map.size());
429c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        for (Entry<? extends K, ? extends V> e : map.entrySet()) {
430c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            put(e.getKey(), e.getValue());
431c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
435c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * Ensures that the hash table has sufficient capacity to store the
436c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * specified number of mappings, with room to grow. If not, it increases the
437c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * capacity as appropriate. Like doubleCapacity, this method moves existing
438c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * entries to new buckets as appropriate. Unlike doubleCapacity, this method
439c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * can grow the table by factors of 2^n for n > 1. Hopefully, a single call
440c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * to this method will be faster than multiple calls to doubleCapacity.
441f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
442c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     *  <p>This method is called only by putAll.
443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
444c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    private void ensureCapacity(int numMappings) {
445c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        int newCapacity = roundUpToPowerOfTwo(capacityForInitSize(numMappings));
446c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        HashtableEntry<K, V>[] oldTable = table;
447c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        int oldCapacity = oldTable.length;
448c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        if (newCapacity <= oldCapacity) {
449c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            return;
450c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
451c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
452c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        rehash();  // Does nothing!!
453c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
454c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        if (newCapacity == oldCapacity << 1) {
455c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            doubleCapacity();
456c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            return;
457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
458c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
459c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        // We're growing by at least 4x, rehash in the obvious way
460c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        HashtableEntry<K, V>[] newTable = makeTable(newCapacity);
461c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        if (size != 0) {
462c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            int newMask = newCapacity - 1;
463c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            for (int i = 0; i < oldCapacity; i++) {
464c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                for (HashtableEntry<K, V> e = oldTable[i]; e != null;) {
465c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                    HashtableEntry<K, V> oldNext = e.next;
466c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                    int newIndex = e.hash & newMask;
467c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                    HashtableEntry<K, V> newNext = newTable[newIndex];
468c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                    newTable[newIndex] = e;
469c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                    e.next = newNext;
470c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                    e = oldNext;
471c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                }
472f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            }
473c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
477c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * Increases the capacity of this {@code Hashtable}. This method is called
478c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * when the size of this {@code Hashtable} exceeds the load factor.
479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
480c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    protected void rehash() {
481c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        /*
482c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch         * This method has no testable semantics, other than that it gets
483c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch         * called from time to time.
484c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch         */
485c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    }
486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
487c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    /**
488c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * Allocate a table of the given capacity and set the threshold accordingly.
489c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @param newCapacity must be a power of two
490c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     */
491c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    private HashtableEntry<K, V>[] makeTable(int newCapacity) {
492c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        @SuppressWarnings("unchecked") HashtableEntry<K, V>[] newTable
493c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                = (HashtableEntry<K, V>[]) new HashtableEntry[newCapacity];
494c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        table = newTable;
495c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        threshold = (newCapacity >> 1) + (newCapacity >> 2); // 3/4 capacity
496c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        return newTable;
497c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    }
498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
499c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    /**
500c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * Doubles the capacity of the hash table. Existing entries are placed in
501c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * the correct bucket on the enlarged table. If the current capacity is,
502c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * MAXIMUM_CAPACITY, this method is a no-op. Returns the table, which
503c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * will be new unless we were already at MAXIMUM_CAPACITY.
504c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     */
505c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    private HashtableEntry<K, V>[] doubleCapacity() {
506c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        HashtableEntry<K, V>[] oldTable = table;
507c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        int oldCapacity = oldTable.length;
508c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        if (oldCapacity == MAXIMUM_CAPACITY) {
509c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            return oldTable;
510c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
511c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        int newCapacity = oldCapacity << 1;
512c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        HashtableEntry<K, V>[] newTable = makeTable(newCapacity);
513c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        if (size == 0) {
514c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            return newTable;
515c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
517c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        for (int j = 0; j < oldCapacity; j++) {
518c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            /*
519c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch             * Rehash the bucket using the minimum number of field writes.
520c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch             * This is the most subtle and delicate code in the class.
521c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch             */
522c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            HashtableEntry<K, V> e = oldTable[j];
523c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            if (e == null) {
524c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                continue;
525c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            }
526c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            int highBit = e.hash & oldCapacity;
527c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            HashtableEntry<K, V> broken = null;
528c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            newTable[j | highBit] = e;
529c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            for (HashtableEntry<K,V> n = e.next; n != null; e = n, n = n.next) {
530c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                int nextHighBit = n.hash & oldCapacity;
531c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                if (nextHighBit != highBit) {
532c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                    if (broken == null)
533c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                        newTable[j | nextHighBit] = n;
534c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                    else
535c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                        broken.next = n;
536c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                    broken = e;
537c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                    highBit = nextHighBit;
538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
540c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            if (broken != null)
541c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                broken.next = null;
542c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
543c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        return newTable;
544c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    }
545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
546c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    /**
547c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * Removes the key/value pair with the specified key from this
548c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * {@code Hashtable}.
549c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     *
550c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @param key
551c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     *            the key to remove.
552c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @return the value associated with the specified key, or {@code null} if
553c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     *         the specified key did not exist.
554c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @see #get
555c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @see #put
556c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     */
557c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    public synchronized V remove(Object key) {
558c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        int hash = secondaryHash(key.hashCode());
559c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        HashtableEntry<K, V>[] tab = table;
560c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        int index = hash & (tab.length - 1);
561c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        for (HashtableEntry<K, V> e = tab[index], prev = null;
562c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                e != null; prev = e, e = e.next) {
563c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            if (e.hash == hash && key.equals(e.key)) {
564c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                if (prev == null) {
565c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                    tab[index] = e.next;
566c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                } else {
567c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                    prev.next = e.next;
568f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                }
569c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                modCount++;
570c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                size--;
571c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                return e.value;
572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
573c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
574c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        return null;
575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
577c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    /**
578c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * Removes all key/value pairs from this {@code Hashtable}, leaving the
579c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * size zero and the capacity unchanged.
580c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     *
581c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @see #isEmpty
582c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @see #size
583c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     */
584c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    public synchronized void clear() {
585c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        if (size != 0) {
586c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            Arrays.fill(table, null);
587c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            modCount++;
588c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            size = 0;
589c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
590c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    }
591f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
592c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    /**
593c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * Returns a set of the keys contained in this {@code Hashtable}. The set
594c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * is backed by this {@code Hashtable} so changes to one are reflected by
595c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * the other. The set does not support adding.
596c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     *
597c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @return a set of the keys.
598c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     */
599c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    public synchronized Set<K> keySet() {
600c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        Set<K> ks = keySet;
601c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        return (ks != null) ? ks : (keySet = new KeySet());
602c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    }
603f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
604c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    /**
605c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * Returns a collection of the values contained in this {@code Hashtable}.
606c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * The collection is backed by this {@code Hashtable} so changes to one are
607c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * reflected by the other. The collection does not support adding.
608c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     *
609c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @return a collection of the values.
610c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     */
611c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    public synchronized Collection<V> values() {
612c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        Collection<V> vs = values;
613c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        return (vs != null) ? vs : (values = new Values());
614c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    }
615f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
616c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    /**
617c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * Returns a set of the mappings contained in this {@code Hashtable}. Each
618c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * element in the set is a {@link Map.Entry}. The set is backed by this
619c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * {@code Hashtable} so changes to one are reflected by the other. The set
620c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * does not support adding.
621c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     *
622c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @return a set of the mappings.
623c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     */
624c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    public synchronized Set<Entry<K, V>> entrySet() {
625c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        Set<Entry<K, V>> es = entrySet;
626c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        return (es != null) ? es : (entrySet = new EntrySet());
627c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    }
628f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
629c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
630c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    /**
631c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * Returns an enumeration on the keys of this {@code Hashtable} instance.
632c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * The results of the enumeration may be affected if the contents of this
633c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * {@code Hashtable} are modified.
634c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     *
635c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @return an enumeration of the keys of this {@code Hashtable}.
636c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @see #elements
637c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @see #size
638c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @see Enumeration
639c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     */
640c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    public synchronized Enumeration<K> keys() {
641c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        return new KeyEnumeration();
642c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    }
643c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
644c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    /**
645c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * Returns an enumeration on the values of this {@code Hashtable}. The
646c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * results of the Enumeration may be affected if the contents of this
647c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * {@code Hashtable} are modified.
648c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     *
649c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @return an enumeration of the values of this {@code Hashtable}.
650c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @see #keys
651c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @see #size
652c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @see Enumeration
653c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     */
654c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    public synchronized Enumeration<V> elements() {
655c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        return new ValueEnumeration();
656c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    }
657c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
658c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    /**
659c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * Note: technically the methods of this class should synchronize the
660c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * backing map.  However, this would require them to have a reference
661438d9883775e6ee31c097e2103a25571d2426cd9Elliott Hughes     * to it, which would cause considerable bloat.  Moreover, the RI
662c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * behaves the same way.
663c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     */
664c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    private static class HashtableEntry<K, V> implements Entry<K, V> {
665c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        final K key;
666c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        V value;
667c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        final int hash;
668c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        HashtableEntry<K, V> next;
669c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
670c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        HashtableEntry(K key, V value, int hash, HashtableEntry<K, V> next) {
671c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            this.key = key;
672c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            this.value = value;
673c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            this.hash = hash;
674c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            this.next = next;
675f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
676f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
677c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public final K getKey() {
678c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            return key;
679f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
680f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
681c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public final V getValue() {
682c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            return value;
683c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
684c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
685c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public final V setValue(V value) {
686c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            if (value == null) {
687c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                throw new NullPointerException();
688c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            }
689c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            V oldValue = this.value;
690c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            this.value = value;
691c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            return oldValue;
692c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
693c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
694c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        @Override public final boolean equals(Object o) {
695c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            if (!(o instanceof Entry)) {
696f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                return false;
697f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            }
698c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            Entry<?, ?> e = (Entry<?, ?>) o;
699c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            return key.equals(e.getKey()) && value.equals(e.getValue());
700f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
701f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
702c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        @Override public final int hashCode() {
703c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            return key.hashCode() ^ value.hashCode();
704c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
705c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
706c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        @Override public final String toString() {
707c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            return key + "=" + value;
708c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
709c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    }
710c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
711c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    private abstract class HashIterator {
712c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        int nextIndex;
713c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        HashtableEntry<K, V> nextEntry;
714c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        HashtableEntry<K, V> lastEntryReturned;
715c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        int expectedModCount = modCount;
716c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
717c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        HashIterator() {
718c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            HashtableEntry<K, V>[] tab = table;
719c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            HashtableEntry<K, V> next = null;
720c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            while (next == null && nextIndex < tab.length) {
721c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                next = tab[nextIndex++];
722f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            }
723c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            nextEntry = next;
724f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
725f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
726c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public boolean hasNext() {
727c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            return nextEntry != null;
728c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
729c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
730c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        HashtableEntry<K, V> nextEntry() {
731c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            if (modCount != expectedModCount)
732c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                throw new ConcurrentModificationException();
733c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            if (nextEntry == null)
734c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                throw new NoSuchElementException();
735c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
736c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            HashtableEntry<K, V> entryToReturn = nextEntry;
737c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            HashtableEntry<K, V>[] tab = table;
738c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            HashtableEntry<K, V> next = entryToReturn.next;
739c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            while (next == null && nextIndex < tab.length) {
740c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                next = tab[nextIndex++];
741f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            }
742c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            nextEntry = next;
743c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            return lastEntryReturned = entryToReturn;
744f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
745f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
746c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        HashtableEntry<K, V> nextEntryNotFailFast() {
747c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            if (nextEntry == null)
748f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                throw new NoSuchElementException();
749c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
750c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            HashtableEntry<K, V> entryToReturn = nextEntry;
751c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            HashtableEntry<K, V>[] tab = table;
752c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            HashtableEntry<K, V> next = entryToReturn.next;
753c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            while (next == null && nextIndex < tab.length) {
754c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                next = tab[nextIndex++];
755f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            }
756c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            nextEntry = next;
757c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            return lastEntryReturned = entryToReturn;
758f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
759f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
760f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        public void remove() {
761c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            if (lastEntryReturned == null)
762c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                throw new IllegalStateException();
763c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            if (modCount != expectedModCount)
764c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                throw new ConcurrentModificationException();
765c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            Hashtable.this.remove(lastEntryReturned.key);
766c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            lastEntryReturned = null;
767c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            expectedModCount = modCount;
768f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
769f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    }
770f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
771c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    private final class KeyIterator extends HashIterator
772c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            implements Iterator<K> {
773c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public K next() { return nextEntry().key; }
774c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    }
775c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
776c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    private final class ValueIterator extends HashIterator
777c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            implements Iterator<V> {
778c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public V next() { return nextEntry().value; }
779c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    }
780c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
781c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    private final class EntryIterator extends HashIterator
782c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            implements Iterator<Entry<K, V>> {
783c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public Entry<K, V> next() { return nextEntry(); }
784c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    }
785c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
786c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    private final class KeyEnumeration extends HashIterator
787c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            implements Enumeration<K> {
788c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public boolean hasMoreElements() { return hasNext(); }
789c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public K nextElement() { return nextEntryNotFailFast().key; }
790c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    }
791c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
792c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    private final class ValueEnumeration extends HashIterator
793c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            implements Enumeration<V> {
794c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public boolean hasMoreElements() { return hasNext(); }
795c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public V nextElement() { return nextEntryNotFailFast().value; }
796adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
797adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
798adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
799c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * Returns true if this map contains the specified mapping.
800adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
801c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    private synchronized boolean containsMapping(Object key, Object value) {
802c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        int hash = secondaryHash(key.hashCode());
803c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        HashtableEntry<K, V>[] tab = table;
804c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        int index = hash & (tab.length - 1);
805c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        for (HashtableEntry<K, V> e = tab[index]; e != null; e = e.next) {
806c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            if (e.hash == hash && e.key.equals(key)) {
807c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                return e.value.equals(value);
808c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            }
809adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
810c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        return false; // No entry for key
811adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
812adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
813adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
814c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * Removes the mapping from key to value and returns true if this mapping
815c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * exists; otherwise, returns does nothing and returns false.
816adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
817c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    private synchronized boolean removeMapping(Object key, Object value) {
818c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        int hash = secondaryHash(key.hashCode());
819c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        HashtableEntry<K, V>[] tab = table;
820c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        int index = hash & (tab.length - 1);
821c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        for (HashtableEntry<K, V> e = tab[index], prev = null;
822c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                e != null; prev = e, e = e.next) {
823c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            if (e.hash == hash && e.key.equals(key)) {
824c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                if (!e.value.equals(value)) {
825c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                    return false;  // Map has wrong value for key
826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
827c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                if (prev == null) {
828c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                    tab[index] = e.next;
829c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                } else {
830c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                    prev.next = e.next;
831adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
832c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                modCount++;
833c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                size--;
834c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                return true;
835adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
836adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
837c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        return false; // No entry for key
838adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
839adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
840adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
841c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * Compares this {@code Hashtable} with the specified object and indicates
842c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * if they are equal. In order to be equal, {@code object} must be an
843c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * instance of Map and contain the same key/value pairs.
844f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
845c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @param object
846c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     *            the object to compare with this object.
847c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @return {@code true} if the specified object is equal to this Map,
848c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     *         {@code false} otherwise.
849c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @see #hashCode
850adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
851c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    @Override public synchronized boolean equals(Object object) {
852c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        return (object instanceof Map) &&
853c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                entrySet().equals(((Map<?, ?>)object).entrySet());
854c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    }
855c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
856c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    @Override public synchronized int hashCode() {
857c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        int result = 0;
858c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        for (Entry<K, V> e : entrySet()) {
859c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            K key = e.getKey();
860c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            V value = e.getValue();
861c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            if (key == this || value == this) {
862c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                continue;
863adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
864c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            result += (key != null ? key.hashCode() : 0)
865c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                    ^ (value != null ? value.hashCode() : 0);
866adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
867c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        return result;
868adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
869adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
870adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
871c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * A rough estimate of the number of characters per entry, for use
872c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * when creating a string buffer in the toString method.
873adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
874c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    private static final int CHARS_PER_ENTRY = 15;
875adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
876adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
877adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the string representation of this {@code Hashtable}.
878f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
879adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the string representation of this {@code Hashtable}.
880adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
881c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    @Override public synchronized String toString() {
882c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        StringBuilder result = new StringBuilder(CHARS_PER_ENTRY * size);
883c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        result.append('{');
884c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        Iterator<Entry<K, V>> i = entrySet().iterator();
885c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        boolean hasMore = i.hasNext();
886c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        while (hasMore) {
887c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            Entry<K, V> entry = i.next();
888c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
889c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            K key = entry.getKey();
890c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            result.append(key == this ? "(this Map)" : key.toString());
891c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
892c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            result.append('=');
893c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
894c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            V value = entry.getValue();
895c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            result.append(value == this ? "(this Map)" : value.toString());
896c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
897c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            if (hasMore = i.hasNext()) {
898c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                result.append(", ");
899c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            }
900adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
901adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
902c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        result.append('}');
903c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        return result.toString();
904c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    }
905c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
906c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    private final class KeySet extends AbstractSet<K> {
907c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public Iterator<K> iterator() {
908c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            return new KeyIterator();
909c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
910c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public int size() {
911c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            return Hashtable.this.size();
912c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
913c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public boolean contains(Object o) {
914c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            return containsKey(o);
915c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
916c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public boolean remove(Object o) {
917c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            synchronized (Hashtable.this) {
918c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                int oldSize = size;
919c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                Hashtable.this.remove(o);
920c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                return size != oldSize;
921adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
922adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
923c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public void clear() {
924c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            Hashtable.this.clear();
925c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
926c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public boolean removeAll(Collection<?> collection) {
927c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            synchronized (Hashtable.this) {
928c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                return super.removeAll(collection);
929c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            }
930c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
931c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public boolean retainAll(Collection<?> collection) {
932c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            synchronized (Hashtable.this) {
933c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                return super.retainAll(collection);
934c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            }
935c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
936c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public boolean containsAll(Collection<?> collection) {
937c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            synchronized (Hashtable.this) {
938c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                return super.containsAll(collection);
939c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            }
940c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
941c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public boolean equals(Object object) {
942c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            synchronized (Hashtable.this) {
943c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                return super.equals(object);
944c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            }
945c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
946c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public int hashCode() {
947c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            synchronized (Hashtable.this) {
948c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                return super.hashCode();
949c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            }
950c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
951c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public String toString() {
952c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            synchronized (Hashtable.this) {
953c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                return super.toString();
954c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            }
955c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
956c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public Object[] toArray() {
957c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            synchronized (Hashtable.this) {
958c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                return super.toArray();
959c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            }
960c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
961c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public <T> T[] toArray(T[] a) {
962c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            synchronized (Hashtable.this) {
963c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                return super.toArray(a);
964c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            }
965c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
966c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    }
967c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
968c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    private final class Values extends AbstractCollection<V> {
969c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public Iterator<V> iterator() {
970c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            return new ValueIterator();
971c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
972c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public int size() {
973c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            return Hashtable.this.size();
974c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
975c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public boolean contains(Object o) {
976c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            return containsValue(o);
977c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
978c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public void clear() {
979c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            Hashtable.this.clear();
980c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
981c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public boolean containsAll(Collection<?> collection) {
982c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            synchronized (Hashtable.this) {
983c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                return super.containsAll(collection);
984c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            }
985c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
986c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public String toString() {
987c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            synchronized (Hashtable.this) {
988c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                return super.toString();
989c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            }
990c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
991c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public Object[] toArray() {
992c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            synchronized (Hashtable.this) {
993c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                return super.toArray();
994c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            }
995c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
996c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public <T> T[] toArray(T[] a) {
997c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            synchronized (Hashtable.this) {
998c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                return super.toArray(a);
999c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            }
1000c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
1001c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    }
1002c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
1003c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    private final class EntrySet extends AbstractSet<Entry<K, V>> {
1004c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public Iterator<Entry<K, V>> iterator() {
1005c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            return new EntryIterator();
1006c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
1007c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public boolean contains(Object o) {
1008c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            if (!(o instanceof Entry))
1009c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                return false;
1010c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            Entry<?, ?> e = (Entry<?, ?>) o;
1011c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            return containsMapping(e.getKey(), e.getValue());
1012c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
1013c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public boolean remove(Object o) {
1014c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            if (!(o instanceof Entry))
1015c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                return false;
1016c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            Entry<?, ?> e = (Entry<?, ?>)o;
1017c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            return removeMapping(e.getKey(), e.getValue());
1018c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
1019c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public int size() {
1020c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            return Hashtable.this.size();
1021c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
1022c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public void clear() {
1023c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            Hashtable.this.clear();
1024c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
1025c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public boolean removeAll(Collection<?> collection) {
1026c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            synchronized (Hashtable.this) {
1027c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                return super.removeAll(collection);
1028c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            }
1029c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
1030c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public boolean retainAll(Collection<?> collection) {
1031c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            synchronized (Hashtable.this) {
1032c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                return super.retainAll(collection);
1033c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            }
1034c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
1035c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public boolean containsAll(Collection<?> collection) {
1036c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            synchronized (Hashtable.this) {
1037c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                return super.containsAll(collection);
1038c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            }
1039c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
1040c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public boolean equals(Object object) {
1041c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            synchronized (Hashtable.this) {
1042c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                return super.equals(object);
1043c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            }
1044c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
1045c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public int hashCode() {
1046c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            return Hashtable.this.hashCode();
1047c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
1048c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public String toString() {
1049c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            synchronized (Hashtable.this) {
1050c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                return super.toString();
1051c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            }
1052c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
1053c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public Object[] toArray() {
1054c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            synchronized (Hashtable.this) {
1055c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                return super.toArray();
1056c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            }
1057c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
1058c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        public <T> T[] toArray(T[] a) {
1059c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            synchronized (Hashtable.this) {
1060c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch                return super.toArray(a);
1061c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            }
1062adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1063adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1064adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1065adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1066c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * Applies a supplemental hash function to a given hashCode, which defends
1067c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * against poor quality hash functions. This is critical because Hashtable
1068c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * uses power-of-two length hash tables, that otherwise encounter collisions
1069c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * for hashCodes that do not differ in lower or upper bits.
1070c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     */
1071c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    private static int secondaryHash(int h) {
1072c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        // Doug Lea's supplemental hash function
1073c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        h ^= (h >>> 20) ^ (h >>> 12);
1074c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        return h ^ (h >>> 7) ^ (h >>> 4);
1075c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    }
1076c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
1077c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    /**
1078c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * Returns the smallest power of two >= its argument, with several caveats:
1079c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * If the argument is negative but not Integer.MIN_VALUE, the method returns
1080c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * zero. If the argument is > 2^30 or equal to Integer.MIN_VALUE, the method
1081c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * returns Integer.MIN_VALUE. If the argument is zero, the method returns
1082c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * zero.
1083adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1084c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    private static int roundUpToPowerOfTwo(int i) {
1085c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        i--; // If input is a power of two, shift its high-order bit right
1086c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
1087c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        // "Smear" the high-order bit all the way to the right
1088c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        i |= i >>>  1;
1089c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        i |= i >>>  2;
1090c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        i |= i >>>  4;
1091c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        i |= i >>>  8;
1092c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        i |= i >>> 16;
1093c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
1094c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        return i + 1;
1095adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1096adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1097c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    private static final long serialVersionUID = 1421746759512286392L;
1098c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
1099c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    /**
1100c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * Serializable fields.
1101c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     *
1102c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     * @serialField loadFactor float
1103c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     *              load factor for this Hashtable
1104c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch     */
1105c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    private static final ObjectStreamField[] serialPersistentFields = {
1106c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        new ObjectStreamField("threshold", Integer.TYPE),
1107c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        new ObjectStreamField("loadFactor", Float.TYPE)
1108c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch    };
1109c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
1110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private synchronized void writeObject(ObjectOutputStream stream)
1111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws IOException {
1112c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        // Emulate loadFactor field for other implementations to read
1113c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        ObjectOutputStream.PutField fields = stream.putFields();
1114c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        fields.put("threshold",  (int) (DEFAULT_LOAD_FACTOR * table.length));
1115c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        fields.put("loadFactor", DEFAULT_LOAD_FACTOR);
1116c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        stream.writeFields();
1117c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
1118c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        stream.writeInt(table.length); // Capacity
1119c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        stream.writeInt(size);
1120c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        for (Entry<K, V> e : entrySet()) {
1121c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            stream.writeObject(e.getKey());
1122c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            stream.writeObject(e.getValue());
1123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void readObject(ObjectInputStream stream) throws IOException,
1127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ClassNotFoundException {
1128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        stream.defaultReadObject();
1129c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        int capacity = stream.readInt();
1130c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        if (capacity < 0) {
1131c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            throw new InvalidObjectException("Capacity: " + capacity);
1132c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
1133c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        if (capacity < MINIMUM_CAPACITY) {
1134c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            capacity = MINIMUM_CAPACITY;
1135c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        } else if (capacity > MAXIMUM_CAPACITY) {
1136c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            capacity = MAXIMUM_CAPACITY;
1137c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        } else {
1138c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            capacity = roundUpToPowerOfTwo(capacity);
1139c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
1140c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        makeTable(capacity);
1141c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
1142c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        int size = stream.readInt();
1143c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        if (size < 0) {
1144c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            throw new InvalidObjectException("Size: " + size);
1145c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        }
1146c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch
1147c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch        for (int i = 0; i < size; i++) {
1148c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            @SuppressWarnings("unchecked") K key = (K) stream.readObject();
1149c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            @SuppressWarnings("unchecked") V val = (V) stream.readObject();
1150c0a4d9b35cbdd33dcc8e6a78a829573f0ed9bf6dJoshua Bloch            constructorPut(key, val);
1151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
1154