{-# LANGUAGE RecordWildCards #-} module Type( Val(..), mergeVal, valFromProfile ) where import GHC.Prof import Data.Maybe import Data.Scientific import Data.Tree import qualified Data.Text as T data Val = Val {name :: String -- Name of this node ,timeTot :: Double -- Time spent under this node ,timeInh :: Double -- Time spent under this node excluding rerooted ,timeInd :: Double -- Time spent in this code ,entries :: Integer -- Number of times this node was called } deriving Show mergeVal :: Val -> Val -> Val mergeVal x y | name x /= name y = error "mergeRoots, invariant violated" | otherwise = Val {name = name x ,timeTot = timeTot x + timeTot y ,timeInh = timeInh x + timeInh y ,timeInd = timeInd x + timeInd y ,entries = entries x + entries y} valFromProfile :: Profile -> Tree Val valFromProfile prf = case costCentres prf of Nothing -> error "Failed to generate value tree from profile (no idea why - corrupt profile?)" Just x | isNothing $ costCentreTicks $ rootLabel x -> fmap toValTime x | otherwise -> fixTotInh $ fmap (toValTick $ (* 0.01) $ fromInteger $ totalTimeTicks $ profileTotalTime prf) x toValTime :: CostCentre -> Val toValTime CostCentre{..} = Val (T.unpack costCentreModule ++ " " ++ T.unpack costCentreName) inh inh (toRealFloat costCentreIndTime) costCentreEntries where inh = toRealFloat costCentreInhTime toValTick :: Double -> CostCentre -> Val toValTick tot cc = (toValTime cc){timeInd = fromInteger (fromJust $ costCentreTicks cc) / tot} fixTotInh :: Tree Val -> Tree Val fixTotInh (Node x xs) = Node x{timeTot=t, timeInh=t} ys where ys = map fixTotInh xs t = timeInd x + sum (map (timeInh . rootLabel) ys)