Map Reduce Example Revision



The book <Akka Essential>'s examples are based on Akka 2.0, my revision gets these examples adapted to Akka 2.3 API, so I can play with these examples in new API, more fun, isn't it?

 

import java.util.concurrent.TimeUnit;

import scala.concurrent.Await;
import scala.concurrent.Future;
import scala.concurrent.duration.Duration;
import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;
import akka.pattern.Patterns;
import akka.util.Timeout;

public class MapReduceApplication {
	public static void main(String[] args) throws Exception {
		Timeout timeout = new Timeout(Duration.create(5, TimeUnit.SECONDS));
		ActorSystem _system = ActorSystem.create("MapReduceApp");
		ActorRef master = _system.actorOf(Props.create(MasterActor.class),
				"master");
		master.tell(
				"The quick brown fox tried to jump over the lazy dog and fell on the dog",
				null);
		master.tell("Dog is man's best friend", null); // NULL SELF!
		master.tell("Dog and Fox belong to the same family", null);
		Thread.sleep(5000);
		Future<Object> future = Patterns.ask(master, new Result(), timeout);
		String result = (String) Await.result(future, timeout.duration());
		System.out.println(result);
		_system.shutdown();
	}
}


import akka.actor.ActorRef;
import akka.actor.Props;
import akka.actor.UntypedActor;
import akka.routing.RoundRobinRouter;

public class MasterActor extends UntypedActor {

	ActorRef mapActor = getContext().actorOf(
			Props.create(MapActor.class).withRouter(new RoundRobinRouter(5)),
			"map");
	ActorRef reduceActor = getContext()
			.actorOf(
					Props.create(ReduceActor.class).withRouter(
							new RoundRobinRouter(5)), "reduce");
	ActorRef aggregateActor = getContext().actorOf(
			Props.create(AggregateActor.class), "aggregate");

	@Override
	public void onReceive(Object message) throws Exception {
		if (message instanceof String) {
			mapActor.tell(message, getSelf());
		} else if (message instanceof MapData) {
			reduceActor.tell(message, getSelf());
		} else if (message instanceof ReduceData) {
			aggregateActor.tell(message, getSelf());
		} else if (message instanceof Result) {
			aggregateActor.forward(message, getContext());
		} else
			unhandled(message);
	}

}

import java.util.HashMap;
import java.util.List;

import akka.actor.UntypedActor;

public class ReduceActor extends UntypedActor {

	@Override
	public void onReceive(Object message) throws Exception {
		if (message instanceof MapData) {
			MapData mapData = (MapData) message;
			// reduce the incoming data and forward the result to Master actor
			getSender().tell(reduce(mapData.getDataList()), getSelf());
		} else
			unhandled(message);
	}

	private ReduceData reduce(List<WordCount> dataList) {
		HashMap<String, Integer> reducedMap = new HashMap<String, Integer>();
		for (WordCount wordCount : dataList) {
			if (reducedMap.containsKey(wordCount.getWord())) {
				Integer value = (Integer) reducedMap.get(wordCount.getWord());
				value++;
				reducedMap.put(wordCount.getWord(), value);
			} else {
				reducedMap.put(wordCount.getWord(), Integer.valueOf(1));
			}
		}
		return new ReduceData(reducedMap);
	}
}


import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.StringTokenizer;

import akka.actor.UntypedActor;

public class MapActor extends UntypedActor {

	String[] STOP_WORDS = { "a", "am", "an", "and", "are", "as", "at", "be",
			"do", "go", "if", "in", "is", "it", "of", "on", "the", "to" };
	List<String> STOP_WORDS_LIST = Arrays.asList(STOP_WORDS);

	@Override
	public void onReceive(Object message) throws Exception {
		if (message instanceof String) {
			String work = (String) message;
			// map the words in the sentence and send the result to MasterActor
			getSender().tell(evaluateExpression(work), getSelf());
		} else
			unhandled(message); // dig it!
	}

	private MapData evaluateExpression(String line) {
		List<WordCount> dataList = new ArrayList<WordCount>();
		StringTokenizer parser = new StringTokenizer(line);
		while (parser.hasMoreTokens()) {
			String word = parser.nextToken().toLowerCase();
			if (!STOP_WORDS_LIST.contains(word)) {
				dataList.add(new WordCount(word, Integer.valueOf(1)));
			}
		}
		return new MapData(dataList);
	}
}


import java.util.HashMap;
import java.util.Map;

import akka.actor.UntypedActor;

public class AggregateActor extends UntypedActor {
	private Map<String, Integer> finalReducedMap = new HashMap<String, Integer>();

	@Override
	public void onReceive(Object message) throws Exception {
		if (message instanceof ReduceData) {
			ReduceData reduceData = (ReduceData) message;
			aggregateInMemoryReduce(reduceData.getReduceDataList());
		} else if (message instanceof Result) {
			getSender().tell(finalReducedMap.toString(), getSelf());
		} else
			unhandled(message);
	}

	private void aggregateInMemoryReduce(Map<String, Integer> reducedList) {
		Integer count = null;
		for (String key : reducedList.keySet()) {
			if (finalReducedMap.containsKey(key)) {
				count = reducedList.get(key) + finalReducedMap.get(key);
				finalReducedMap.put(key, count);
			} else {
				finalReducedMap.put(key, reducedList.get(key));
			}
		}
	}
}


import java.util.List;

public class MapData {
	private final List<WordCount> dataList;
	
	public List<WordCount> getDataList() {
		return dataList;
	}

	public MapData(List<WordCount> dataList) {
		this.dataList = dataList;
	}
}


import java.util.HashMap;

public class ReduceData {
	private final HashMap<String, Integer> reduceDataList;

	public HashMap<String, Integer> getReduceDataList() {
		return reduceDataList;
	}

	public ReduceData(HashMap<String, Integer> reduceDataList) {
		this.reduceDataList = reduceDataList;
	}
}


public class Result {

}


public class WordCount {
	private final String word;
	private final Integer count;

	public WordCount(String inWord, Integer inCount) {
		word = inWord;
		count = inCount;
	}

	public String getWord() {
		return word;
	}

	public Integer getCount() {
		return count;
	}
}


Reference:

[1] Akka Essential.


你可能感兴趣的:( Map Reduce Example Revision)