public class QueryTask extends Task { int maxDepth; Queue toprocess; DistributedHashMap results; GlobalString workingURL; public QueryTask(Queue todoList, DistributedHashMap doneList, int maxDepth, DistributedHashMap results) { this.todoList = todoList; this.doneList = doneList; this.maxDepth = maxDepth; this.results = results; } public void execute() { int depth; int max; atomic { depth = ((GlobalQuery)myWork).getDepth(); max = this.maxDepth; } if (depth < max) { /* global variables */ GlobalQuery gq; /* local variables */ LocalQuery lq; String hostname; String path; atomic { gq = (GlobalQuery)myWork; hostname = new String(GlobalString.toLocalCharArray(gq.getHostName())); path = new String(GlobalString.toLocalCharArray(gq.getPath())); GlobalStringBuffer gsb = global new GlobalStringBuffer(hostname); gsb.append("/"); gsb.append(path); workingURL = global new GlobalString(gsb.toGlobalString()); } lq = new LocalQuery(hostname, path, depth); System.printString(lq.getDepth()+" "); System.printString("Processing - Hostname : "); System.printString(hostname); System.printString(", Path : "); System.printString(path); System.printString("\n"); Socket s = new Socket(hostname, 80); requestQuery(hostname, path, s); readResponse(lq, s); atomic { processList(lq, workingURL, results); } atomic { toprocess = processPage(lq); } s.close(); } } public void done(Object obj) { GlobalString str = global new GlobalString("true"); doneList.put(workingURL, str); while(!toprocess.isEmpty()) { GlobalQuery q = (GlobalQuery)toprocess.pop(); GlobalString hostname = global new GlobalString(q.getHostName()); GlobalString path = global new GlobalString(q.getPath()); GlobalStringBuffer gsb = global new GlobalStringBuffer(hostname); gsb.append("/"); gsb.append(path); if (!doneList.containsKey(gsb.toGlobalString())) { todoList.push(q); } } } public static void requestQuery(String hostname, String path, Socket sock) { StringBuffer req = new StringBuffer("GET "); req.append("/"); req.append(path); req.append(" HTTP/1.1\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 int state=0; while(true) { if (state<4) { if (state==0) { byte[] b=new byte[1]; int numchars=sock.read(b); if ((numchars==1)) { if (b[0]=='\r') { state++; } } else return; } else if (state==1) { byte[] b=new byte[1]; int numchars=sock.read(b); if (numchars==1) { if (b[0]=='\n') state++; else state=0; } else return; } else if (state==2) { byte[] b=new byte[1]; int numchars=sock.read(b); if (numchars==1) { if (b[0]=='\r') state++; else state=0; } else return; } else if (state==3) { byte[] b=new byte[1]; int numchars=sock.read(b); if (numchars==1) { if (b[0]=='\n') state++; else state=0; } else return; } } else { byte[] buffer=new byte[1024]; int numchars=sock.read(buffer); if (numchars==0) return; else { String curr=(new String(buffer)).subString(0,numchars); lq.response.append(curr); } } } } public static void processList(LocalQuery lq, GlobalString url, DistributedHashMap results) { String sTitle = new String("