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