module Data.ZoomCache.Int (
RawData(..)
, SummaryData(..)
, SummaryWork(..)
)where
import Blaze.ByteString.Builder
import Control.Monad (replicateM)
import Control.Monad.Trans (MonadIO)
import Data.Iteratee (Iteratee)
import Data.Monoid
import Data.Word
import Text.Printf
import Data.ZoomCache.Codec
instance ZoomReadable Int where
data RawData Int = RDInt [Int]
readRaw = zReadInt32
fromList = RDInt
data SummaryData Int = SummaryInt
{ summaryIntEntry :: Int
, summaryIntExit :: Int
, summaryIntMin :: Int
, summaryIntMax :: Int
, summaryIntAvg :: Double
, summaryIntRMS :: Double
}
readSummary = readSummaryInt
prettyRawData = prettyPacketInt
prettySummaryData = prettySummaryInt
prettyPacketInt :: RawData Int -> [String]
prettyPacketInt (RDInt ds) = map show ds
readSummaryInt :: (Functor m, MonadIO m)
=> Iteratee [Word8] m (SummaryData Int)
readSummaryInt = do
[en,ex,mn,mx] <- replicateM 4 zReadInt32
[avg,rms] <- replicateM 2 zReadFloat64be
return (SummaryInt en ex mn mx avg rms)
prettySummaryInt :: SummaryData Int -> String
prettySummaryInt SummaryInt{..} = concat
[ printf "\tentry: %d\texit: %df\tmin: %d\tmax: %d\t"
summaryIntEntry summaryIntExit summaryIntMin summaryIntMax
, printf "avg: %.3f\trms: %.3f" summaryIntAvg summaryIntRMS
]
instance ZoomWrite Int where
write = writeData
instance ZoomWrite (TimeStamp, Int) where
write = writeDataVBR
instance ZoomWritable Int where
data SummaryWork Int = SummaryWorkInt
{ ztsiTime :: TimeStamp
, ztsiEntry :: Int
, ztsiExit :: Int
, ztsiMin :: Int
, ztsiMax :: Int
, ztsiSum :: Int
, ztsiSumSq :: Double
}
fromRaw = fromIntegral32be
fromSummaryData = fromSummaryInt
initSummaryWork = initSummaryInt
toSummaryData = mkSummaryInt
updateSummaryData = updateSummaryInt
appendSummaryData = appendSummaryInt
initSummaryInt :: TimeStamp -> SummaryWork Int
initSummaryInt entry = SummaryWorkInt
{ ztsiTime = entry
, ztsiEntry = 0
, ztsiExit = 0
, ztsiMin = maxBound
, ztsiMax = minBound
, ztsiSum = 0
, ztsiSumSq = 0
}
mkSummaryInt :: Double -> SummaryWork Int -> SummaryData Int
mkSummaryInt dur SummaryWorkInt{..} = SummaryInt
{ summaryIntEntry = ztsiEntry
, summaryIntExit = ztsiExit
, summaryIntMin = ztsiMin
, summaryIntMax = ztsiMax
, summaryIntAvg = fromIntegral ztsiSum / dur
, summaryIntRMS = sqrt $ ztsiSumSq / dur
}
fromSummaryInt :: SummaryData Int -> Builder
fromSummaryInt SummaryInt{..} = mconcat $ map fromIntegral32be
[ summaryIntEntry
, summaryIntExit
, summaryIntMin
, summaryIntMax
] ++ map fromDouble
[ summaryIntAvg
, summaryIntRMS
]
updateSummaryInt :: Int -> TimeStamp -> Int -> SummaryWork Int
-> SummaryWork Int
updateSummaryInt count t i SummaryWorkInt{..} = SummaryWorkInt
{ ztsiTime = t
, ztsiEntry = if count == 0 then i else ztsiEntry
, ztsiExit = i
, ztsiMin = min ztsiMin i
, ztsiMax = max ztsiMax i
, ztsiSum = ztsiSum + (i * dur)
, ztsiSumSq = ztsiSumSq + fromIntegral (i*i * dur)
}
where
dur = fromIntegral $ (unTS t) (unTS ztsiTime)
appendSummaryInt :: Double -> SummaryData Int
-> Double -> SummaryData Int
-> SummaryData Int
appendSummaryInt dur1 s1 dur2 s2 = SummaryInt
{ summaryIntEntry = summaryIntEntry s1
, summaryIntExit = summaryIntExit s2
, summaryIntMin = min (summaryIntMin s1) (summaryIntMin s2)
, summaryIntMax = max (summaryIntMax s1) (summaryIntMax s2)
, summaryIntAvg = ((summaryIntAvg s1 * dur1) +
(summaryIntAvg s2 * dur2)) /
durSum
, summaryIntRMS = sqrt $ ((summaryIntRMS s1 * summaryIntRMS s1 * dur1) +
(summaryIntRMS s2 * summaryIntRMS s2 * dur2)) /
durSum
}
where
durSum = dur1 + dur2