module ParIndices (parIndices) where
import Control.Parallel
import Control.DeepSeq
import GHC.Conc (numCapabilities)
import Data.Sequence (Seq)
import qualified Data.Sequence as Seq
import Data.List (elemIndices)
-- Split input sequence into numCapabilities even-sized chunks
--
parIndices :: (Eq a) => a -> Seq a -> [Int]
parIndices e xs = indices 0 e (chunk xs)
where
indices :: (Eq a) => Int -> a -> [Seq a] -> [Int]
indices _ _ [] = []
indices offs e (xs:xss) = hs `par` (ts `pseq` (hs ++ ts))
where
hs = force $ map (offs +) $ Seq.findIndicesL (e ==) xs
ts = force $ indices (offs + len) e xss
chunk xs | Seq.null xs = []
| otherwise = l:chunk r
where
(l,r) = Seq.splitAt len xs
len = ceiling $ fromIntegral (Seq.length xs) / fromIntegral numCapabilities