| HashMapLong |

    1   /*
    2    *  HashMapLong.java
    3    *
    4    *  Copyright (c) 2001, The University of Sheffield.
    5    *
    6    *  This file is part of GATE (see http://gate.ac.uk/), and is free
    7    *  software, licenced under the GNU Library General Public License,
    8    *  Version 2, June 1991 (in the distribution as file licence.html,
    9    *  and also available at http://gate.ac.uk/gate/licence.html).
    10   *
    11   *  D.Ognyanoff, 15/Nov/2001
    12   *
    13   */
    14
    15   package gate.util;
    16  import java.util.*;
    17  import java.io.*;
    18
    19  /**
    20   * simple cut-off version of the hashmap with native long's as keys
    21   * only get,put and isEmpty methods are implemented().
    22   * This map is used in very private case in the SimpleSortedSet class.
    23   * The main purpose is to optimize the speed of the SinglePhaseTransducer.transduce()
    24   */
    25
    26  public class HashMapLong {
    27
    28      /**
    29       * The hash table data.
    30       */
    31      private transient Entry table[];
    32
    33      private transient int count;
    34
    35      private int threshold;
    36
    37      private float loadFactor;
    38
    39      /**
    40       * the main constructor. see the HashMap constructor for description
    41       */
    42      public HashMapLong(int initialCapacity, float loadFactor) {
    43    if (initialCapacity < 0)
    44        throw new IllegalArgumentException("Illegal Initial Capacity: "+
    45                                                 initialCapacity);
    46          if (loadFactor <= 0 || Float.isNaN(loadFactor))
    47              throw new IllegalArgumentException("Illegal Load factor: "+
    48                                                 loadFactor);
    49          if (initialCapacity==0)
    50              initialCapacity = 1;
    51    this.loadFactor = loadFactor;
    52    table = new Entry[initialCapacity];
    53    threshold = (int)(initialCapacity * loadFactor);
    54      }
    55
    56      public HashMapLong(int initialCapacity) {
    57    this(initialCapacity, 0.75f);
    58      }
    59
    60      public HashMapLong() {
    61    this(11, 0.75f);
    62      }
    63
    64      public boolean isEmpty() {
    65    return count == 0;
    66      }
    67
    68      public Object get(long key) {
    69    Entry tab[] = table;
    70      int hash = (int)(key ^ (key >> 32));
    71      int index = (hash & 0x7FFFFFFF) % tab.length;
    72      for (Entry e = tab[index]; e != null; e = e.next)
    73          if ((e.hash == hash) && key == e.key)
    74              return e.value;
    75
    76    return null;
    77      }
    78
    79      /**
    80       * Rehashes the contents of this map into a new <tt>HashMapLong</tt> instance
    81       * with a larger capacity. This method is called automatically when the
    82       * number of keys in this map exceeds its capacity and load factor.
    83       */
    84      private void rehash() {
    85    int oldCapacity = table.length;
    86    Entry oldMap[] = table;
    87
    88    int newCapacity = oldCapacity * 2 + 1;
    89    Entry newMap[] = new Entry[newCapacity];
    90
    91    threshold = (int)(newCapacity * loadFactor);
    92    table = newMap;
    93
    94    for (int i = oldCapacity ; i-- > 0 ;) {
    95        for (Entry old = oldMap[i] ; old != null ; ) {
    96      Entry e = old;
    97      old = old.next;
    98
    99      int index = (e.hash & 0x7FFFFFFF) % newCapacity;
    100     e.next = newMap[index];
    101     newMap[index] = e;
    102       }
    103   }
    104     }
    105
    106     public Object put(long key, Object value) {
    107         // Makes sure the key is not already in the HashMapLong.
    108         Entry tab[] = table;
    109         int hash = (int)(key ^ (key >> 32));
    110         int index = (hash & 0x7FFFFFFF) % tab.length;
    111
    112         for (Entry e = tab[index] ; e != null ; e = e.next) {
    113             if ((e.hash == hash) && key == e.key) {
    114                 Object old = e.value;
    115                 e.value = value;
    116                 return old;
    117             }
    118         }
    119
    120         if (count >= threshold) {
    121             // Rehash the table if the threshold is exceeded
    122             rehash();
    123
    124                 tab = table;
    125                 index = (hash & 0x7FFFFFFF) % tab.length;
    126         }
    127
    128         // Creates the new entry.
    129         Entry e = new Entry(hash, key, value, tab[index]);
    130         tab[index] = e;
    131         count++;
    132         return null;
    133     }
    134
    135     /**
    136      * HashMapLong collision list entry.
    137      */
    138     private static class Entry {
    139         int hash;
    140         long key;
    141         Object value;
    142         Entry next;
    143
    144         Entry(int hash, long key, Object value, Entry next) {
    145             this.hash = hash;
    146             this.key = key;
    147             this.value = value;
    148             this.next = next;
    149         }
    150     } //Entry
    151 } // hasnMapLong
    152

| HashMapLong |