• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  */
18 package Mini;
19 
20 import java.util.Vector;
21 
22 /**
23  * For efficiency and convenience reasons we want our own hash table. It does
24  * not conform to java.util.Dictionary(yet).
25  *
26  * That environment contains all function definitions and identifiers.
27  * Hash keys are Strings (identifiers), which are mapped to a table index.
28  *
29  * The table consists of `SIZE' fields which have `SLOTS' subfields. Thus
30  * the maximum number of storable items is `SLOTS' * `SIZE'.
31  *
32  * @version $Id$
33  */
34 public class Environment implements Cloneable {
35   private static final int SIZE  = 127; // Prime number large enough for most cases
36   private static final int SLOTS = 3;   // Number of slots of each field
37 
38   private int       size;               // The table is an array of
39   private Vector<EnvEntry>[]  table;              // Vectors
40   private int       elements=0;
41 
Environment(int size)42   public Environment(int size) {
43     this.size = size;
44     table     = new Vector[size];
45   }
46 
Environment(Vector<EnvEntry>[] table)47   private Environment(Vector<EnvEntry>[] table) {
48     size       = table.length;
49     this.table = table;
50   }
51 
Environment()52   public Environment() {
53     this(SIZE);
54   }
55 
hashCode(String key)56   private int hashCode(String key) {
57     return Math.abs(key.hashCode()) % size;
58   }
59 
60   /**
61    * Inserts macro into table or overwrite old contents if it
62    * was already stored.
63    */
put(EnvEntry obj)64   public void put(EnvEntry obj) {
65     int    hash;
66     Vector<EnvEntry> v;
67     String key = obj.getHashKey();
68 
69     hash = hashCode(key);
70     v    = table[hash];
71 
72     elements++; // Count
73 
74     if(v == null) {
75         table[hash] = v = new Vector<EnvEntry>(SLOTS);
76     } else {
77       try {
78         int index = lookup(v, key);
79 
80         if(index >= 0) {
81           v.setElementAt(obj, index); // Overwrite
82           return;
83         }
84       } catch(ArrayIndexOutOfBoundsException e) {}
85     }
86 
87     // Not found in Vector -> add it
88     v.addElement(obj);
89   }
90 
91   /** Get entry from hash table.
92    */
get(String key)93   public EnvEntry get(String key) {
94     int       hash;
95     Vector<EnvEntry>    v;
96     EnvEntry entry = null;
97 
98     hash = hashCode(key);
99     v    = table[hash];
100 
101     if(v == null) {
102         return null;
103     }
104 
105     try {
106       int index = lookup(v, key);
107 
108       if(index >= 0) {
109         entry = v.elementAt(index);
110     }
111     } catch(ArrayIndexOutOfBoundsException e) {}
112 
113     return entry;
114   }
115 
116   /**
117    * Delete an object if it does exist.
118    */
delete(String key)119   public void delete(String key) {
120     int       hash;
121     Vector<EnvEntry>    v;
122 
123     hash = hashCode(key);
124     v    = table[hash];
125 
126     if(v == null) {
127         return;
128     }
129 
130     try {
131       int index = lookup(v, key);
132 
133       if(index >= 0) {
134         elements--; // Count
135         v.removeElementAt(index);
136       }
137     } catch(ArrayIndexOutOfBoundsException e) {}
138   }
139 
lookup(Vector<EnvEntry> v, String key)140   private static int lookup(Vector<EnvEntry> v, String key)
141        throws ArrayIndexOutOfBoundsException
142   {
143     int len = v.size();
144 
145     for(int i=0; i < len; i++) {
146       EnvEntry entry = v.elementAt(i);
147 
148       if(entry.getHashKey().equals(key)) {
149         return i;
150     }
151     }
152 
153     return -1;
154   }
155 
156   @Override
clone()157   public Object clone() {
158     Vector<EnvEntry>[] copy = new Vector[size];
159 
160     for(int i=0; i < size; i++) {
161       if(table[i] != null) {
162         copy[i] = (Vector)table[i].clone(); // Copies references
163 
164         /*
165         int len = table[i].size();
166 
167         copy[i] = new Vector(len);
168         try {
169           for(int j=0; j < len; j++)
170             copy[i].addElement(table[i].elementAt(j));
171         } catch(ArrayIndexOutOfBoundsException e) {}*/
172       }
173     }
174 
175     return new Environment(copy);
176   }
177 
178   @Override
toString()179   public String toString() {
180     StringBuffer buf = new StringBuffer();
181 
182     for(int i=0; i < size; i++) {
183         if(table[i] != null) {
184             buf.append(table[i] + "\n");
185         }
186     }
187 
188     return buf.toString();
189   }
190 
getEntries()191   public EnvEntry[] getEntries() {
192     EnvEntry[] entries = new EnvEntry[elements];
193     int        k       = 0;
194     Vector<EnvEntry>     v;
195 
196     for(int i=0; i < size; i++) {
197       if((v = table[i]) != null) {
198         int len = v.size();
199         try {
200           for(int j=0; j < len; j++) {
201         entries[k++] = v.elementAt(j);
202     }
203         } catch(ArrayIndexOutOfBoundsException e) {}
204       }
205     }
206 
207     return entries;
208   }
209 }
210