public class QueryTask extends Task {
int maxDepth;
int maxSearchDepth;
- Queue toprocess;
+ GlobalQueue toprocess;
DistributedHashMap results;
DistributedLinkedList results_list;
DistributedHashMap visitedList;
GlobalString gTitle;
GlobalString workingURL;
- public QueryTask(Queue todoList, DistributedHashMap visitedList, int maxDepth, int maxSearchDepth, DistributedHashMap results, DistributedLinkedList results_list) {
+ public QueryTask(GlobalQueue todoList, DistributedHashMap visitedList, int maxDepth, int maxSearchDepth, DistributedHashMap results, DistributedLinkedList results_list) {
this.todoList = todoList;
this.visitedList = visitedList;
this.maxDepth = maxDepth;
this.maxSearchDepth = maxSearchDepth;
this.results = results;
this.results_list = results_list;
- toprocess = global new Queue();
+ toprocess = global new GlobalQueue();
}
public void execute() {
public void done(Object obj) {
if ((gTitle != null) && (gTitle.length() > 0)) {
- processList();
+ processedList();
}
int searchCnt = 0;
} while(numchars > 0);
}
- public void processList() {
+ public void processedList() {
LinkedList ll;
GlobalString token = null;
int mindex = 0;
token = refine(token);
}
- Queue q = (Queue)results.get(token);
+ GlobalQueue q = (GlobalQueue)results.get(token);
if (q == null) {
- q = global new Queue();
+ q = global new GlobalQueue();
}
q.push(workingURL);
results.put(token, q);
return str;
}
- public static Queue processPage(LocalQuery lq) {
+ public static GlobalQueue processPage(LocalQuery lq) {
int index = 0;
String href = new String("href=\"");
String searchstr = lq.response.toString();
int depth;
boolean cont = true;
- Queue toprocess;
+ GlobalQueue toprocess;
depth = lq.getDepth() + 1;
- toprocess = global new Queue();
+ toprocess = global new GlobalQueue();
while(cont) {
int mindex = searchstr.indexOf(href,index);
if (mindex != -1) {
GlobalQuery firstquery = global new GlobalQuery(firstmachine, firstpage);
- Queue todoList = global new Queue();
+ GlobalQueue todoList = global new GlobalQueue();
DistributedHashMap visitedList = global new DistributedHashMap(500, 500, 0.75f);
DistributedHashMap results = global new DistributedHashMap(100, 100, 0.75f);
DistributedLinkedList results_list = global new DistributedLinkedList();
--- /dev/null
+public class LocalQuery {
+ String hostname;
+ String path;
+ StringBuffer response;
+ int depth;
+
+ public LocalQuery(String hostname, String path, int depth) {
+ this.hostname = new String(hostname);
+ this.path = new String(path);
+ response = new StringBuffer();
+ this.depth = depth;
+ }
+
+ public int getDepth() {
+ return depth;
+ }
+
+ public String getHostName() {
+ return hostname;
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ public void outputFile() {
+ StringBuffer sb = new StringBuffer(hostname);
+ sb.append(path);
+ FileOutputStream fos = new FileOutputStream(sb.toString().replace('/','#'));
+ fos.write(response.toString().getBytes());
+ fos.close();
+ }
+
+ public String makewebcanonical(String page) {
+ StringBuffer b = new StringBuffer(getHostName(page));
+ b.append("/");
+ b.append(getPathName(page));
+ return b.toString();
+ }
+
+ public String getHostName(String page) {
+ String http = new String("http://");
+ String https = new String("https://");
+ int beginindex;
+ int endindex;
+
+ if ((page.indexOf(http) == -1) && (page.indexOf(https) == -1)) {
+ return getHostName();
+ }
+ else if (page.indexOf(https) != -1) {
+ beginindex = page.indexOf(https) + https.length();
+ }
+ else {
+ beginindex = page.indexOf(http) + http.length();
+ }
+ endindex = page.indexOf('/',beginindex+1);
+
+ if ((beginindex == -1)) {
+ System.printString("ERROR");
+ }
+ if (endindex == -1)
+ endindex = page.length();
+
+ return page.subString(beginindex, endindex);
+ }
+
+ public String getPathName(String page) {
+ String http = new String("http://");
+ String https = new String("https://");
+ int beginindex;
+ int nextindex;
+
+ if ((page.indexOf(http) == -1) && (page.indexOf(https) == -1)) {
+ String path = getPath();
+ int lastindex = path.lastindexOf('/');
+ if (lastindex == -1)
+ return page;
+
+ StringBuffer sb = new StringBuffer(path.subString(0,lastindex+1));
+ sb.append(page);
+ return sb.toString();
+ }
+ else if (page.indexOf(https) != -1) {
+ beginindex = page.indexOf(https) + https.length();
+ }
+ else {
+ beginindex = page.indexOf(http) + http.length();
+ }
+ nextindex = page.indexOf('/',beginindex+1);
+
+ if ((beginindex==-1) || (nextindex==-1))
+ return new String("index.html");
+ return page.subString(nextindex+1, page.length());
+ }
+}
--- /dev/null
+public class QueryTask {
+ int maxDepth;
+ int maxSearchDepth;
+ Queue todoList;
+ HashMap results;
+ HashMap visitedList;
+ LinkedList results_list;
+
+ String title;
+ String workingURL;
+
+ public QueryTask(Queue todoList, HashMap visitedList, int maxDepth, int maxSearchDepth, HashMap results, LinkedList results_list) {
+ this.todoList = todoList;
+ this.visitedList = visitedList;
+ this.maxDepth = maxDepth;
+ this.maxSearchDepth = maxSearchDepth;
+ this.results = results;
+ this.results_list = results_list;
+ title = new String();
+ workingURL = new String();
+ }
+
+ public void execute() {
+ int depth;
+ LocalQuery lq;
+ String hostname;
+ String path;
+ String title;
+ Queue toprocess;
+
+ lq = (LocalQuery)(todoList.pop());
+ depth = lq.getDepth();
+
+ while (depth < maxDepth) {
+ toprocess = new Queue();
+ hostname = lq.getHostName();
+ path = lq.getPath();
+
+ StringBuffer sb = new StringBuffer(hostname);
+ sb.append("/");
+ sb.append(path);
+ workingURL = sb.toString();
+ title = null;
+
+ System.printString("["+lq.getDepth()+"] ");
+ System.printString("Processing - Hostname : ");
+ System.printString(hostname);
+ System.printString(", Path : ");
+ System.printString(path);
+ System.printString("\n");
+
+ if (isDocument(path)) {
+ lq = (LocalQuery)(todoList.pop());
+ depth = lq.getDepth();
+ continue;
+ }
+
+ Socket s = new Socket();
+
+ if(s.connect(hostname, 80) == -1) {
+ lq = (LocalQuery)(todoList.pop());
+ depth = lq.getDepth();
+ continue;
+ }
+
+// System.out.println("AAA");
+ requestQuery(hostname, path, s);
+// System.out.println("BBB");
+ readResponse(lq, s);
+
+// System.out.println("CCC");
+ if ((title = grabTitle(lq)) != null) {
+ toprocess = processPage(lq);
+ }
+// System.out.println("DDD");
+
+ s.close();
+ done(toprocess);
+ lq = (LocalQuery)(todoList.pop());
+ depth = lq.getDepth();
+ }
+ }
+
+ public static boolean isDocument(String str) {
+ int index = str.lastindexOf('.');
+
+ if (index != -1) {
+ if ((str.subString(index+1)).equals("pdf")) return true;
+ else if ((str.subString(index+1)).equals("ps")) return true;
+ else if ((str.subString(index+1)).equals("ppt")) return true;
+ else if ((str.subString(index+1)).equals("pptx")) return true;
+ else if ((str.subString(index+1)).equals("jpg")) return true;
+ else if ((str.subString(index+1)).equals("mp3")) return true;
+ else if ((str.subString(index+1)).equals("wmv")) return true;
+ else if ((str.subString(index+1)).equals("doc")) return true;
+ else if ((str.subString(index+1)).equals("docx")) return true;
+ else if ((str.subString(index+1)).equals("mov")) return true;
+ else if ((str.subString(index+1)).equals("flv")) return true;
+ else return false;
+ }
+ return false;
+ }
+
+ public void done(Queue toprocess) {
+ if ((title != null) && (title.length() > 0)) {
+ processedList();
+ }
+
+ int searchCnt = 0;
+ while(!toprocess.isEmpty()) {
+ LocalQuery q = (LocalQuery)toprocess.pop();
+
+ String hostname = new String(q.getHostName());
+ String path = new String(q.getPath());
+
+ StringBuffer sb = new StringBuffer(hostname);
+ sb.append("/");
+ sb.append(path);
+
+ if (!visitedList.containsKey(sb.toString()) && (searchCnt < maxSearchDepth)) {
+ todoList.push(q);
+
+ String str = new String("1"); // dump data
+ visitedList.put(sb.toString(), str); // if URL is never visited, put in the list
+ results_list.add(sb.toString()); // the whole list that once visited
+ searchCnt++;
+ }
+ }
+ }
+
+ public void output() {
+ String str;
+ Iterator iter = results_list.iterator();
+
+ while (iter.hasNext() == true) {
+ str = ((String)(iter.next()));
+ System.printString(str + "\n");
+ }
+ }
+
+ public static String grabTitle(LocalQuery lq) {
+ String sBrace = new String("<");
+ String strTitle = new String("title>");
+ String searchstr = lq.response.toString();
+ String title = null;
+ char ch;
+
+ int mindex = -1;
+ int endquote = -1;
+ int i, j;
+ String tmp;
+
+ for (i = 0; i < searchstr.length(); i++) {
+ if (searchstr.charAt(i) == '<') {
+ i++;
+ if (searchstr.length() > (i+strTitle.length())) {
+ tmp = searchstr.subString(i, i+strTitle.length());
+ if (tmp.equalsIgnoreCase("title>")) {
+ mindex = i + tmp.length();
+ for (j = mindex; j < searchstr.length(); j++) {
+ if (searchstr.charAt(j) == '<') {
+ j++;
+ tmp = searchstr.subString(j, j+strTitle.length()+1);
+ if (tmp.equalsIgnoreCase("/title>")) {
+ endquote = j - 1;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (mindex != -1) {
+ title = searchstr.subString(mindex, endquote);
+ if (Character.isWhitespace(title.charAt(0))){
+ mindex=0;
+ while (Character.isWhitespace(title.charAt(mindex++)));
+ mindex--;
+ if (mindex >= title.length()) return null;
+ title = new String(title.subString(mindex));
+ }
+
+ if (Character.isWhitespace(title.charAt(title.length()-1))) {
+ endquote=title.length()-1;
+ while (Character.isWhitespace(title.charAt(endquote--)));
+ endquote += 2;
+ if (mindex >= endquote) return null;
+ title = new String(title.subString(0, endquote));
+ }
+
+ if (isErrorPage(title)) { // error page
+ return null;
+ }
+ }
+
+ return title;
+ }
+
+ public static boolean isErrorPage(String str) { // error msg list
+ if (str.equals("301 Moved Permanently"))
+ return true;
+ else if (str.equals("302 Found"))
+ return true;
+ else if (str.equals("404 Not Found"))
+ return true;
+ else if (str.equals("403 Forbidden"))
+ return true;
+ else if (str.equals("404 File Not Found"))
+ return true;
+ else
+ return false;
+ }
+
+ public static void requestQuery(String hostname, String path, Socket sock) {
+ StringBuffer req = new StringBuffer("GET ");
+ req.append("/");
+ req.append(path);
+ req.append(" HTTP/1.0\r\nHost: ");
+ req.append(hostname);
+ req.append("\r\n\r\n");
+ sock.write(req.toString().getBytes());
+ }
+
+ public static void readResponse(LocalQuery lq, Socket sock) {
+ // state 0 - nothing
+ // state 1 - \r
+ // state 2 - \r\n
+ // state 3 - \r\n\r
+ // state 4 - \r\n\r\n
+ byte[] buffer = new byte[1024];
+ int numchars;
+
+ do {
+ numchars = sock.read(buffer);
+
+ String curr = (new String(buffer)).subString(0, numchars);
+
+ lq.response.append(curr);
+ buffer = new byte[1024];
+ } while(numchars > 0);
+ }
+
+ public void processedList() {
+ LinkedList ll;
+ String token = null;
+ int mindex = 0;
+ int endquote = 0;
+
+ while (endquote != -1) {
+ endquote = title.indexOf(' ', mindex);
+
+ if (endquote != -1) {
+ token = title.subString(mindex, endquote);
+ mindex = endquote + 1;
+ if (filter(token)) {
+ continue;
+ }
+ token = refine(token);
+ }
+ else {
+ token = title.subString(mindex);
+ token = refine(token);
+ }
+
+ Queue q = (Queue)results.get(token);
+ if (q == null) {
+ q = new Queue();
+ }
+ q.push(workingURL);
+ results.put(token, q);
+ }
+ }
+
+ public boolean filter(String str) {
+ if (str.equals("of")) return true;
+ else if (str.equals("for")) return true;
+ else if (str.equals("a")) return true;
+ else if (str.equals("an")) return true;
+ else if (str.equals("the")) return true;
+ else if (str.equals("at")) return true;
+ else if (str.equals("and")) return true;
+ else if (str.equals("or")) return true;
+ else if (str.equals("but")) return true;
+ else if (str.equals("to")) return true;
+ else if (str.equals("The")) return true;
+ else if (str.length() == 1) {
+ if (str.charAt(0) == '.') return true;
+ else if (str.charAt(0) == '.') return true;
+ else if (str.charAt(0) == '-') return true;
+ else if (str.charAt(0) == '=') return true;
+ else if (str.charAt(0) == '_') return true;
+ else if (str.charAt(0) == ':') return true;
+ else if (str.charAt(0) == ';') return true;
+ else if (str.charAt(0) == '\'') return true;
+ else if (str.charAt(0) == '\"') return true;
+ else if (str.charAt(0) == '|') return true;
+ else if (str.charAt(0) == '@') return true;
+ else if (str.charAt(0) == '&') return true;
+ else if (str.charAt(0) == ' ') return true;
+ }
+ else return false;
+ }
+
+ public String refine(String str) { // if title has some unnecessary prefix or postfix
+ str = refinePrefix(str);
+ str = refinePostfix(str);
+ return str;
+ }
+
+ public String refinePrefix(String str) {
+ if (str.charAt(0) == '&') { // &
+ return str.subString(1);
+ }
+ else if (str.charAt(0) == '/') { // &
+ return str.subString(1);
+ }
+ return str;
+ }
+
+ public String refinePostfix(String str) {
+ if (str.charAt(str.length()-1) == ',') { // ,
+ return str.subString(0, str.length()-1);
+ }
+ else if (str.charAt(str.length()-1) == ':') { // :
+ return str.subString(0, str.length()-1);
+ }
+ else if (str.charAt(str.length()-1) == ';') { // ;
+ return str.subString(0, str.length()-1);
+ }
+ else if (str.charAt(str.length()-1) == '!') { // !
+ return str.subString(0, str.length()-1);
+ }
+ else if (str.charAt(str.length()-1) == 's') { // 's
+ if (str.charAt(str.length()-2) == '\'')
+ return str.subString(0, str.length()-2);
+ }
+ else if (str.charAt(str.length()-1) == '-') {
+ int index = str.length()-2;
+ while (Character.isWhitespace(str.charAt(index--)));
+ return str.subString(0, index+2);
+ }
+ return str;
+ }
+
+ public static Queue processPage(LocalQuery lq) {
+ int index = 0;
+ String href = new String("href=\"");
+ String searchstr = lq.response.toString();
+ int depth;
+ boolean cont = true;
+ Queue toprocess;
+
+ depth = lq.getDepth() + 1;
+
+ toprocess = new Queue();
+ while(cont) {
+ int mindex = searchstr.indexOf(href,index);
+ if (mindex != -1) {
+ int endquote = searchstr.indexOf('"', mindex+href.length());
+ if (endquote != -1) {
+ String match = searchstr.subString(mindex+href.length(), endquote);
+ String match2 = lq.makewebcanonical(match);
+
+ String hostname;
+ String path;
+
+ hostname = new String(lq.getHostName(match));
+ path = new String(lq.getPathName(match));
+
+ if (match2 != null) {
+ LocalQuery gq = new LocalQuery(hostname, path, depth);
+ toprocess.push(gq);
+ }
+ index = endquote;
+ } else cont = false;
+ } else cont = false;
+ }
+ return toprocess;
+ }
+}
--- /dev/null
+public class Spider {
+ public static void main(String[] args) {
+ int maxDepth = 3;
+ int maxSearchDepth = 10;
+ int i, j;
+ QueryTask qt;
+
+ String firstmachine;
+ String firstpage;
+
+ firstmachine = new String(args[0]);
+ if (args.length == 2) {
+ firstpage = new String(args[1]);
+ }
+ else
+ firstpage = new String("");;
+
+ HashMap visitedList = new HashMap(500, 0.75f);
+ HashMap results = new HashMap(100, 0.75f);
+ LinkedList results_list = new LinkedList();
+
+ LocalQuery firstquery = new LocalQuery(firstmachine, firstpage, 0);
+
+ Queue todoList = new Queue();
+ todoList.push(firstquery);
+
+ qt = new QueryTask(todoList, visitedList, maxDepth, maxSearchDepth, results, results_list);
+
+ System.printString("Finished to create Objects\n");
+
+ qt.execute();
+ }
+}
--- /dev/null
+MAINCLASS=Spider
+SUBCLASS=Query
+SRC1=${MAINCLASS}.java
+SRC2=Local${SUBCLASS}.java
+SRC3=${SUBCLASS}Task.java
+FLAGS= -32bit -nooptimize -mainclass ${MAINCLASS}
+default:
+ ../../../../buildscript ${FLAGS} -o ${MAINCLASS} ${SRC2} ${SRC3} ${SRC1}
+
+clean:
+ rm -rf tmpbuilddirectory
+ rm *.bin
--- /dev/null
+/* =============================================================================
+ *
+ * queue.java
+ *
+ * =============================================================================
+ *
+ * Copyright (C) Stanford University, 2006. All Rights Reserved.
+ * Author: Chi Cao Minh
+ *
+ * Ported to Java
+ * Author:Alokika Dash
+ * University of California, Irvine
+ *
+ * =============================================================================
+ *
+ * Unless otherwise noted, the following license applies to STAMP files:
+ *
+ * Copyright (c) 2007, Stanford University
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Stanford University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY STANFORD UNIVERSITY ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * =============================================================================
+ */
+
+public class GlobalQueue{
+ int pop; /* points before element to pop */
+ int push;
+ int capacity;
+ int size;
+ int QUEUE_GROWTH_FACTOR;
+ Object[] elements;
+
+ public GlobalQueue() {
+ GlobalQueue(10);
+ }
+
+ /* =============================================================================
+ * queue_alloc
+ * =============================================================================
+ */
+ public GlobalQueue (int initCapacity)
+ {
+ QUEUE_GROWTH_FACTOR = 2;
+ capacity = ((initCapacity < 2) ? 2 : initCapacity);
+
+ elements = global new Object[capacity];
+ size = 0;
+ pop = capacity - 1;
+ push = 0;
+ capacity = capacity;
+ }
+
+ /* =============================================================================
+ * queue_isEmpty
+ * =============================================================================
+ */
+ public boolean
+ isEmpty ()
+ {
+ return (((pop + 1) % capacity == push) ? true : false);
+ }
+
+
+ /* =============================================================================
+ * queue_clear
+ * =============================================================================
+ */
+ public void
+ queue_clear ()
+ {
+ pop = capacity - 1;
+ push = 0;
+ }
+
+ /* =============================================================================
+ * queue_push
+ * =============================================================================
+ */
+ public boolean
+ push (Object dataPtr)
+ {
+ if(pop == push) {
+// System.out.println("push == pop in Queue.java");
+ return false;
+ }
+
+ /* Need to resize */
+ int newPush = (push + 1) % capacity;
+ if (newPush == pop) {
+
+ int newCapacity = capacity * QUEUE_GROWTH_FACTOR;
+ Object[] newElements = global new Object[newCapacity];
+
+ if (newElements == null) {
+ return false;
+ }
+
+ int dst = 0;
+ Object[] tmpelements = elements;
+ if (pop < push) {
+ int src;
+ for (src = (pop + 1); src < push; src++, dst++) {
+ newElements[dst] = elements[src];
+ }
+ } else {
+ int src;
+ for (src = (pop + 1); src < capacity; src++, dst++) {
+ newElements[dst] = elements[src];
+ }
+ for (src = 0; src < push; src++, dst++) {
+ newElements[dst] = elements[src];
+ }
+ }
+
+ //elements = null;
+ elements = newElements;
+ pop = newCapacity - 1;
+ capacity = newCapacity;
+ push = dst;
+ newPush = push + 1; /* no need modulo */
+ }
+ size++;
+ elements[push] = dataPtr;
+ push = newPush;
+
+ return true;
+ }
+
+
+ /* =============================================================================
+ * queue_pop
+ * =============================================================================
+ */
+ public Object
+ pop ()
+ {
+ int newPop = (pop + 1) % capacity;
+ if (newPop == push) {
+ return null;
+ }
+
+ //Object dataPtr = queuePtr.elements[newPop];
+ //queuePtr.pop = newPop;
+ Object dataPtr = elements[newPop];
+ pop = newPop;
+ size--;
+ return dataPtr;
+ }
+ public int size()
+ {
+ return size;
+ }
+
+}
+/* =============================================================================
+ *
+ * End of queue.java
+ *
+ * =============================================================================
+ */
public class Task {
- Queue todoList;
- DistributedHashMap doneList;
+ GlobalQueue todoList;
Object myWork;
Task() {}
}
}
-
/* for debugging purpose */
atomic {
tasks.output();
}
System.out.println("\n\n I'm done\n\n\n");
- RecoveryStat.printRecoveryStat();
+ RecoveryStat.printRecoveryStat();
}
public static int checkCurrentWorkList(Work mywork) {
--- /dev/null
+/* =============================================================================
+ *
+ * queue.java
+ *
+ * =============================================================================
+ *
+ * Copyright (C) Stanford University, 2006. All Rights Reserved.
+ * Author: Chi Cao Minh
+ *
+ * Ported to Java
+ * Author:Alokika Dash
+ * University of California, Irvine
+ *
+ * =============================================================================
+ *
+ * Unless otherwise noted, the following license applies to STAMP files:
+ *
+ * Copyright (c) 2007, Stanford University
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Stanford University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY STANFORD UNIVERSITY ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * =============================================================================
+ */
+
+public class Queue {
+ int pop; /* points before element to pop */
+ int push;
+ int capacity;
+ int size;
+ int QUEUE_GROWTH_FACTOR;
+ Object[] elements;
+
+ public Queue() {
+ Queue(10);
+ }
+
+ /* =============================================================================
+ * queue_alloc
+ * =============================================================================
+ */
+ public Queue (int initCapacity)
+ {
+ QUEUE_GROWTH_FACTOR = 2;
+ capacity = ((initCapacity < 2) ? 2 : initCapacity);
+
+ elements = new Object[capacity];
+ size = 0;
+ pop = capacity - 1;
+ push = 0;
+ capacity = capacity;
+ }
+
+ /* =============================================================================
+ * queue_isEmpty
+ * =============================================================================
+ */
+ public boolean
+ isEmpty ()
+ {
+ return (((pop + 1) % capacity == push) ? true : false);
+ }
+
+
+ /* =============================================================================
+ * queue_clear
+ * =============================================================================
+ */
+ public void
+ queue_clear ()
+ {
+ pop = capacity - 1;
+ push = 0;
+ }
+
+ /* =============================================================================
+ * queue_push
+ * =============================================================================
+ */
+ public boolean
+ push (Object dataPtr)
+ {
+ if(pop == push) {
+// System.out.println("push == pop in Queue.java");
+ return false;
+ }
+
+ /* Need to resize */
+ int newPush = (push + 1) % capacity;
+ if (newPush == pop) {
+
+ int newCapacity = capacity * QUEUE_GROWTH_FACTOR;
+ Object[] newElements = new Object[newCapacity];
+
+ if (newElements == null) {
+ return false;
+ }
+
+ int dst = 0;
+ Object[] tmpelements = elements;
+ if (pop < push) {
+ int src;
+ for (src = (pop + 1); src < push; src++, dst++) {
+ newElements[dst] = elements[src];
+ }
+ } else {
+ int src;
+ for (src = (pop + 1); src < capacity; src++, dst++) {
+ newElements[dst] = elements[src];
+ }
+ for (src = 0; src < push; src++, dst++) {
+ newElements[dst] = elements[src];
+ }
+ }
+
+ //elements = null;
+ elements = newElements;
+ pop = newCapacity - 1;
+ capacity = newCapacity;
+ push = dst;
+ newPush = push + 1; /* no need modulo */
+ }
+ size++;
+ elements[push] = dataPtr;
+ push = newPush;
+
+ return true;
+ }
+
+
+ /* =============================================================================
+ * queue_pop
+ * =============================================================================
+ */
+ public Object
+ pop ()
+ {
+ int newPop = (pop + 1) % capacity;
+ if (newPop == push) {
+ return null;
+ }
+
+ //Object dataPtr = queuePtr.elements[newPop];
+ //queuePtr.pop = newPop;
+ Object dataPtr = elements[newPop];
+ pop = newPop;
+ size--;
+ return dataPtr;
+ }
+ public int size()
+ {
+ return size;
+ }
+
+}
+/* =============================================================================
+ *
+ * End of queue.java
+ *
+ * =============================================================================
+ */
return -1;
}
+ public int indexOfIgnoreCase(String str, int fromIndex) {
+ if (fromIndex < 0)
+ fromIndex = 0;
+ }
+
public int lastIndexOf(String str, int fromIndex) {
int k=count-str.count;
if (k>fromIndex)