aboutsummaryrefslogtreecommitdiff
path: root/examples/Mini/Environment.java
diff options
context:
space:
mode:
Diffstat (limited to 'examples/Mini/Environment.java')
-rw-r--r--examples/Mini/Environment.java184
1 files changed, 184 insertions, 0 deletions
diff --git a/examples/Mini/Environment.java b/examples/Mini/Environment.java
new file mode 100644
index 00000000..9c30e025
--- /dev/null
+++ b/examples/Mini/Environment.java
@@ -0,0 +1,184 @@
+package Mini;
+
+import java.util.Vector;
+
+/**
+ * For efficiency and convenience reasons we want our own hash table. It does
+ * not conform to java.util.Dictionary(yet).
+ *
+ * That environment contains all function definitions and identifiers.
+ * Hash keys are Strings (identifiers), which are mapped to a table index.
+ *
+ * The table consists of `SIZE' fields which have `SLOTS' subfields. Thus
+ * the maximum number of storable items is `SLOTS' * `SIZE'.
+ *
+ * @version $Id$
+ * @author <A HREF="http://www.berlin.de/~markus.dahm/">M. Dahm</A>
+ */
+public class Environment implements Cloneable {
+ private static final int SIZE = 127; // Prime number large enough for most cases
+ private static final int SLOTS = 3; // Number of slots of each field
+
+ private int size; // The table is an array of
+ private Vector[] table; // Vectors
+ private int elements=0;
+
+ public Environment(int size) {
+ this.size = size;
+ table = new Vector[size];
+ }
+
+ private Environment(Vector[] table) {
+ size = table.length;
+ this.table = table;
+ }
+
+ public Environment() {
+ this(SIZE);
+ }
+
+ private final int hashCode(String key) {
+ return Math.abs(key.hashCode()) % size;
+ }
+
+ /**
+ * Inserts macro into table or overwrite old contents if it
+ * was already stored.
+ */
+ public void put(EnvEntry obj) {
+ int hash;
+ Vector v;
+ String key = obj.getHashKey();
+
+ hash = hashCode(key);
+ v = table[hash];
+
+ elements++; // Count
+
+ if(v == null) // Not yet initialized
+ table[hash] = v = new Vector(SLOTS);
+ else {
+ try {
+ int index = lookup(v, key);
+
+ if(index >= 0) {
+ v.setElementAt(obj, index); // Overwrite
+ return;
+ }
+ } catch(ArrayIndexOutOfBoundsException e) {}
+ }
+
+ // Not found in Vector -> add it
+ v.addElement(obj);
+ }
+
+ /** Get entry from hash table.
+ */
+ public EnvEntry get(String key) {
+ int hash;
+ Vector v;
+ EnvEntry entry = null;
+
+ hash = hashCode(key);
+ v = table[hash];
+
+ if(v == null)
+ return null;
+
+ try {
+ int index = lookup(v, key);
+
+ if(index >= 0)
+ entry = (EnvEntry)v.elementAt(index);
+ } catch(ArrayIndexOutOfBoundsException e) {}
+
+ return entry;
+ }
+
+ /**
+ * Delete an object if it does exist.
+ */
+ public void delete(String key) {
+ int hash;
+ Vector v;
+
+ hash = hashCode(key);
+ v = table[hash];
+
+ if(v == null)
+ return;
+
+ try {
+ int index = lookup(v, key);
+
+ if(index >= 0) {
+ elements--; // Count
+ v.removeElementAt(index);
+ }
+ } catch(ArrayIndexOutOfBoundsException e) {}
+ }
+
+ private static final int lookup(Vector v, String key)
+ throws ArrayIndexOutOfBoundsException
+ {
+ int len = v.size();
+
+ for(int i=0; i < len; i++) {
+ EnvEntry entry = (EnvEntry)v.elementAt(i);
+
+ if(entry.getHashKey().equals(key)) // Found index
+ return i;
+ }
+
+ return -1;
+ }
+
+ public Object clone() {
+ Vector[] copy = new Vector[size];
+
+ for(int i=0; i < size; i++) {
+ if(table[i] != null) {
+ copy[i] = (Vector)table[i].clone(); // Copies references
+
+ /*
+ int len = table[i].size();
+
+ copy[i] = new Vector(len);
+ try {
+ for(int j=0; j < len; j++)
+ copy[i].addElement(table[i].elementAt(j));
+ } catch(ArrayIndexOutOfBoundsException e) {}*/
+ }
+ }
+
+ return new Environment(copy);
+ }
+
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+
+ for(int i=0; i < size; i++)
+ if(table[i] != null)
+ buf.append(table[i] + "\n");
+
+ return buf.toString();
+ }
+
+ public EnvEntry[] getEntries() {
+ EnvEntry[] entries = new EnvEntry[elements];
+ int k = 0;
+ Vector v;
+
+ for(int i=0; i < size; i++) {
+ if((v = table[i]) != null) {
+ int len = v.size();
+ try {
+ for(int j=0; j < len; j++)
+ entries[k++] = (EnvEntry)v.elementAt(j);
+ } catch(ArrayIndexOutOfBoundsException e) {}
+ }
+ }
+
+ return entries;
+ }
+}