11package fj .demo .concurrent ;
22
3- import static fj .Monoid .monoid ;
4- import static fj .Monoid .monoidDef ;
5- import static fj .control .parallel .ParModule .parModule ;
6- import static fj .data .List .nil ;
7- import static java .util .concurrent .Executors .newFixedThreadPool ;
3+ import fj .F ;
4+ import fj .Monoid ;
5+ import fj .P ;
6+ import fj .P1 ;
7+ import fj .P2 ;
8+ import fj .control .parallel .ParModule ;
9+ import fj .control .parallel .Promise ;
10+ import fj .control .parallel .Strategy ;
11+ import fj .data .IOFunctions ;
12+ import fj .data .Iteratee .Input ;
13+ import fj .data .Iteratee .IterV ;
14+ import fj .data .List ;
15+ import fj .data .Option ;
816
917import java .io .BufferedWriter ;
1018import java .io .File ;
1422import java .io .Reader ;
1523import java .io .StringWriter ;
1624import java .io .Writer ;
17- import java .nio .charset .Charset ;
1825import java .util .Collections ;
1926import java .util .HashMap ;
2027import java .util .Map ;
2128import java .util .concurrent .ExecutorService ;
2229
23- import fj .F ;
24- import fj .Monoid ;
25- import fj .P ;
26- import fj .P1 ;
27- import fj .P2 ;
28- import fj .Unit ;
29- import fj .control .parallel .ParModule ;
30- import fj .control .parallel .Promise ;
31- import fj .control .parallel .Strategy ;
32- import fj .data .*;
33- import fj .data .Iteratee .Input ;
34- import fj .data .Iteratee .IterV ;
35- import fj .function .Effect1 ;
30+ import static fj .Monoid .monoid ;
31+ import static fj .control .parallel .ParModule .parModule ;
32+ import static fj .data .List .nil ;
33+ import static java .util .concurrent .Executors .newFixedThreadPool ;
3634
3735/**
3836 * Reads words and their counts from files ({@link #getWordsAndCountsFromFiles} in a single thread
3937 * and {@link #getWordsAndCountsFromFilesInParallel} in multiple threads). The files are created
4038 * initially and populated with some sample content.
41- *
39+ *
4240 * @author Martin Grotzke
4341 */
4442public class WordCount {
45-
43+
4644 // Integers.add.f(1) caused an SOE...
4745 private static final F <Integer ,Integer > addOne = a -> a .intValue () + 1 ;
4846
@@ -55,23 +53,23 @@ private static <K, V> Map<K, V> update(Map<K, V> map, K key, F<V, V> valueFuncti
5553 map .put (key , valueFunction .f (value ));
5654 return map ;
5755 }
58-
56+
5957 private static final F <String , Map <String , Integer >> fileNameToWordsAndCountsWithCharChunkIteratee = fileName -> {
6058 try {
6159 return IOFunctions .enumFileCharChunks (new File (fileName ), Option .none (), wordCountsFromCharChunks ()).run ().run ();
6260 } catch (final IOException e ) {
6361 throw new RuntimeException (e );
6462 }
6563 };
66-
64+
6765 private static final F <String , Map <String , Integer >> fileNameToWordsAndCountsWithCharChunk2Iteratee = fileName -> {
6866 try {
6967 return IOFunctions .enumFileChars (new File (fileName ), Option .none (), wordCountsFromChars ()).run ().run ();
7068 } catch (final IOException e ) {
7169 throw new RuntimeException (e );
7270 }
7371 };
74-
72+
7573 private static final F <String , Map <String , Integer >> fileNameToWordsAndCountsWithCharIteratee = fileName -> {
7674 try {
7775 return IOFunctions .enumFileChars (new File (fileName ), Option .none (), wordCountsFromChars ()).run ().run ();
@@ -181,7 +179,7 @@ public static void main(String[] args) throws IOException {
181179 final Map <String , Integer > expectedWordsAndCounts = result ._2 ();
182180 long avgSize = fileNames .foldLeft ((a , file ) -> a .longValue () + new File (file ).length (), 0l ) / fileNames .length ();
183181 System .out .println ("Processing " + numFiles + " files with ~" +numSharedWords +" words and an avg size of " + avgSize + " bytes." );
184-
182+
185183 // warmup
186184 for (int i = 0 ; i < 1 ; i ++) {
187185 // getWordsAndCountsFromFiles(fileNames.take(1)).size();
@@ -211,7 +209,7 @@ public static void main(String[] args) throws IOException {
211209 assertTrue (wordsAndCountsFromFiles != null );
212210 assertEquals (wordsAndCountsFromFiles .size (), numFiles + numSharedWords );
213211 assertEquals (wordsAndCountsFromFiles , expectedWordsAndCounts );
214-
212+
215213 System .gc ();
216214
217215 // get word counts sequentially / single threaded \w iteratee
@@ -223,7 +221,7 @@ public static void main(String[] args) throws IOException {
223221 assertEquals (wordsAndCountsFromFiles , expectedWordsAndCounts );
224222
225223 System .gc ();
226-
224+
227225 // get word counts sequentially / single threaded \w iteratee
228226 start = System .currentTimeMillis ();
229227 wordsAndCountsFromFiles = getWordsAndCountsFromFilesWithIteratee (fileNames , fileNameToWordsAndCountsWithCharChunk2Iteratee );
@@ -233,7 +231,7 @@ public static void main(String[] args) throws IOException {
233231 assertEquals (wordsAndCountsFromFiles , expectedWordsAndCounts );
234232
235233 System .gc ();
236-
234+
237235// start = System.currentTimeMillis();
238236// wordsAndCountsFromFiles = getWordsAndCountsFromFilesInParallel(fileNames, fileNameToWordsAndCounts, 8);
239237// System.out.println("Getting word counts in 8 threads took " + (System.currentTimeMillis() - start) + " ms.");
@@ -249,14 +247,14 @@ public static void main(String[] args) throws IOException {
249247 assertEquals (wordsAndCountsFromFiles , expectedWordsAndCounts );
250248
251249 System .gc ();
252-
250+
253251 start = System .currentTimeMillis ();
254252 wordsAndCountsFromFiles = getWordsAndCountsFromFilesInParallel (fileNames , fileNameToWordsAndCountsWithCharChunkIteratee , 32 );
255253 System .out .println ("Getting word counts in 32 threads with char chunk iteratee took " + (System .currentTimeMillis () - start ) + " ms." );
256254 assertTrue (wordsAndCountsFromFiles != null );
257255 assertEquals (wordsAndCountsFromFiles .size (), numFiles + numSharedWords );
258256 assertEquals (wordsAndCountsFromFiles , expectedWordsAndCounts );
259-
257+
260258 // we have tmpfiles, but still want to be sure not to leave rubbish
261259 fileNames .foreachDoEffect (a -> new File (a ).delete ());
262260 }
@@ -286,13 +284,13 @@ private static P2<List<String>, Map<String, Integer>> writeSampleFiles(
286284 }
287285 return P .p (fileNames , expectedWordsAndCounts );
288286 }
289-
287+
290288 public static Map <String , Integer > getWordsAndCountsFromFilesWithIteratee (final List <String > fileNames ,
291289 final F <String , Map <String , Integer >> fileNameToWordsAndCountsWithIteratee ) {
292290 final List <Map <String , Integer >> maps = fileNames .map (fileNameToWordsAndCountsWithIteratee );
293291 return maps .foldLeft (WordCount ::plus , new HashMap <String , Integer >());
294292 }
295-
293+
296294 public static Map <String , Integer > getWordsAndCountsFromFilesInParallel (
297295 final List <String > fileNames , final F <String , Map <String , Integer >> fileNameToWordsAndCounts , int numThreads ) {
298296 final ExecutorService pool = newFixedThreadPool (numThreads );
@@ -305,14 +303,14 @@ public static Map<String, Integer> getWordsAndCountsFromFilesInParallel(
305303
306304 return result ;
307305 }
308-
306+
309307 // Read documents and extract words and word counts of documents
310308 public static Promise <Map <String , Integer >> getWordsAndCountsFromFiles (
311309 final List <String > fileNames , final F <String , Map <String , Integer >> fileNameToWordsAndCounts , final ParModule m ) {
312- final Monoid <Map <String , Integer >> monoid = monoidDef (WordCount ::plus , Collections .emptyMap ());
310+ final Monoid <Map <String , Integer >> monoid = monoid (WordCount ::plus , Collections .emptyMap ());
313311 return m .parFoldMap (fileNames , fileNameToWordsAndCounts , monoid );
314312 }
315-
313+
316314 private static Map <String , Integer > plus (Map <String , Integer > a , Map <String , Integer > b ) {
317315 final Map <String , Integer > result = new HashMap <>(a );
318316 for (Map .Entry <String , Integer > entry : b .entrySet ()) {
@@ -321,7 +319,7 @@ private static Map<String, Integer> plus(Map<String, Integer> a, Map<String, Int
321319 }
322320 return result ;
323321 }
324-
322+
325323 @ SuppressWarnings ("unused" )
326324 private static String readFileToString (File file ) throws IOException {
327325 Reader reader = null ;
@@ -342,13 +340,13 @@ private static void copy(Reader reader, Writer writer) throws IOException {
342340 writer .write (buffer , 0 , n );
343341 }
344342 }
345-
343+
346344 static void assertTrue (boolean condition ) {
347345 if (!condition ) {
348346 throw new AssertionError ();
349347 }
350348 }
351-
349+
352350 static void assertEquals (Object actual , Object expected ) {
353351 if (!expected .equals (actual )) {
354352 throw new IllegalArgumentException ("Not equals. Expected: " + expected + ", actual: " + actual );
0 commit comments