source: branches/0.22.x/abcl/src/org/armedbear/lisp/EqHashTable.java

Last change on this file was 11488, checked in by ehuelsmann, 16 years ago

Add @Override annotations.

Patch by: Douglas Miles

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 4.9 KB
Line 
1/*
2 * EqHashTable.java
3 *
4 * Copyright (C) 2004-2005 Peter Graves
5 * $Id: EqHashTable.java 11488 2008-12-27 10:50:33Z ehuelsmann $
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20 *
21 * As a special exception, the copyright holders of this library give you
22 * permission to link this library with independent modules to produce an
23 * executable, regardless of the license terms of these independent
24 * modules, and to copy and distribute the resulting executable under
25 * terms of your choice, provided that you also meet, for each linked
26 * independent module, the terms and conditions of the license of that
27 * module.  An independent module is a module which is not derived from
28 * or based on this library.  If you modify this library, you may extend
29 * this exception to your version of the library, but you are not
30 * obligated to do so.  If you do not wish to do so, delete this
31 * exception statement from your version.
32 */
33
34package org.armedbear.lisp;
35
36public final class EqHashTable extends HashTable
37{
38    private LispObject cachedKey;
39    private int cachedIndex;
40
41    private int mask;
42
43    public EqHashTable(int size, LispObject rehashSize,
44                       LispObject rehashThreshold)
45    {
46        super(calculateInitialCapacity(size), rehashSize, rehashThreshold);
47        mask = buckets.length - 1;
48    }
49
50    @Override
51    public Symbol getTest()
52    {
53        return Symbol.EQ;
54    }
55
56    @Override
57    public LispObject get(LispObject key)
58    {
59        final int index;
60        if (key == cachedKey) {
61            index = cachedIndex;
62        } else {
63            index = key.sxhash() & mask;
64            cachedKey = key;
65            cachedIndex = index;
66        }
67        HashEntry e = buckets[index];
68        while (e != null) {
69            if (key == e.key)
70                return e.value;
71            e = e.next;
72        }
73        return null;
74    }
75
76    @Override
77    public void put(LispObject key, LispObject value)
78    {
79        int index;
80        if (key == cachedKey) {
81            index = cachedIndex;
82        } else {
83            index = key.sxhash() & mask;
84            cachedKey = key;
85            cachedIndex = index;
86        }
87        HashEntry e = buckets[index];
88        while (e != null) {
89            if (key == e.key) {
90                e.value = value;
91                return;
92            }
93            e = e.next;
94        }
95        // Not found. We need to add a new entry.
96        if (++count > threshold) {
97            rehash();
98            // Need a new hash value to suit the bigger table.
99            index = key.sxhash() & mask;
100            cachedKey = key;
101            cachedIndex = index;
102        }
103        e = new HashEntry(key, value);
104        e.next = buckets[index];
105        buckets[index] = e;
106    }
107
108    @Override
109    public LispObject remove(LispObject key)
110    {
111        final int index;
112        if (key == cachedKey) {
113            index = cachedIndex;
114        } else {
115            index = key.sxhash() & mask;
116            cachedKey = key;
117            cachedIndex = index;
118        }
119        HashEntry e = buckets[index];
120        HashEntry last = null;
121        while (e != null) {
122            if (key == e.key) {
123                if (last == null)
124                    buckets[index] = e.next;
125                else
126                    last.next = e.next;
127                --count;
128                return e.value;
129            }
130            last = e;
131            e = e.next;
132        }
133        return null;
134    }
135
136    @Override
137    protected void rehash()
138    {
139        cachedKey = null; // Invalidate the cache!
140        HashEntry[] oldBuckets = buckets;
141        final int newCapacity = buckets.length * 2;
142        threshold = (int) (newCapacity * loadFactor);
143        buckets = new HashEntry[newCapacity];
144        mask = buckets.length - 1;
145        for (int i = oldBuckets.length; i-- > 0;) {
146            HashEntry e = oldBuckets[i];
147            while (e != null) {
148                final int index = e.key.sxhash() & mask;
149                HashEntry dest = buckets[index];
150                if (dest != null) {
151                    while (dest.next != null)
152                        dest = dest.next;
153                    dest.next = e;
154                } else
155                    buckets[index] = e;
156                HashEntry next = e.next;
157                e.next = null;
158                e = next;
159            }
160        }
161    }
162}
Note: See TracBrowser for help on using the repository browser.