profiteur-0.4.2.0: src/Profiteur/Parser.hs
--------------------------------------------------------------------------------
{-# LANGUAGE OverloadedStrings #-}
module Profiteur.Parser
( decode
) where
--------------------------------------------------------------------------------
import qualified Data.IntMap as IM
import qualified Data.Scientific as Scientific
import qualified Data.Set as Set
import qualified Data.Text as T
import qualified Data.Text.Lazy as TL
import qualified Data.Vector as V
import qualified GHC.Prof as Prof
import qualified GHC.Prof.Types as Prof
--------------------------------------------------------------------------------
import Profiteur.Core
--------------------------------------------------------------------------------
decode :: TL.Text -> Either String CostCentre
decode txt = Prof.decode txt >>= profileToCostCentre
--------------------------------------------------------------------------------
profileToCostCentre :: Prof.Profile -> Either String CostCentre
profileToCostCentre prof = do
rootNo <- findRoot
toCostCentreByNo rootNo
where
tree :: Prof.CostCentreTree
tree = Prof.profileCostCentreTree prof
findRoot :: Either String Prof.CostCentreNo
findRoot = case IM.toList (Prof.costCentreParents tree) of
[] -> Left "Could not find root node"
((_, no) : _) -> go no
where
go no = case IM.lookup no (Prof.costCentreParents tree) of
Nothing -> Right no
Just par -> go par
toCostCentreByNo :: Prof.CostCentreNo -> Either String CostCentre
toCostCentreByNo no = do
cc <- maybe (Left $ "Could not find CCN " ++ show no) Right $
IM.lookup no (Prof.costCentreNodes tree)
toCostCentreByNode cc
toCostCentreByNode :: Prof.CostCentre -> Either String CostCentre
toCostCentreByNode cc = do
let no = Prof.costCentreNo cc
childrenNodes = maybe [] Set.toList $
IM.lookup no (Prof.costCentreChildren tree)
children <- V.mapM toCostCentreByNode (V.fromList childrenNodes)
return CostCentre
{ ccName = Prof.costCentreName cc
, ccModule = Prof.costCentreModule cc
, ccId = T.pack (show $ no)
, ccEntries = fromIntegral (Prof.costCentreEntries cc)
, ccIndividualTime = Scientific.toRealFloat (Prof.costCentreIndTime cc)
, ccIndividualAlloc = Scientific.toRealFloat (Prof.costCentreIndAlloc cc)
, ccInheritedTime = Scientific.toRealFloat (Prof.costCentreInhTime cc)
, ccInheritedAlloc = Scientific.toRealFloat (Prof.costCentreInhAlloc cc)
, ccChildren = children
}