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