@@ -28,9 +28,9 @@ import Control.Concurrent (threadDelay)
28--------------------------------------------------------------------------------
28--------------------------------------------------------------------------------
30-- | MapReduce skeleton
30-- | MapReduce skeleton
31−data MapReduce k1 v1 k2 v2 = MapReduce {
31+data MapReduce k1 v1 k2 v2 v3 = MapReduce {
32 mrMap :: k1 -> v1 -> [(k2, v2)]
32 mrMap :: k1 -> v1 -> [(k2, v2)]
33− , mrReduce :: k2 -> [v2] -> v2
33+ , mrReduce :: k2 -> [v2] -> v3
34 } deriving (Typeable)
34 } deriving (Typeable)
36-- | Local (non-distributed) implementation of the map-reduce algorithm
36-- | Local (non-distributed) implementation of the map-reduce algorithm
@@ -38,19 +38,19 @@ data MapReduce k1 v1 k2 v2 = MapReduce {
38-- This can be regarded as the specification of map-reduce; see
38-- This can be regarded as the specification of map-reduce; see
39-- /Google’s MapReduce Programming Model---Revisited/ by Ralf Laemmel
39-- /Google’s MapReduce Programming Model---Revisited/ by Ralf Laemmel
40-- (<http://userpages.uni-koblenz.de/~laemmel/MapReduce/>).
40-- (<http://userpages.uni-koblenz.de/~laemmel/MapReduce/>).
41−localMapReduce :: forall k1 k2 v1 v2. Ord k2 =>
41+localMapReduce :: forall k1 k2 v1 v2 v3. Ord k2 =>
42− MapReduce k1 v1 k2 v2
42+ MapReduce k1 v1 k2 v2 v3
43 -> Map k1 v1
43 -> Map k1 v1
44− -> Map k2 v2
44+ -> Map k2 v3
45localMapReduce mr = reducePerKey mr . groupByKey . mapPerKey mr
45localMapReduce mr = reducePerKey mr . groupByKey . mapPerKey mr
47−reducePerKey :: MapReduce k1 v1 k2 v2 -> Map k2 [v2] -> Map k2 v2
47+reducePerKey :: MapReduce k1 v1 k2 v2 v3 -> Map k2 [v2] -> Map k2 v3
48reducePerKey mr = Map.mapWithKey (mrReduce mr)
48reducePerKey mr = Map.mapWithKey (mrReduce mr)
50groupByKey :: Ord k2 => [(k2, v2)] -> Map k2 [v2]
50groupByKey :: Ord k2 => [(k2, v2)] -> Map k2 [v2]
51groupByKey = Map.fromListWith (++) . map (second return)
51groupByKey = Map.fromListWith (++) . map (second return)
53−mapPerKey :: MapReduce k1 v1 k2 v2 -> Map k1 v1 -> [(k2, v2)]
53+mapPerKey :: MapReduce k1 v1 k2 v2 v3 -> Map k1 v1 -> [(k2, v2)]
54mapPerKey mr = concatMap (uncurry (mrMap mr)) . Map.toList
54mapPerKey mr = concatMap (uncurry (mrMap mr)) . Map.toList
56--------------------------------------------------------------------------------
56--------------------------------------------------------------------------------
@@ -63,11 +63,11 @@ matchDict SerializableDict = match
63sendDict :: forall a. SerializableDict a -> ProcessId -> a -> Process ()
63sendDict :: forall a. SerializableDict a -> ProcessId -> a -> Process ()
64sendDict SerializableDict = send
64sendDict SerializableDict = send
66−mapperProcess :: forall k1 v1 k2 v2.
66+mapperProcess :: forall k1 v1 k2 v2 v3.
67 SerializableDict (ProcessId, k1, v1)
67 SerializableDict (ProcessId, k1, v1)
68 -> SerializableDict [(k2, v2)]
68 -> SerializableDict [(k2, v2)]
69 -> ProcessId
69 -> ProcessId
70− -> MapReduce k1 v1 k2 v2
70+ -> MapReduce k1 v1 k2 v2 v3
71 -> Process ()
71 -> Process ()
72mapperProcess dictIn dictOut workQueue mr = do
72mapperProcess dictIn dictOut workQueue mr = do
73 us <- getSelfPid
73 us <- getSelfPid
@@ -97,30 +97,30 @@ mapperProcess dictIn dictOut workQueue mr = do
98remotable ['mapperProcess]
98remotable ['mapperProcess]
100−mapperProcessClosure :: forall k1 v1 k2 v2.
100+mapperProcessClosure :: forall k1 v1 k2 v2 v3.
101− (Typeable k1, Typeable v1, Typeable k2, Typeable v2)
101+ (Typeable k1, Typeable v1, Typeable k2, Typeable v2, Typeable v3)
102 => Static (SerializableDict (ProcessId, k1, v1))
102 => Static (SerializableDict (ProcessId, k1, v1))
103 -> Static (SerializableDict [(k2, v2)])
103 -> Static (SerializableDict [(k2, v2)])
104− -> Closure (MapReduce k1 v1 k2 v2)
104+ -> Closure (MapReduce k1 v1 k2 v2 v3)
105 -> ProcessId
105 -> ProcessId
106 -> Closure (Process ())
106 -> Closure (Process ())
107mapperProcessClosure dictIn dictOut mr pid =
107mapperProcessClosure dictIn dictOut mr pid =
108 closure decoder (encode pid) `closureApply` mr
108 closure decoder (encode pid) `closureApply` mr
110− decoder :: Static (ByteString -> MapReduce k1 v1 k2 v2 -> Process ())
110+ decoder :: Static (ByteString -> MapReduce k1 v1 k2 v2 v3 -> Process ())
111 decoder =
111 decoder =
112 ($(mkStatic 'mapperProcess) `staticApply` dictIn `staticApply` dictOut)
112 ($(mkStatic 'mapperProcess) `staticApply` dictIn `staticApply` dictOut)
113 `staticCompose`
113 `staticCompose`
114 staticDecode sdictProcessId
114 staticDecode sdictProcessId
116−distrMapReduce :: forall k1 k2 v1 v2.
116+distrMapReduce :: forall k1 k2 v1 v2 v3.
117− (Serializable k1, Serializable v1, Serializable k2, Serializable v2, Ord k2)
117+ (Serializable k1, Serializable v1, Serializable k2, Serializable v2, Serializable v3, Ord k2)
118 => Static (SerializableDict (ProcessId, k1, v1))
118 => Static (SerializableDict (ProcessId, k1, v1))
119 -> Static (SerializableDict [(k2, v2)])
119 -> Static (SerializableDict [(k2, v2)])
120− -> Closure (MapReduce k1 v1 k2 v2)
120+ -> Closure (MapReduce k1 v1 k2 v2 v3)
121 -> [NodeId]
121 -> [NodeId]
122 -> Map k1 v1
122 -> Map k1 v1
123− -> Process (Map k2 v2)
123+ -> Process (Map k2 v3)
124distrMapReduce dictIn dictOut mr mappers input = do
124distrMapReduce dictIn dictOut mr mappers input = do
125 us <- getSelfPid
125 us <- getSelfPid
126 slavesTerminated <- liftIO $ newEmptyMVar
126 slavesTerminated <- liftIO $ newEmptyMVar