/* AlgThread.java */
import java.awt.*;
import java.io.*;
import java.net.*;
import java.util.*;
/**
* AlgThread
is an extension of the provided Java
* multi-threading package.
* It enables the graphical display of the main execution thread to be
* updated during the execution of the algorithm.
*
* A section of this source file is normally displayed on the TextFrame.
* This section starts with the line after
* /*------------------*
/
*
and finishes before the line //------------
*
.
* Every line starting with /*-*
/
will be discarded in
* the source code display area and each line is terminated by the first
* encounter of /*-*
/
.
*
* The source file AlgThread.java
is to be
* modified/completed for separate animation algorithms.
*
* @author Woi L Ang
* @since JDK1.0
*/
public class AlgThread extends Thread {
/**
* Array of strings used to set the choices of the data choice button
* in ControlPanel.
* @see ControlPanel
*/
public static String[] dataSets = {"Linear Probing",
"Quadratic Probing (c=1)",
"Quadratic Probing (c=2)",
"Quadratic Probing (c=4)"};
/**
* The initial caller of the constructor of this class.
* It holds the references to all existing panels.
*/
public AlgAnimFrame frame;
/**
* A reference to the drawing panel in order to update the animation
* during the execution of the algorithm.
* @see DrawingPanel
*/
public DrawingPanel drawingPanel;
public TablePanel table;
String datafile = "textfile.txt";
String[] words = null;
String allInputWords;
int c = 1;
static final int max_table_size = 101;
/**
* Creates a new thread using the frame passed in as the parameter.
* If this constructor is called from the frame constructor,
* a drawingPanel will be initialized and assigned to the frame
* class.
*
* @param frame An extended frame where the algorithm is going to
* execute in.
*
* @see AlgAnimFrame
*/
public AlgThread(AlgAnimFrame frame) {
this.frame = frame;
if (frame != null && frame.alg != null &&
frame.alg.drawingPanel != null) {
// drawingPanel already created -> this constructor called from
// clicking the run button -> use the generated data set
this.drawingPanel = frame.alg.drawingPanel;
this.words = frame.alg.words;
this.c = frame.alg.c;
this.allInputWords = frame.alg.allInputWords;
} else {
// this constructor called from Frame constructor
drawingPanel = new DrawingPanel();
frame.drawingPanel = (Panel)this.drawingPanel;
}
}
/**
* Sets the delay between each animation step. This determines
* the rate the drawingPanel is updated. The setDelay
* method is normally called by the action listener of
* the delay choice button
on the control panel.
* @param delay The delay set in milliseconds.
*/
public void setDelay(int delay) {
drawingPanel.setDelay(delay);
}
/**
* Generate data based on the choice made on the choice button
* created in ControlPanel. This method is application specific
* and the contents for the satisfaction of each 'if' statement
* have to be filled in based on the algorithm.
* @see ControlPanel
*/
public void generateData() {
int choice = frame.control_panel.getDataChoice();
if (choice == 0) {
frame.control_panel.setText(
"Linear Probing collision handling...");
drawingPanel.setRehashFunction("( H() + i )");
} else if (choice == 1) {
c = 1;
frame.control_panel.setText(
"Quadratic Probing collision handling... C = " + c);
drawingPanel.setRehashFunction("( H() + i^2 )");
} else if (choice == 2) {
c = 2;
frame.control_panel.setText(
"Quadratic Probing collision handling... C = " + c);
drawingPanel.setRehashFunction("( H() + 2 * i^2 )");
} else if (choice == 3) {
c = 4;
frame.control_panel.setText(
"Quadratic Probing collision handling... C = " + c);
drawingPanel.setRehashFunction("( H() + 4 * i^2 )");
}
frame.setText(1, "This demo reads words from a text file and");
frame.setText(2, "stores them into a hash table...");
if (words == null) {
loadFile();
allInputWords = new String();
for (int i = 0; i < words.length; i++)
allInputWords = allInputWords.concat(" " + words[i]);
}
table = drawingPanel.table;
table.setTableSize(max_table_size);
drawingPanel.setInputText(allInputWords.trim());
drawingPanel.repaint();
}
public void loadFile() {
AlgAnimApp app = frame.parentApp;
InputStream inFile = null;
try {
URL dataURL =
new URL(app.getCodeBase(), datafile);
inFile = dataURL.openStream();
words = new String[700]; int wc = 0;
String thisWord = new String();
int c = inFile.read();
while (c != -1) {
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c < 'z')) {
thisWord = thisWord + (char)c;
} else {
if (thisWord.length() > 0) {
words[wc] = thisWord.toLowerCase();
thisWord = new String();
wc++;
if (wc > words.length-1)
break;
}
}
c = inFile.read();
}
inFile.close();
} catch (IOException e) {
System.out.println("Error opening file: " + e);
}
}
/*--------------------------------------------------------------------*/
//----
public int hash(String str) {
int sum = 0;
// hash the word based on the first 8 character of the string
// so the hash value ranges from 0 to 200
String word = str.trim().toUpperCase();
for (int i = 0; i < word.length(); i++) {
if (i==8) break;
sum += (int)word.charAt(i);
}
return (sum % max_table_size);
}
public int rehash(int hash, int c, int i) {
int choice = frame.control_panel.getDataChoice();
if (choice == 0) // linearing probing
if ((hash+1) < max_table_size)
return hash+1;
else return 0;
else {// -> quadratic probing
int val = hash + c * (i * i - (i-1)*(i-1));
if (val < max_table_size)
return val;
else
return (val % max_table_size);
}
}
public void hashTableDemo(String[] words) {
// insert words into table
for (int i = 0; i < words.length; i++) {
if (words[i] == null || table.full())
break;
/*-*/drawingPanel.setInput(words[i], hash(words[i])); frame.waitStep();
/*-*/drawingPanel.contains(words[i]);
if (table.contains(words[i]))
continue;
if (table.occupied(hash(words[i]))) {
/*-*/drawingPanel.collision(words[i], hash(words[i]));
int k = 1;
int index = rehash(hash(words[i]), c, k++);
/*-*/drawingPanel.rehash(index);
boolean found = true;
while (table.occupied(index)) {
/*-*/drawingPanel.collision(words[i], index);
index = rehash(index, c, k++);
/*-*/drawingPanel.rehash(index);
if (index == hash(words[i])) {
// cannot find an unoccupied space using this
// rehashing scheme
found = false;
break;
}
}
if (found) {
/*-*/drawingPanel.setTableEntry(words[i], index);
/*-*/drawingPanel.incHashStat(k);
table.setTableEntry(words[i], index);
/*-*/drawingPanel.setColStat(table.numOccupied(), k-1);
} else {
/*-*/frame.setText(1, "There is no space to fit in this entry...");
/*-*/frame.setText(2, "Animation terminated...");
break;
}
} else {
/*-*/drawingPanel.setTableEntry(words[i], hash(words[i]));
/*-*/drawingPanel.incHashStat(1);
table.setTableEntry(words[i], hash(words[i]));
}
}
}
/**
* This method is invoked when the Thread
class
* start()
method is called.
* It contains the statements to execute the methods which perform
* the algorithm. This method is to be completed based on separate
* animation algorithms.
* @see java.lang.Thread
*/
public void run() {
table = drawingPanel.table;
table.setTableSize(max_table_size);
frame.setText(1, "This demo reads words from a text file and");
frame.setText(2, "stores them into a hash table...");
drawingPanel.setInputText(allInputWords.trim());
hashTableDemo(words);
// finish
frame.finishAlg();
frame.control_panel.setText("Execution completed successfully...");
}
/**
* Restore the drawing panel at the beginning or the end of each
* simulation.
*/
public void restoreDrawingPanelColor() {
}
}