module Data.Metrics.Histogram (
Histogram,
histogram,
exponentiallyDecayingHistogram,
uniformHistogram,
uniformSampler,
module Data.Metrics.Types
) where
import Control.Monad.Base
import Control.Monad.Primitive
import qualified Data.Metrics.Histogram.Internal as P
import Data.Metrics.Internal
import Data.Metrics.Types
import Data.Metrics.Reservoir (Reservoir)
import Data.Metrics.Reservoir.Uniform (unsafeReservoir)
import Data.Metrics.Reservoir.ExponentiallyDecaying (reservoir)
import Data.Primitive.MutVar
import Data.Time.Clock
import Data.Time.Clock.POSIX
import System.Random.MWC
data Histogram m = Histogram
{ fromHistogram :: !(MV m P.Histogram)
, histogramGetSeconds :: !(m NominalDiffTime)
}
instance (MonadBase b m, PrimMonad b) => Clear b m (Histogram b) where
clear h = liftBase $ do
t <- histogramGetSeconds h
updateRef (fromHistogram h) $ P.clear t
instance (MonadBase b m, PrimMonad b) => Update b m (Histogram b) Double where
update h x = liftBase $ do
t <- histogramGetSeconds h
updateRef (fromHistogram h) $ P.update x t
instance (MonadBase b m, PrimMonad b) => Count b m (Histogram b) where
count h = liftBase $ fmap P.count $ readMutVar (fromHistogram h)
instance (MonadBase b m, PrimMonad b) => Statistics b m (Histogram b) where
mean h = liftBase $ applyWithRef (fromHistogram h) P.mean
stddev h = liftBase $ applyWithRef (fromHistogram h) P.stddev
variance h = liftBase $ applyWithRef (fromHistogram h) P.variance
maxVal h = liftBase $ fmap P.maxVal $ readMutVar (fromHistogram h)
minVal h = liftBase $ fmap P.minVal $ readMutVar (fromHistogram h)
instance (MonadBase b m, PrimMonad b) => TakeSnapshot b m (Histogram b) where
snapshot h = liftBase $ applyWithRef (fromHistogram h) P.snapshot
histogram :: (MonadBase b m, PrimMonad b) => b NominalDiffTime -> Reservoir -> m (Histogram b)
histogram t r = do
v <- liftBase $ newMutVar $ P.histogram r
return $ Histogram v t
uniformHistogram :: MonadBase IO m => Seed -> m (Histogram IO)
uniformHistogram s = liftBase $ histogram getPOSIXTime $ unsafeReservoir s 1028
exponentiallyDecayingHistogram :: MonadBase IO m => m (Histogram IO)
exponentiallyDecayingHistogram = liftBase $ do
t <- getPOSIXTime
s <- createSystemRandom >>= save
histogram getPOSIXTime $ reservoir 0.015 1028 t s
uniformSampler :: Seed -> P.Histogram
uniformSampler s = P.histogram (unsafeReservoir s 1028)