import java.util.StringTokenizer; import java.util.Map; import java.util.HashMap; import java.io.BufferedReader; import java.io.FileReader; /** RESULT OF STEP 2: single-threaded program with units of work made clear. Notice that we are now running WordCountTransition on each chunk as it's read, not after all have been read. */ public class WordCountTransition implements Runnable { private String buffer; private Map counts; private final static String DELIMS = " :;,.{}()\t\n"; private final static boolean printAll = false; public WordCountTransition(String buffer, Map counts) { this.counts = counts; this.buffer = buffer; } private static int findDelim(String buf) { for (int i = buf.length() - 1; i>=0; i--) { for (int j = 0; j < DELIMS.length(); j++) { char d = DELIMS.charAt(j); if (d == buf.charAt(i)) return i; } } return 0; } private static String readFileAsString(BufferedReader reader, int size) throws java.io.IOException { StringBuffer fileData = new StringBuffer(size); int numRead=0; while(size > 0) { int bufsz = 1024 > size ? size : 1024; char[] buf = new char[bufsz]; numRead = reader.read(buf,0,bufsz); if (numRead == -1) break; String readData = String.valueOf(buf, 0, numRead); fileData.append(readData); size -= numRead; } return fileData.toString(); } public void run() { StringTokenizer st = new StringTokenizer(buffer," :;,.{}()\t\n"); while (st.hasMoreTokens()) { String token = st.nextToken(); Integer oldCount = counts.remove(token); if (oldCount != null) counts.put(token,oldCount + 1); else counts.put(token,1); } } public static void main(String args[]) throws java.io.IOException { long startTime = System.currentTimeMillis(); Map m = new HashMap(); if (args.length != 1) { System.out.println("Usage: \n"); System.exit(1); } BufferedReader reader = new BufferedReader(new FileReader(args[0])); String leftover = ""; while (true) { String res = readFileAsString(reader,1000); if (res.equals("")) { if (!leftover.equals("")) new WordCountTransition(leftover,m).run(); break; } int endidx = findDelim(res); new WordCountTransition(leftover+res.substring(0,endidx),m).run(); leftover = res.substring(endidx,res.length()); } long endTime = System.currentTimeMillis(); long elapsed = endTime - startTime; int total = 0; for (Map.Entry entry : m.entrySet()) { int count = entry.getValue(); if (printAll) System.out.format("%-30s %d\n",entry.getKey(),count); total += count; } System.out.println("Total words = "+total); System.out.println("Total time = "+elapsed+" ms"); } }