HashMapLong.java
001 /*
002  *  HashMapLong.java
003  *
004  *  Copyright (c) 2001, The University of Sheffield.
005  *
006  *  This file is part of GATE (see http://gate.ac.uk/), and is free
007  *  software, licenced under the GNU Library General Public License,
008  *  Version 2, June 1991 (in the distribution as file licence.html,
009  *  and also available at http://gate.ac.uk/gate/licence.html).
010  *
011  *  D.Ognyanoff, 15/Nov/2001
012  *
013  */
014 
015  package gate.util;
016 
017 /**
018  * simple cut-off version of the hashmap with native long's as keys
019  * only get,put and isEmpty methods are implemented().
020  * This map is used in very private case in the SimpleSortedSet class.
021  * The main purpose is to optimize the speed of the SinglePhaseTransducer.transduce()
022  */
023 
024 public class HashMapLong {
025 
026     /**
027      * The hash table data.
028      */
029     private transient Entry table[];
030 
031     private transient int count;
032 
033     private int threshold;
034 
035     private float loadFactor;
036 
037     /**
038      * the main constructor. see the HashMap constructor for description
039      */
040     public HashMapLong(int initialCapacity, float loadFactor) {
041         if (initialCapacity < 0)
042             throw new IllegalArgumentException("Illegal Initial Capacity: "+
043                                                initialCapacity);
044         if (loadFactor <= || Float.isNaN(loadFactor))
045             throw new IllegalArgumentException("Illegal Load factor: "+
046                                                loadFactor);
047         if (initialCapacity==0)
048             initialCapacity = 1;
049         this.loadFactor = loadFactor;
050         table = new Entry[initialCapacity];
051         threshold = (int)(initialCapacity * loadFactor);
052     }
053 
054     public HashMapLong(int initialCapacity) {
055         this(initialCapacity, 0.75f);
056     }
057 
058     public HashMapLong() {
059         this(110.75f);
060     }
061 
062     public boolean isEmpty() {
063         return count == 0;
064     }
065 
066     public Object get(long key) {
067         Entry tab[] = table;
068     int hash = (int)(key ^ (key >> 32));
069     int index = (hash & 0x7FFFFFFF% tab.length;
070     for (Entry e = tab[index]; e != null; e = e.next)
071         if ((e.hash == hash&& key == e.key)
072             return e.value;
073 
074         return null;
075     }
076 
077     /**
078      * Rehashes the contents of this map into a new <tt>HashMapLong</tt> instance
079      * with a larger capacity. This method is called automatically when the
080      * number of keys in this map exceeds its capacity and load factor.
081      */
082     private void rehash() {
083       int oldCapacity = table.length;
084       Entry oldMap[] = table;
085 
086       int newCapacity = oldCapacity * 1;
087       Entry newMap[] new Entry[newCapacity];
088 
089       threshold = (int) (newCapacity * loadFactor);
090       table = newMap;
091 
092       for (int i = oldCapacity; i-- > 0) {
093         for (Entry old = oldMap[i]; old != null) {
094           Entry e = old;
095           old = old.next;
096 
097           int index = (e.hash & 0x7FFFFFFF% newCapacity;
098           e.next = newMap[index];
099           newMap[index= e;
100         }
101       }
102     }
103 
104     public Object put(long key, Object value) {
105         // Makes sure the key is not already in the HashMapLong.
106         Entry tab[] = table;
107         int hash = (int)(key ^ (key >> 32));
108         int index = (hash & 0x7FFFFFFF% tab.length;
109 
110         for (Entry e = tab[index; e != null ; e = e.next) {
111             if ((e.hash == hash&& key == e.key) {
112                 Object old = e.value;
113                 e.value = value;
114                 return old;
115             }
116         }
117 
118         if (count >= threshold) {
119             // Rehash the table if the threshold is exceeded
120             rehash();
121 
122                 tab = table;
123                 index = (hash & 0x7FFFFFFF% tab.length;
124         }
125 
126         // Creates the new entry.
127         Entry e = new Entry(hash, key, value, tab[index]);
128         tab[index= e;
129         count++;
130         return null;
131     }
132 
133     /**
134      * HashMapLong collision list entry.
135      */
136     private static class Entry {
137         int hash;
138         long key;
139         Object value;
140         Entry next;
141 
142         Entry(int hash, long key, Object value, Entry next) {
143             this.hash = hash;
144             this.key = key;
145             this.value = value;
146             this.next = next;
147         }
148     //Entry
149 // hasnMapLong