eventlog2html-0.4.0: src/Eventlog/Prune.hs
module Eventlog.Prune
( prune
) where
import Data.Text (Text)
import Data.List (sortBy)
import Data.Ord (comparing)
import Data.Map.Strict (Map, toList, fromList)
import Eventlog.Args (Args(..), Sort(..))
type Compare a = a -> a -> Ordering
getComparison :: Args -> Compare (Text, (Double, Double))
getComparison Args { sorting = Size, reversing = False } = cmpSizeDescending
getComparison Args { sorting = Size, reversing = True } = cmpSizeAscending
getComparison Args { sorting = StdDev, reversing = False } = cmpStdDevDescending
getComparison Args { sorting = StdDev, reversing = True } = cmpStdDevAscending
getComparison Args { sorting = Name, reversing = True } = cmpNameDescending
getComparison Args { sorting = Name, reversing = False } = cmpNameAscending
cmpNameAscending, cmpNameDescending,
cmpStdDevAscending, cmpStdDevDescending,
cmpSizeAscending, cmpSizeDescending :: Compare (Text, (Double, Double))
cmpNameAscending = comparing fst
cmpNameDescending = flip cmpNameAscending
cmpStdDevAscending = comparing (snd . snd)
cmpStdDevDescending = flip cmpStdDevAscending
cmpSizeAscending = comparing (fst . snd)
cmpSizeDescending = flip cmpSizeAscending
prune :: Args -> Map Text (Double, Double) -> Map Text Int
prune args ts =
let ccTotals = sortBy cmpSizeDescending (toList ts)
sizes = map (fst . snd) ccTotals
limit = sum sizes
bigs = takeWhile (< limit) . scanl (+) 0 $ sizes
bands = zipWith const ccTotals $ take (bound $ nBands args) bigs
ccs = map fst (sortBy (getComparison args) bands)
in fromList (reverse ccs `zip` [1 ..])
bound :: Int -> Int
bound n
| n <= 0 = maxBound
| otherwise = n