Card Only Sequential Map Reduce Framework Assignment
Contents
Motivation
Building a parallel MapReduce framework with five generic types can be challenging. This warmup takes the bottlenecked approach to MapReduce, but sequentially and with specific types- the ones from the Card Counting application. We will later build a parallel framework with specific types, followed by a parallel generic framework.
Java Utilities
List<E>, implementations: class ArrayList<E>, class LinkedList<E>
Map<K, V>, implementations: class HashMap<K,V>, class EnumMap<K extends Enum<K>,V>
Building On Previous Exercises
Be sure to complete the Card Mapper and Summing Int Classic Reducer exercises first.
Code To Investigate
CardOnlySequentialMapReduceFramework
You will build each of the three methods mapReduceAll(input) invokes. Much can be gleaned from the parameters and return values of these methods.
mapReduceAll(Deck[] input) |
---|
@Override
public java.util.Map<Suit, Integer> mapReduceAll(Deck[] input) {
List<List<Map.Entry<Suit, Integer>>> mapAllResult = mapAll(input);
Map<Suit, List<Integer>> accumulateAllResult = accumulateAll(mapAllResult);
return reduceAll(accumulateAllResult);
}
|
mapAll
Given Deck[] input:
input[0] = | { ♥ THREE, | ♣ EIGHT, | ♦ FIVE, | ♠ JACK, | ♣ SEVEN } |
input[1] = | { ♣ JACK, | ♦ NINE, | ♥ TEN, | ♥ TWO, | ♠ FIVE } |
input[2] = | { ♠ SIX, | ♦ TWO, | ♥ QUEEN, | ♦ EIGHT, | ♠ FOUR } |
input[3] = | { ♣ QUEEN, | ♦ SEVEN, | ♥ SIX, | ♣ KING, | ♠ THREE } |
mapAll(input) will return:
accumulateAll
accumulateAll(mapAllResult) would produce a Map<Suit, List<Integer>>. Below we visualize a Map with 4 buckets that places entries based on the key's hashCode().
Note: due to the hashCode implementation of enums in Java, the structure of a hash table will be different for different runs, depending on the initial memory locations of the Suit enum constants.
reduceAll
reduceAll(accumulateAllResult) would produce a Map<Suit, Integer>
. Below we visualize a Map with 4 buckets that places entries based on the key's hashCode().
Note: due to the hashCode implementation of enums in Java, the structure of a hash table will be different for different runs, depending on the initial memory locations of the Suit enum constants. This visualization used the same run as in accumulateAll's visualization. Therefore the initial memory locations were the same (and therefore the buckets each key hashed to is the same).
Note: the keys all fall in the same location as in accumulateAllResult, but are associated with the reduced values.
Code To Implement
CardOnlySequentialMapReduceFramework
mapper
method: public Mapper<Deck, Suit, Integer> mapper()
(sequential implementation only)
This method exists to remind you to use the mapper. The type is a perfect match for the CardMapper:
accumulatorCombinerReducer
method: public Reducer<Integer, List<Integer>, Integer> reducer()
(sequential implementation only)
This method exists to remind you to use the accumulatorCombinerReducer. The type is a perfect match for the SummingIntClassicReducer:
public abstract class ClassicReducer<V, R> implements AccumulatorCombinerReducer<V, List<V>, R>
public class SummingIntClassicReducer extends ClassicReducer<Integer, Integer>
mapAll
method: private List<List<Map.Entry<Suit, Integer>>> mapAll(Deck[] input)
(sequential implementation only)
Requirement: |
Use the mapper's map method |
accumulateAll
method: private Map<Suit, List<Integer>> accumulateAll(List<List<Map.Entry<Suit, Integer>>> mapAllResults)
(sequential implementation only)
Requirement: |
Use the accumulatorCombinerReducer's createMutableContainer and accumulate methods |
reduceAll
method: private Map<Suit, Integer> reduceAll(Map<Suit, List<Integer>> accumulateAllResult)
(sequential implementation only)
Requirement: |
Use the accumulatorCombinerReducer's reduce method |
Client
class: | CardOnlySequentialMapReduceFrameworkClient.java | CLIENT |
package: | mapreduce.framework.sequential.client | |
source folder: | student/src/main/java |
CardOnlySequentialMapReduceFrameworkClient |
---|
Deck[] decks = new Deck[] {
Deck.createFull(),
Deck.createFull(),
Deck.createFull(),
Deck.createFull(),
};
MapReduceFramework<Deck, Suit, Integer, List<Integer>, Integer> framework = new CardOnlySequentialMapReduceFramework(
new CardMapper(), new SummingIntClassicReducer());
Map<Suit, Integer> map = framework.mapReduceAll(decks);
for (Entry<Suit, Integer> entry : map.entrySet()) {
System.out.println(entry);
}
|
CardOnlySequentialMapReduceFrameworkClient Output |
---|
DIAMONDS=216 SPADES=216 CLUBS=216 HEARTS=216 |
Testing Your Solution
class: | _CardOnlySequentialMapReduceFrameworkTestSuite.java | |
package: | mapreduce.framework.sequential.group | |
source folder: | testing/src/test/java |