PageRenderTime 49ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/projects/netbeans-7.3/cnd.repository/src/org/netbeans/modules/cnd/repository/util/LongHashMap.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 931 lines | 479 code | 79 blank | 373 comment | 117 complexity | 951ba56beac8e0acce32d74fea2b1b46 MD5 | raw file
  1. /*
  2. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  3. *
  4. * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
  5. *
  6. * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  7. * Other names may be trademarks of their respective owners.
  8. *
  9. * The contents of this file are subject to the terms of either the GNU
  10. * General Public License Version 2 only ("GPL") or the Common
  11. * Development and Distribution License("CDDL") (collectively, the
  12. * "License"). You may not use this file except in compliance with the
  13. * License. You can obtain a copy of the License at
  14. * http://www.netbeans.org/cddl-gplv2.html
  15. * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  16. * specific language governing permissions and limitations under the
  17. * License. When distributing the software, include this License Header
  18. * Notice in each file and include the License file at
  19. * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
  20. * particular file as subject to the "Classpath" exception as provided
  21. * by Oracle in the GPL Version 2 section of the License file that
  22. * accompanied this code. If applicable, add the following below the
  23. * License Header, with the fields enclosed by brackets [] replaced by
  24. * your own identifying information:
  25. * "Portions Copyrighted [year] [name of copyright owner]"
  26. *
  27. * Contributor(s):
  28. *
  29. * The Original Software is NetBeans. The Initial Developer of the Original
  30. * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
  31. * Microsystems, Inc. All Rights Reserved.
  32. *
  33. * If you wish your version of this file to be governed by only the CDDL
  34. * or only the GPL Version 2, indicate your decision by adding
  35. * "[Contributor] elects to include this software in this distribution
  36. * under the [CDDL or GPL Version 2] license." If you do not indicate a
  37. * single choice of license, a recipient has the option to distribute
  38. * your version of this file under either the CDDL, the GPL Version 2 or
  39. * to extend the choice of license to its licensees as provided above.
  40. * However, if you add GPL Version 2 code and therefore, elected the GPL
  41. * Version 2 license, then the option applies only if the new code is
  42. * made subject to such option by the copyright holder.
  43. */
  44. package org.netbeans.modules.cnd.repository.util;
  45. import java.util.AbstractSet;
  46. import java.util.Collection;
  47. import java.util.ConcurrentModificationException;
  48. import java.util.Hashtable;
  49. import java.util.Iterator;
  50. import java.util.Map;
  51. import java.util.NoSuchElementException;
  52. import java.util.Set;
  53. import java.util.TreeMap;
  54. /**
  55. * Hash table based implementation of the <tt>Map</tt> interface. This
  56. * implementation provides all of the optional map operations, and permits
  57. * <tt>null</tt> values and the <tt>null</tt> key. (The <tt>LongHashMap</tt>
  58. * class is roughly equivalent to <tt>Hashtable</tt>, except that it is
  59. * unsynchronized and permits nulls.) This class makes no guarantees as to
  60. * the order of the map; in particular, it does not guarantee that the order
  61. * will remain constant over time.
  62. *
  63. * <p>This implementation provides constant-time performance for the basic
  64. * operations (<tt>get</tt> and <tt>put</tt>), assuming the hash function
  65. * disperses the elements properly among the buckets. Iteration over
  66. * collection views requires time proportional to the "capacity" of the
  67. * <tt>LongHashMap</tt> instance (the number of buckets) plus its size (the number
  68. * of key-value mappings). Thus, it's very important not to set the initial
  69. * capacity too high (or the load factor too low) if iteration performance is
  70. * important.
  71. *
  72. * <p>An instance of <tt>LongHashMap</tt> has two parameters that affect its
  73. * performance: <i>initial capacity</i> and <i>load factor</i>. The
  74. * <i>capacity</i> is the number of buckets in the hash table, and the initial
  75. * capacity is simply the capacity at the time the hash table is created. The
  76. * <i>load factor</i> is a measure of how full the hash table is allowed to
  77. * get before its capacity is automatically increased. When the number of
  78. * entries in the hash table exceeds the product of the load factor and the
  79. * current capacity, the capacity is roughly doubled by calling the
  80. * <tt>rehash</tt> method.
  81. *
  82. * <p>As a general rule, the default load factor (.75) offers a good tradeoff
  83. * between time and space costs. Higher values decrease the space overhead
  84. * but increase the lookup cost (reflected in most of the operations of the
  85. * <tt>LongHashMap</tt> class, including <tt>get</tt> and <tt>put</tt>). The
  86. * expected number of entries in the map and its load factor should be taken
  87. * into account when setting its initial capacity, so as to minimize the
  88. * number of <tt>rehash</tt> operations. If the initial capacity is greater
  89. * than the maximum number of entries divided by the load factor, no
  90. * <tt>rehash</tt> operations will ever occur.
  91. *
  92. * <p>If many mappings are to be stored in a <tt>LongHashMap</tt> instance,
  93. * creating it with a sufficiently large capacity will allow the mappings to
  94. * be stored more efficiently than letting it perform automatic rehashing as
  95. * needed to grow the table.
  96. *
  97. * <p><b>Note that this implementation is not synchronized.</b> If multiple
  98. * threads access this map concurrently, and at least one of the threads
  99. * modifies the map structurally, it <i>must</i> be synchronized externally.
  100. * (A structural modification is any operation that adds or deletes one or
  101. * more mappings; merely changing the value associated with a key that an
  102. * instance already contains is not a structural modification.) This is
  103. * typically accomplished by synchronizing on some object that naturally
  104. * encapsulates the map. If no such object exists, the map should be
  105. * "wrapped" using the <tt>Collections.synchronizedMap</tt> method. This is
  106. * best done at creation time, to prevent accidental unsynchronized access to
  107. * the map: <pre> Map m = Collections.synchronizedMap(new LongHashMap(...));
  108. * </pre>
  109. *
  110. * <p>The iterators returned by all of this class's "collection view methods"
  111. * are <i>fail-fast</i>: if the map is structurally modified at any time after
  112. * the iterator is created, in any way except through the iterator's own
  113. * <tt>remove</tt> or <tt>add</tt> methods, the iterator will throw a
  114. * <tt>ConcurrentModificationException</tt>. Thus, in the face of concurrent
  115. * modification, the iterator fails quickly and cleanly, rather than risking
  116. * arbitrary, non-deterministic behavior at an undetermined time in the
  117. * future.
  118. *
  119. * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
  120. * as it is, generally speaking, impossible to make any hard guarantees in the
  121. * presence of unsynchronized concurrent modification. Fail-fast iterators
  122. * throw <tt>ConcurrentModificationException</tt> on a best-effort basis.
  123. * Therefore, it would be wrong to write a program that depended on this
  124. * exception for its correctness: <i>the fail-fast behavior of iterators
  125. * should be used only to detect bugs.</i>
  126. *
  127. * <p>This class is a member of the
  128. * <a href="{@docRoot}/../guide/collections/index.html">
  129. * Java Collections Framework</a>.
  130. *
  131. * @author Doug Lea
  132. * @author Josh Bloch
  133. * @author Arthur van Hoff
  134. * @author Neal Gafter
  135. * @version 1.65, 03/03/05
  136. * @see Object#hashCode()
  137. * @see Collection
  138. * @see Map
  139. * @see TreeMap
  140. * @see Hashtable
  141. * @since 1.2
  142. */
  143. public class LongHashMap<K> //extends AbstractMap<K>
  144. //implements Map<K>, Cloneable, Serializable
  145. {
  146. public static final long NO_VALUE = Long.MIN_VALUE;
  147. /**
  148. * The default initial capacity - MUST be a power of two.
  149. */
  150. static final int DEFAULT_INITIAL_CAPACITY = 16;
  151. /**
  152. * The maximum capacity, used if a higher value is implicitly specified
  153. * by either of the constructors with arguments.
  154. * MUST be a power of two <= 1<<30.
  155. */
  156. static final int MAXIMUM_CAPACITY = 1 << 30;
  157. /**
  158. * The load factor used when none specified in constructor.
  159. **/
  160. static final float DEFAULT_LOAD_FACTOR = 0.75f;
  161. /**
  162. * The table, resized as necessary. Length MUST Always be a power of two.
  163. */
  164. transient Entry<K>[] table;
  165. /**
  166. * The number of key-value mappings contained in this identity hash map.
  167. */
  168. transient int size;
  169. /**
  170. * The next size value at which to resize (capacity * load factor).
  171. * @serial
  172. */
  173. int threshold;
  174. /**
  175. * The load factor for the hash table.
  176. *
  177. * @serial
  178. */
  179. final float loadFactor;
  180. /**
  181. * The number of times this LongHashMap has been structurally modified
  182. * Structural modifications are those that change the number of mappings in
  183. * the LongHashMap or otherwise modify its internal structure (e.g.,
  184. * rehash). This field is used to make iterators on Collection-views of
  185. * the LongHashMap fail-fast. (See ConcurrentModificationException).
  186. */
  187. transient volatile int modCount;
  188. /**
  189. * Constructs an empty <tt>LongHashMap</tt> with the specified initial
  190. * capacity and load factor.
  191. *
  192. * @param initialCapacity The initial capacity.
  193. * @param loadFactor The load factor.
  194. * @throws IllegalArgumentException if the initial capacity is negative
  195. * or the load factor is nonpositive.
  196. */
  197. public LongHashMap(int initialCapacity, float loadFactor) {
  198. if (initialCapacity < 0) {
  199. throw new IllegalArgumentException("Illegal initial capacity: " + // NOI18N
  200. initialCapacity);
  201. }
  202. if (initialCapacity > MAXIMUM_CAPACITY) {
  203. initialCapacity = MAXIMUM_CAPACITY;
  204. }
  205. if (loadFactor <= 0 || Float.isNaN(loadFactor)) {
  206. throw new IllegalArgumentException("Illegal load factor: " + // NOI18N
  207. loadFactor);
  208. }
  209. // Find a power of 2 >= initialCapacity
  210. int capacity = 1;
  211. while (capacity < initialCapacity) {
  212. capacity <<= 1;
  213. }
  214. this.loadFactor = loadFactor;
  215. threshold = (int) (capacity * loadFactor);
  216. @SuppressWarnings("unchecked")
  217. Entry<K>[] ar = new Entry[capacity];
  218. table = ar;
  219. init();
  220. }
  221. /**
  222. * Constructs an empty <tt>LongHashMap</tt> with the specified initial
  223. * capacity and the default load factor (0.75).
  224. *
  225. * @param initialCapacity the initial capacity.
  226. * @throws IllegalArgumentException if the initial capacity is negative.
  227. */
  228. public LongHashMap(int initialCapacity) {
  229. this(initialCapacity, DEFAULT_LOAD_FACTOR);
  230. }
  231. /**
  232. * Constructs an empty <tt>LongHashMap</tt> with the default initial capacity
  233. * (16) and the default load factor (0.75).
  234. */
  235. public LongHashMap() {
  236. this.loadFactor = DEFAULT_LOAD_FACTOR;
  237. threshold = (int) (DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);
  238. @SuppressWarnings("unchecked")
  239. Entry<K>[] ar = new Entry[DEFAULT_INITIAL_CAPACITY];
  240. table = ar;
  241. init();
  242. }
  243. // internal utilities
  244. /**
  245. * Initialization hook for subclasses. This method is called
  246. * in all constructors and pseudo-constructors (clone, readObject)
  247. * after LongHashMap has been initialized but before any entries have
  248. * been inserted. (In the absence of this method, readObject would
  249. * require explicit knowledge of subclasses.)
  250. */
  251. private void init() {
  252. }
  253. /**
  254. * Value representing null keys inside tables.
  255. */
  256. static final Object NULL_KEY = new Object();
  257. /**
  258. * Returns internal representation for key. Use NULL_KEY if key is null.
  259. */
  260. static <T> Object maskNull(T key) {
  261. return key == null ? NULL_KEY : key;
  262. }
  263. /**
  264. * Returns key represented by specified internal representation.
  265. */
  266. static <T> T unmaskNull(T key) {
  267. return (key == NULL_KEY ? null : key);
  268. }
  269. /**
  270. * Check for equality of non-null reference x and possibly-null y.
  271. */
  272. static boolean eq(Object x, Object y) {
  273. return x == y || x.equals(y);
  274. }
  275. /**
  276. * Returns index for hash code h.
  277. */
  278. static int indexFor(int h, int length) {
  279. return h & (length - 1);
  280. }
  281. /**
  282. * Returns the number of key-value mappings in this map.
  283. *
  284. * @return the number of key-value mappings in this map.
  285. */
  286. public int size() {
  287. return size;
  288. }
  289. /**
  290. * Returns <tt>true</tt> if this map contains no key-value mappings.
  291. *
  292. * @return <tt>true</tt> if this map contains no key-value mappings.
  293. */
  294. public boolean isEmpty() {
  295. return size == 0;
  296. }
  297. /**
  298. * Returns the value to which the specified key is mapped in this identity
  299. * hash map, or <tt>null</tt> if the map contains no mapping for this key.
  300. * A return value of <tt>null</tt> does not <i>necessarily</i> indicate
  301. * that the map contains no mapping for the key; it is also possible that
  302. * the map explicitly maps the key to <tt>null</tt>. The
  303. * <tt>containsKey</tt> method may be used to distinguish these two cases.
  304. *
  305. * @param key the key whose associated value is to be returned.
  306. * @return the value to which this map maps the specified key, or
  307. * <tt>null</tt> if the map contains no mapping for this key.
  308. * @see #put(Object, Object)
  309. */
  310. public long get(Object key) {
  311. if (key == null) {
  312. return getForNullKey();
  313. }
  314. int hash = key.hashCode();
  315. for (Entry<K> e = table[indexFor(hash, table.length)];
  316. e != null;
  317. e = e.next) {
  318. Object k;
  319. if (e.key.hashCode() == hash && ((k = e.key) == key || key.equals(k))) {
  320. return e.value;
  321. }
  322. }
  323. return NO_VALUE;
  324. }
  325. private long getForNullKey() {
  326. int hash = NULL_KEY.hashCode();
  327. int i = indexFor(hash, table.length);
  328. Entry<K> e = table[i];
  329. while (true) {
  330. if (e == null) {
  331. return NO_VALUE;
  332. }
  333. if (e.key == NULL_KEY) {
  334. return e.value;
  335. }
  336. e = e.next;
  337. }
  338. }
  339. /**
  340. * Returns <tt>true</tt> if this map contains a mapping for the
  341. * specified key.
  342. *
  343. * @param key The key whose presence in this map is to be tested
  344. * @return <tt>true</tt> if this map contains a mapping for the specified
  345. * key.
  346. */
  347. public boolean containsKey(Object key) {
  348. Object k = maskNull(key);
  349. int hash = k.hashCode();
  350. int i = indexFor(hash, table.length);
  351. Entry e = table[i];
  352. while (e != null) {
  353. if (e.key.hashCode() == hash && eq(k, e.key)) {
  354. return true;
  355. }
  356. e = e.next;
  357. }
  358. return false;
  359. }
  360. /**
  361. * Returns the entry associated with the specified key in the
  362. * LongHashMap. Returns null if the LongHashMap contains no mapping
  363. * for this key.
  364. */
  365. public Entry<K> getEntry(Object key) {
  366. Object k = maskNull(key);
  367. int hash = k.hashCode();
  368. int i = indexFor(hash, table.length);
  369. Entry<K> e = table[i];
  370. while (e != null && !(e.key.hashCode() == hash && eq(k, e.key))) {
  371. e = e.next;
  372. }
  373. return e;
  374. }
  375. /**
  376. * Associates the specified value with the specified key in this map.
  377. * If the map previously contained a mapping for this key, the old
  378. * value is replaced.
  379. *
  380. * @param key key with which the specified value is to be associated.
  381. * @param value value to be associated with the specified key.
  382. * @return previous value associated with specified key, or <tt>null</tt>
  383. * if there was no mapping for key. A <tt>null</tt> return can
  384. * also indicate that the LongHashMap previously associated
  385. * <tt>null</tt> with the specified key.
  386. */
  387. public long put(K key, long value) {
  388. if (key == null) {
  389. return putForNullKey(value);
  390. }
  391. int hash = key.hashCode();
  392. int i = indexFor(hash, table.length);
  393. for (Entry<K> e = table[i]; e != null; e = e.next) {
  394. Object k;
  395. if (e.key.hashCode() == hash && ((k = e.key) == key || key.equals(k))) {
  396. long oldValue = e.value;
  397. e.value = value;
  398. e.recordAccess(this);
  399. return oldValue;
  400. }
  401. }
  402. modCount++;
  403. addEntry(key, value, i);
  404. return NO_VALUE;
  405. }
  406. private long putForNullKey(long value) {
  407. int hash = NULL_KEY.hashCode();
  408. int i = indexFor(hash, table.length);
  409. for (Entry<K> e = table[i]; e != null; e = e.next) {
  410. if (e.key == NULL_KEY) {
  411. long oldValue = e.value;
  412. e.value = value;
  413. e.recordAccess(this);
  414. return oldValue;
  415. }
  416. }
  417. modCount++;
  418. @SuppressWarnings("unchecked")
  419. K nullKey = (K) NULL_KEY;
  420. addEntry(nullKey, value, i);
  421. return NO_VALUE;
  422. }
  423. /**
  424. * This method is used instead of put by constructors and
  425. * pseudoconstructors (clone, readObject). It does not resize the table,
  426. * check for comodification, etc. It calls createEntry rather than
  427. * addEntry.
  428. */
  429. // private void putForCreate(K key, long value) {
  430. // K k = maskNull(key);
  431. // int hash = hash(k.hashCode());
  432. // int i = indexFor(hash, table.length);
  433. //
  434. // /**
  435. // * Look for preexisting entry for key. This will never happen for
  436. // * clone or deserialize. It will only happen for construction if the
  437. // * input Map is a sorted map whose ordering is inconsistent w/ equals.
  438. // */
  439. // for (Entry<K> e = table[i]; e != null; e = e.next) {
  440. // if (e.hash == hash && eq(k, e.key)) {
  441. // e.value = value;
  442. // return;
  443. // }
  444. // }
  445. //
  446. // createEntry(hash, k, value, i);
  447. // }
  448. /**
  449. * Rehashes the contents of this map into a new array with a
  450. * larger capacity. This method is called automatically when the
  451. * number of keys in this map reaches its threshold.
  452. *
  453. * If current capacity is MAXIMUM_CAPACITY, this method does not
  454. * resize the map, but sets threshold to Integer.MAX_VALUE.
  455. * This has the effect of preventing future calls.
  456. *
  457. * @param newCapacity the new capacity, MUST be a power of two;
  458. * must be greater than current capacity unless current
  459. * capacity is MAXIMUM_CAPACITY (in which case value
  460. * is irrelevant).
  461. */
  462. void resize(int newCapacity) {
  463. Entry<K>[] oldTable = table;
  464. int oldCapacity = oldTable.length;
  465. if (oldCapacity == MAXIMUM_CAPACITY) {
  466. threshold = Integer.MAX_VALUE;
  467. return;
  468. }
  469. @SuppressWarnings("unchecked")
  470. Entry<K>[] newTable = new Entry[newCapacity];
  471. transfer(newTable);
  472. table = newTable;
  473. threshold = (int) (newCapacity * loadFactor);
  474. }
  475. /**
  476. * Transfer all entries from current table to newTable.
  477. */
  478. void transfer(Entry<K>[] newTable) {
  479. Entry<K>[] src = table;
  480. int newCapacity = newTable.length;
  481. for (int j = 0; j < src.length; j++) {
  482. Entry<K> e = src[j];
  483. if (e != null) {
  484. src[j] = null;
  485. do {
  486. Entry<K> next = e.next;
  487. int i = indexFor(e.key.hashCode(), newCapacity);
  488. e.next = newTable[i];
  489. newTable[i] = e;
  490. e = next;
  491. } while (e != null);
  492. }
  493. }
  494. }
  495. public long remove(Object key) {
  496. Entry<K> e = removeEntryForKey(key);
  497. return (e == null ? NO_VALUE : e.value);
  498. }
  499. /**
  500. * Removes and returns the entry associated with the specified key
  501. * in the LongHashMap. Returns null if the LongHashMap contains no mapping
  502. * for this key.
  503. */
  504. Entry<K> removeEntryForKey(Object key) {
  505. Object k = maskNull(key);
  506. int hash = k.hashCode();
  507. int i = indexFor(hash, table.length);
  508. Entry<K> prev = table[i];
  509. Entry<K> e = prev;
  510. while (e != null) {
  511. Entry<K> next = e.next;
  512. if (e.key.hashCode() == hash && eq(k, e.key)) {
  513. modCount++;
  514. size--;
  515. if (prev == e) {
  516. table[i] = next;
  517. } else {
  518. prev.next = next;
  519. }
  520. e.recordRemoval(this);
  521. return e;
  522. }
  523. prev = e;
  524. e = next;
  525. }
  526. return e;
  527. }
  528. /**
  529. * Special version of remove for EntrySet.
  530. */
  531. Entry<K> removeMapping(Object o) {
  532. if (!(o instanceof Map.Entry)) {
  533. return null;
  534. }
  535. @SuppressWarnings("unchecked")
  536. LongHashMap.Entry<K> entry = (LongHashMap.Entry<K>) o;
  537. Object k = maskNull(entry.getKey());
  538. int hash = k.hashCode();
  539. int i = indexFor(hash, table.length);
  540. Entry<K> prev = table[i];
  541. Entry<K> e = prev;
  542. while (e != null) {
  543. Entry<K> next = e.next;
  544. if (e.key.hashCode() == hash && e.equals(entry)) {
  545. modCount++;
  546. size--;
  547. if (prev == e) {
  548. table[i] = next;
  549. } else {
  550. prev.next = next;
  551. }
  552. e.recordRemoval(this);
  553. return e;
  554. }
  555. prev = e;
  556. e = next;
  557. }
  558. return e;
  559. }
  560. /**
  561. * Removes all mappings from this map.
  562. */
  563. public void clear() {
  564. modCount++;
  565. Entry[] tab = table;
  566. for (int i = 0; i < tab.length; i++) {
  567. tab[i] = null;
  568. }
  569. size = 0;
  570. }
  571. /**
  572. * Returns <tt>true</tt> if this map maps one or more keys to the
  573. * specified value.
  574. *
  575. * @param value value whose presence in this map is to be tested.
  576. * @return <tt>true</tt> if this map maps one or more keys to the
  577. * specified value.
  578. */
  579. public boolean containsValue(Object value) {
  580. if (value == null) {
  581. return containsNullValue();
  582. }
  583. Entry[] tab = table;
  584. for (int i = 0; i < tab.length; i++) {
  585. for (Entry e = tab[i]; e != null; e = e.next) {
  586. if (value.equals(e.value)) {
  587. return true;
  588. }
  589. }
  590. }
  591. return false;
  592. }
  593. /**
  594. * Special-case code for containsValue with null argument
  595. **/
  596. private boolean containsNullValue() {
  597. Entry[] tab = table;
  598. for (int i = 0; i < tab.length; i++) {
  599. for (Entry e = tab[i]; e != null; e = e.next) {
  600. if (e.value == NO_VALUE) {
  601. return true;
  602. }
  603. }
  604. }
  605. return false;
  606. }
  607. public static class Entry<K> /*implements Map.Entry<K>*/ {
  608. final K key;
  609. long value;
  610. Entry<K> next;
  611. /**
  612. * Create new entry.
  613. */
  614. Entry(K k, long v, Entry<K> n) {
  615. value = v;
  616. next = n;
  617. key = k;
  618. }
  619. public K getKey() {
  620. return LongHashMap.<K>unmaskNull(key);
  621. }
  622. public long getValue() {
  623. return value;
  624. }
  625. public long setValue(long newValue) {
  626. long oldValue = value;
  627. value = newValue;
  628. return oldValue;
  629. }
  630. @Override
  631. public boolean equals(Object o) {
  632. if (!(o instanceof Entry)) {
  633. return false;
  634. }
  635. Entry e = (Entry) o;
  636. Object k1 = getKey();
  637. Object k2 = e.getKey();
  638. if (k1 == k2 || (k1 != null && k1.equals(k2))) {
  639. long v1 = getValue();
  640. long v2 = e.getValue();
  641. if (v1 == v2) {
  642. return true;
  643. }
  644. }
  645. return false;
  646. }
  647. @Override
  648. public int hashCode() {
  649. return (int) (value ^ (value >>> 32));
  650. }
  651. @Override
  652. public String toString() {
  653. return getKey() + "=" + getValue(); // NOI18N
  654. }
  655. /**
  656. * This method is invoked whenever the value in an entry is
  657. * overwritten by an invocation of put(k,v) for a key k that's already
  658. * in the LongHashMap.
  659. */
  660. void recordAccess(LongHashMap<K> m) {
  661. }
  662. /**
  663. * This method is invoked whenever the entry is
  664. * removed from the table.
  665. */
  666. void recordRemoval(LongHashMap<K> m) {
  667. }
  668. }
  669. /**
  670. * Add a new entry with the specified key, value and hash code to
  671. * the specified bucket. It is the responsibility of this
  672. * method to resize the table if appropriate.
  673. *
  674. * Subclass overrides this to alter the behavior of put method.
  675. */
  676. void addEntry(K key, long value, int bucketIndex) {
  677. Entry<K> e = table[bucketIndex];
  678. table[bucketIndex] = new Entry<K>(key, value, e);
  679. if (size++ >= threshold) {
  680. resize(2 * table.length);
  681. }
  682. }
  683. private abstract class HashIterator<E> implements Iterator<E> {
  684. Entry<K> next; // next entry to return
  685. int expectedModCount; // For fast-fail
  686. int index; // current slot
  687. Entry<K> current; // current entry
  688. HashIterator() {
  689. expectedModCount = modCount;
  690. Entry<K>[] t = table;
  691. int i = t.length;
  692. Entry<K> n = null;
  693. if (size != 0) { // advance to first entry
  694. while (i > 0 && (n = t[--i]) == null) {
  695. }
  696. }
  697. next = n;
  698. index = i;
  699. }
  700. @Override
  701. public boolean hasNext() {
  702. return next != null;
  703. }
  704. Entry<K> nextEntry() {
  705. if (modCount != expectedModCount) {
  706. throw new ConcurrentModificationException();
  707. }
  708. Entry<K> e = next;
  709. if (e == null) {
  710. throw new NoSuchElementException();
  711. }
  712. Entry<K> n = e.next;
  713. Entry<K>[] t = table;
  714. int i = index;
  715. while (n == null && i > 0) {
  716. n = t[--i];
  717. }
  718. index = i;
  719. next = n;
  720. return current = e;
  721. }
  722. @Override
  723. public void remove() {
  724. if (current == null) {
  725. throw new IllegalStateException();
  726. }
  727. if (modCount != expectedModCount) {
  728. throw new ConcurrentModificationException();
  729. }
  730. Object k = current.key;
  731. current = null;
  732. LongHashMap.this.removeEntryForKey(k);
  733. expectedModCount = modCount;
  734. }
  735. }
  736. private class KeyIterator extends HashIterator<K> {
  737. @Override
  738. public K next() {
  739. return nextEntry().getKey();
  740. }
  741. }
  742. private class EntryIterator extends HashIterator<LongHashMap.Entry<K>> {
  743. @Override
  744. public LongHashMap.Entry<K> next() {
  745. return nextEntry();
  746. }
  747. }
  748. // Subclass overrides these to alter behavior of views' iterator() method
  749. Iterator<K> newKeyIterator() {
  750. return new KeyIterator();
  751. }
  752. Iterator<LongHashMap.Entry<K>> newEntryIterator() {
  753. return new EntryIterator();
  754. }
  755. // Views
  756. private transient Set<LongHashMap.Entry<K>> entrySet = null;
  757. /**
  758. * Each of these fields are initialized to contain an instance of the
  759. * appropriate view the first time this view is requested. The views are
  760. * stateless, so there's no reason to create more than one of each.
  761. */
  762. transient volatile Set<K> keySet = null;
  763. /**
  764. * Returns a set view of the keys contained in this map. The set is
  765. * backed by the map, so changes to the map are reflected in the set, and
  766. * vice-versa. The set supports element removal, which removes the
  767. * corresponding mapping from this map, via the <tt>Iterator.remove</tt>,
  768. * <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt>, and
  769. * <tt>clear</tt> operations. It does not support the <tt>add</tt> or
  770. * <tt>addAll</tt> operations.
  771. *
  772. * @return a set view of the keys contained in this map.
  773. */
  774. public Set<K> keySet() {
  775. Set<K> ks = keySet;
  776. return (ks != null ? ks : (keySet = new KeySet()));
  777. }
  778. private class KeySet extends AbstractSet<K> {
  779. @Override
  780. public Iterator<K> iterator() {
  781. return newKeyIterator();
  782. }
  783. @Override
  784. public int size() {
  785. return size;
  786. }
  787. @Override
  788. public boolean contains(Object o) {
  789. return containsKey(o);
  790. }
  791. @Override
  792. public boolean remove(Object o) {
  793. return LongHashMap.this.removeEntryForKey(o) != null;
  794. }
  795. @Override
  796. public void clear() {
  797. LongHashMap.this.clear();
  798. }
  799. }
  800. /**
  801. * Returns a collection view of the mappings contained in this map. Each
  802. * element in the returned collection is a <tt>Map.Entry</tt>. The
  803. * collection is backed by the map, so changes to the map are reflected in
  804. * the collection, and vice-versa. The collection supports element
  805. * removal, which removes the corresponding mapping from the map, via the
  806. * <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>,
  807. * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations.
  808. * It does not support the <tt>add</tt> or <tt>addAll</tt> operations.
  809. *
  810. * @return a collection view of the mappings contained in this map.
  811. * @see Map.Entry
  812. */
  813. public Set<LongHashMap.Entry<K>> entrySet() {
  814. Set<LongHashMap.Entry<K>> es = entrySet;
  815. return (es != null ? es : (entrySet = new EntrySet()));
  816. }
  817. private class EntrySet extends AbstractSet<LongHashMap.Entry<K>> {
  818. @Override
  819. public Iterator<LongHashMap.Entry<K>> iterator() {
  820. return newEntryIterator();
  821. }
  822. @Override
  823. public boolean contains(Object o) {
  824. if (!(o instanceof Map.Entry)) {
  825. return false;
  826. }
  827. @SuppressWarnings("unchecked")
  828. LongHashMap.Entry<K> e = (LongHashMap.Entry<K>) o;
  829. Entry<K> candidate = getEntry(e.getKey());
  830. return candidate != null && candidate.equals(e);
  831. }
  832. @Override
  833. public boolean remove(Object o) {
  834. return removeMapping(o) != null;
  835. }
  836. @Override
  837. public int size() {
  838. return size;
  839. }
  840. @Override
  841. public void clear() {
  842. LongHashMap.this.clear();
  843. }
  844. }
  845. // These methods are used when serializing HashSets
  846. int capacity() {
  847. return table.length;
  848. }
  849. float loadFactor() {
  850. return loadFactor;
  851. }
  852. }