{-# LANGUAGE FlexibleContexts #-}

-- |
-- Module     : Simulation.Aivika.Trans.GPSS.Queue
-- Copyright  : Copyright (c) 2017, David Sorokin <david.sorokin@gmail.com>
-- License    : BSD3
-- Maintainer : David Sorokin <david.sorokin@gmail.com>
-- Stability  : experimental
-- Tested with: GHC 8.0.2
--
-- This module defines a GPSS queue entity.
--
module Simulation.Aivika.Trans.GPSS.Queue
       (-- * Queue Types
        Queue,
        QueueEntry(..),
        -- * Creating Queue
        newQueue,
        -- * Queue Properties and Activities
        queueNull,
        queueContent,
        queueContentStats,
        enqueueCount,
        enqueueZeroEntryCount,
        queueWaitTime,
        queueNonZeroEntryWaitTime,
        queueRate,
        -- * Dequeuing and Enqueuing
        enqueue,
        dequeue,
        -- * Statistics Reset
        resetQueue,
        -- * Derived Signals for Properties
        queueNullChanged,
        queueNullChanged_,
        queueContentChanged,
        queueContentChanged_,
        enqueueCountChanged,
        enqueueCountChanged_,
        enqueueZeroEntryCountChanged,
        enqueueZeroEntryCountChanged_,
        queueWaitTimeChanged,
        queueWaitTimeChanged_,
        queueNonZeroEntryWaitTimeChanged,
        queueNonZeroEntryWaitTimeChanged_,
        queueRateChanged,
        queueRateChanged_,
        -- * Basic Signals
        enqueued,
        dequeued,
        -- * Overall Signal
        queueChanged_) where

import Data.Monoid
import Data.Maybe
import Data.Hashable

import Control.Monad
import Control.Monad.Trans

import Simulation.Aivika.Trans
import Simulation.Aivika.Trans.Internal.Specs
import Simulation.Aivika.Trans.Internal.Simulation
import Simulation.Aivika.Trans.Internal.Dynamics
import Simulation.Aivika.Trans.Internal.Event
import Simulation.Aivika.Trans.Internal.Process
import Simulation.Aivika.Trans.Signal
import Simulation.Aivika.Trans.Statistics

import Simulation.Aivika.Trans.GPSS.Transact

-- | Represents the queue entity.
data Queue m =
  Queue { forall (m :: * -> *). Queue m -> Int
queueSequenceNo :: Int,
          forall (m :: * -> *). Queue m -> Ref m Int
queueContentRef :: Ref m Int,
          forall (m :: * -> *). Queue m -> Ref m (TimingStats Int)
queueContentStatsRef :: Ref m (TimingStats Int),
          forall (m :: * -> *). Queue m -> Ref m Int
enqueueCountRef :: Ref m Int,
          forall (m :: * -> *). Queue m -> Ref m Int
enqueueZeroEntryCountRef :: Ref m Int,
          forall (m :: * -> *). Queue m -> Ref m (SamplingStats Double)
queueWaitTimeRef :: Ref m (SamplingStats Double),
          forall (m :: * -> *). Queue m -> Ref m (SamplingStats Double)
queueNonZeroEntryWaitTimeRef :: Ref m (SamplingStats Double),
          forall (m :: * -> *). Queue m -> SignalSource m ()
enqueuedSource :: SignalSource m (),
          forall (m :: * -> *). Queue m -> SignalSource m ()
dequeuedSource :: SignalSource m ()
        }

-- | The information about queue entry.
data QueueEntry m =
  QueueEntry { forall (m :: * -> *). QueueEntry m -> Queue m
entryQueue :: Queue m,
               -- ^ the entry queue
               forall (m :: * -> *). QueueEntry m -> Double
entryEnqueueTime :: Double
               -- ^ the time of registering the queue entry
             } deriving QueueEntry m -> QueueEntry m -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (m :: * -> *).
MonadDES m =>
QueueEntry m -> QueueEntry m -> Bool
/= :: QueueEntry m -> QueueEntry m -> Bool
$c/= :: forall (m :: * -> *).
MonadDES m =>
QueueEntry m -> QueueEntry m -> Bool
== :: QueueEntry m -> QueueEntry m -> Bool
$c== :: forall (m :: * -> *).
MonadDES m =>
QueueEntry m -> QueueEntry m -> Bool
Eq

instance MonadDES m => Eq (Queue m) where
  Queue m
x == :: Queue m -> Queue m -> Bool
== Queue m
y = (forall (m :: * -> *). Queue m -> Ref m Int
queueContentRef Queue m
x) forall a. Eq a => a -> a -> Bool
== (forall (m :: * -> *). Queue m -> Ref m Int
queueContentRef Queue m
y)

instance MonadDES m => Hashable (Queue m) where
  hashWithSalt :: Int -> Queue m -> Int
hashWithSalt Int
salt Queue m
x = forall a. Hashable a => Int -> a -> Int
hashWithSalt Int
salt (forall (m :: * -> *). Queue m -> Int
queueSequenceNo Queue m
x)

-- | Create a new queue.
newQueue :: MonadDES m => Event m (Queue m)
{-# INLINABLE newQueue #-}
newQueue :: forall (m :: * -> *). MonadDES m => Event m (Queue m)
newQueue =
  do Double
t  <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
DynamicsLift t m =>
Dynamics m a -> t m a
liftDynamics forall (m :: * -> *). Monad m => Dynamics m Double
time
     Generator m
g  <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
ParameterLift t m =>
Parameter m a -> t m a
liftParameter forall (m :: * -> *). Monad m => Parameter m (Generator m)
generatorParameter
     Int
no <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
MonadCompTrans t m =>
m a -> t m a
liftComp forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *). MonadGenerator m => Generator m -> m Int
generateSequenceNo Generator m
g
     Ref m Int
i  <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
SimulationLift t m =>
Simulation m a -> t m a
liftSimulation forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => a -> Simulation m (Ref m a)
newRef Int
0
     Ref m (TimingStats Int)
is <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
SimulationLift t m =>
Simulation m a -> t m a
liftSimulation forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => a -> Simulation m (Ref m a)
newRef forall a b. (a -> b) -> a -> b
$ forall a. TimingData a => Double -> a -> TimingStats a
returnTimingStats Double
t Int
0
     Ref m Int
e  <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
SimulationLift t m =>
Simulation m a -> t m a
liftSimulation forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => a -> Simulation m (Ref m a)
newRef Int
0
     Ref m Int
z  <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
SimulationLift t m =>
Simulation m a -> t m a
liftSimulation forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => a -> Simulation m (Ref m a)
newRef Int
0 
     Ref m (SamplingStats Double)
w  <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
SimulationLift t m =>
Simulation m a -> t m a
liftSimulation forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => a -> Simulation m (Ref m a)
newRef forall a. Monoid a => a
mempty
     Ref m (SamplingStats Double)
w2 <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
SimulationLift t m =>
Simulation m a -> t m a
liftSimulation forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => a -> Simulation m (Ref m a)
newRef forall a. Monoid a => a
mempty
     SignalSource m ()
s1 <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
SimulationLift t m =>
Simulation m a -> t m a
liftSimulation forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Simulation m (SignalSource m a)
newSignalSource
     SignalSource m ()
s2 <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
SimulationLift t m =>
Simulation m a -> t m a
liftSimulation forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Simulation m (SignalSource m a)
newSignalSource
     forall (m :: * -> *) a. Monad m => a -> m a
return Queue { queueSequenceNo :: Int
queueSequenceNo = Int
no,
                    queueContentRef :: Ref m Int
queueContentRef = Ref m Int
i,
                    queueContentStatsRef :: Ref m (TimingStats Int)
queueContentStatsRef = Ref m (TimingStats Int)
is,
                    enqueueCountRef :: Ref m Int
enqueueCountRef = Ref m Int
e,
                    enqueueZeroEntryCountRef :: Ref m Int
enqueueZeroEntryCountRef = Ref m Int
z,
                    queueWaitTimeRef :: Ref m (SamplingStats Double)
queueWaitTimeRef = Ref m (SamplingStats Double)
w,
                    queueNonZeroEntryWaitTimeRef :: Ref m (SamplingStats Double)
queueNonZeroEntryWaitTimeRef = Ref m (SamplingStats Double)
w2,
                    enqueuedSource :: SignalSource m ()
enqueuedSource = SignalSource m ()
s1,
                    dequeuedSource :: SignalSource m ()
dequeuedSource = SignalSource m ()
s2 }
  
-- | Test whether the queue is empty.
--
-- See also 'queueNullChanged' and 'queueNullChanged_'.
queueNull :: MonadDES m => Queue m -> Event m Bool
{-# INLINABLE queueNull #-}
queueNull :: forall (m :: * -> *). MonadDES m => Queue m -> Event m Bool
queueNull Queue m
q =
  forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p ->
  do Int
n <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *). Queue m -> Ref m Int
queueContentRef Queue m
q)
     forall (m :: * -> *) a. Monad m => a -> m a
return (Int
n forall a. Eq a => a -> a -> Bool
== Int
0)
  
-- | Signal when the 'queueNull' property value has changed.
queueNullChanged :: MonadDES m => Queue m -> Signal m Bool
{-# INLINABLE queueNullChanged #-}
queueNullChanged :: forall (m :: * -> *). MonadDES m => Queue m -> Signal m Bool
queueNullChanged Queue m
q =
  forall (m :: * -> *) a b.
MonadDES m =>
(a -> Event m b) -> Signal m a -> Signal m b
mapSignalM (forall a b. a -> b -> a
const forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *). MonadDES m => Queue m -> Event m Bool
queueNull Queue m
q) (forall (m :: * -> *). MonadDES m => Queue m -> Signal m ()
queueNullChanged_ Queue m
q)
  
-- | Signal when the 'queueNull' property value has changed.
queueNullChanged_ :: MonadDES m => Queue m -> Signal m ()
{-# INLINABLE queueNullChanged_ #-}
queueNullChanged_ :: forall (m :: * -> *). MonadDES m => Queue m -> Signal m ()
queueNullChanged_ = forall (m :: * -> *). MonadDES m => Queue m -> Signal m ()
queueContentChanged_

-- | Return the current queue content.
--
-- See also 'queueContentStats', 'queueContentChanged' and 'queueContentChanged_'.
queueContent :: MonadDES m => Queue m -> Event m Int
{-# INLINABLE queueContent #-}
queueContent :: forall (m :: * -> *). MonadDES m => Queue m -> Event m Int
queueContent Queue m
q =
  forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p -> forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *). Queue m -> Ref m Int
queueContentRef Queue m
q)

-- | Return the queue content statistics.
queueContentStats :: MonadDES m => Queue m -> Event m (TimingStats Int)
{-# INLINABLE queueContentStats #-}
queueContentStats :: forall (m :: * -> *).
MonadDES m =>
Queue m -> Event m (TimingStats Int)
queueContentStats Queue m
q =
  forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p -> forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *). Queue m -> Ref m (TimingStats Int)
queueContentStatsRef Queue m
q)
  
-- | Signal when the 'queueContent' property value has changed.
queueContentChanged :: MonadDES m => Queue m -> Signal m Int
{-# INLINABLE queueContentChanged #-}
queueContentChanged :: forall (m :: * -> *). MonadDES m => Queue m -> Signal m Int
queueContentChanged Queue m
q =
  forall (m :: * -> *) a b.
MonadDES m =>
(a -> Event m b) -> Signal m a -> Signal m b
mapSignalM (forall a b. a -> b -> a
const forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *). MonadDES m => Queue m -> Event m Int
queueContent Queue m
q) (forall (m :: * -> *). MonadDES m => Queue m -> Signal m ()
queueContentChanged_ Queue m
q)
  
-- | Signal when the 'queueContent' property value has changed.
queueContentChanged_ :: MonadDES m => Queue m -> Signal m ()
{-# INLINABLE queueContentChanged_ #-}
queueContentChanged_ :: forall (m :: * -> *). MonadDES m => Queue m -> Signal m ()
queueContentChanged_ Queue m
q =
  forall (m :: * -> *) a b.
MonadDES m =>
(a -> b) -> Signal m a -> Signal m b
mapSignal (forall a b. a -> b -> a
const ()) (forall (m :: * -> *). MonadDES m => Queue m -> Signal m ()
enqueued Queue m
q) forall a. Semigroup a => a -> a -> a
<>
  forall (m :: * -> *) a b.
MonadDES m =>
(a -> b) -> Signal m a -> Signal m b
mapSignal (forall a b. a -> b -> a
const ()) (forall (m :: * -> *). MonadDES m => Queue m -> Signal m ()
dequeued Queue m
q)

-- | Return the total number of input items that were enqueued.
--
-- See also 'enqueueCountChanged' and 'enqueueCountChanged_'.
enqueueCount :: MonadDES m => Queue m -> Event m Int
{-# INLINABLE enqueueCount #-}
enqueueCount :: forall (m :: * -> *). MonadDES m => Queue m -> Event m Int
enqueueCount Queue m
q =
  forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p -> forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *). Queue m -> Ref m Int
enqueueCountRef Queue m
q)
  
-- | Signal when the 'enqueueCount' property value has changed.
enqueueCountChanged :: MonadDES m => Queue m -> Signal m Int
{-# INLINABLE enqueueCountChanged #-}
enqueueCountChanged :: forall (m :: * -> *). MonadDES m => Queue m -> Signal m Int
enqueueCountChanged Queue m
q =
  forall (m :: * -> *) a b.
MonadDES m =>
(a -> Event m b) -> Signal m a -> Signal m b
mapSignalM (forall a b. a -> b -> a
const forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *). MonadDES m => Queue m -> Event m Int
enqueueCount Queue m
q) (forall (m :: * -> *). MonadDES m => Queue m -> Signal m ()
enqueueCountChanged_ Queue m
q)
  
-- | Signal when the 'enqueueCount' property value has changed.
enqueueCountChanged_ :: MonadDES m => Queue m -> Signal m ()
{-# INLINABLE enqueueCountChanged_ #-}
enqueueCountChanged_ :: forall (m :: * -> *). MonadDES m => Queue m -> Signal m ()
enqueueCountChanged_ Queue m
q =
  forall (m :: * -> *) a b.
MonadDES m =>
(a -> b) -> Signal m a -> Signal m b
mapSignal (forall a b. a -> b -> a
const ()) (forall (m :: * -> *). MonadDES m => Queue m -> Signal m ()
enqueued Queue m
q)

-- | Return the total number of zero entry items.
--
-- See also 'enqueueZeroEntryCountChanged' and 'enqueueZeroEntryCountChanged_'.
enqueueZeroEntryCount :: MonadDES m => Queue m -> Event m Int
{-# INLINABLE enqueueZeroEntryCount #-}
enqueueZeroEntryCount :: forall (m :: * -> *). MonadDES m => Queue m -> Event m Int
enqueueZeroEntryCount Queue m
q =
  forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p -> forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *). Queue m -> Ref m Int
enqueueZeroEntryCountRef Queue m
q)
  
-- | Signal when the 'enqueueZeroEntryCount' property value has changed.
enqueueZeroEntryCountChanged :: MonadDES m => Queue m -> Signal m Int
{-# INLINABLE enqueueZeroEntryCountChanged #-}
enqueueZeroEntryCountChanged :: forall (m :: * -> *). MonadDES m => Queue m -> Signal m Int
enqueueZeroEntryCountChanged Queue m
q =
  forall (m :: * -> *) a b.
MonadDES m =>
(a -> Event m b) -> Signal m a -> Signal m b
mapSignalM (forall a b. a -> b -> a
const forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *). MonadDES m => Queue m -> Event m Int
enqueueZeroEntryCount Queue m
q) (forall (m :: * -> *). MonadDES m => Queue m -> Signal m ()
enqueueZeroEntryCountChanged_ Queue m
q)
  
-- | Signal when the 'enqueueZeroEntryCount' property value has changed.
enqueueZeroEntryCountChanged_ :: MonadDES m => Queue m -> Signal m ()
{-# INLINABLE enqueueZeroEntryCountChanged_ #-}
enqueueZeroEntryCountChanged_ :: forall (m :: * -> *). MonadDES m => Queue m -> Signal m ()
enqueueZeroEntryCountChanged_ Queue m
q =
  forall (m :: * -> *) a b.
MonadDES m =>
(a -> b) -> Signal m a -> Signal m b
mapSignal (forall a b. a -> b -> a
const ()) (forall (m :: * -> *). MonadDES m => Queue m -> Signal m ()
dequeued Queue m
q)

-- | Return the wait (or residence) time.
--
-- See also 'queueWaitTimeChanged' and 'queueWaitTimeChanged_'.
queueWaitTime :: MonadDES m => Queue m -> Event m (SamplingStats Double)
{-# INLINABLE queueWaitTime #-}
queueWaitTime :: forall (m :: * -> *).
MonadDES m =>
Queue m -> Event m (SamplingStats Double)
queueWaitTime Queue m
q =
  forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p -> forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *). Queue m -> Ref m (SamplingStats Double)
queueWaitTimeRef Queue m
q)
      
-- | Signal when the 'queueWaitTime' property value has changed.
queueWaitTimeChanged :: MonadDES m => Queue m -> Signal m (SamplingStats Double)
{-# INLINABLE queueWaitTimeChanged #-}
queueWaitTimeChanged :: forall (m :: * -> *).
MonadDES m =>
Queue m -> Signal m (SamplingStats Double)
queueWaitTimeChanged Queue m
q =
  forall (m :: * -> *) a b.
MonadDES m =>
(a -> Event m b) -> Signal m a -> Signal m b
mapSignalM (forall a b. a -> b -> a
const forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
MonadDES m =>
Queue m -> Event m (SamplingStats Double)
queueWaitTime Queue m
q) (forall (m :: * -> *). MonadDES m => Queue m -> Signal m ()
queueWaitTimeChanged_ Queue m
q)
  
-- | Signal when the 'queueWaitTime' property value has changed.
queueWaitTimeChanged_ :: MonadDES m => Queue m -> Signal m ()
{-# INLINABLE queueWaitTimeChanged_ #-}
queueWaitTimeChanged_ :: forall (m :: * -> *). MonadDES m => Queue m -> Signal m ()
queueWaitTimeChanged_ Queue m
q =
  forall (m :: * -> *) a b.
MonadDES m =>
(a -> b) -> Signal m a -> Signal m b
mapSignal (forall a b. a -> b -> a
const ()) (forall (m :: * -> *). MonadDES m => Queue m -> Signal m ()
dequeued Queue m
q)
      
-- | Return the wait (or residence) time excluding zero entries.
--
-- See also 'queueNonZeroEntryWaitTimeChanged' and 'queueNonZeroEntryWaitTimeChanged_'.
queueNonZeroEntryWaitTime :: MonadDES m => Queue m -> Event m (SamplingStats Double)
{-# INLINABLE queueNonZeroEntryWaitTime #-}
queueNonZeroEntryWaitTime :: forall (m :: * -> *).
MonadDES m =>
Queue m -> Event m (SamplingStats Double)
queueNonZeroEntryWaitTime Queue m
q =
  forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p -> forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *). Queue m -> Ref m (SamplingStats Double)
queueNonZeroEntryWaitTimeRef Queue m
q)
      
-- | Signal when the 'queueNonZeroEntryWaitTime' property value has changed.
queueNonZeroEntryWaitTimeChanged :: MonadDES m => Queue m -> Signal m (SamplingStats Double)
{-# INLINABLE queueNonZeroEntryWaitTimeChanged #-}
queueNonZeroEntryWaitTimeChanged :: forall (m :: * -> *).
MonadDES m =>
Queue m -> Signal m (SamplingStats Double)
queueNonZeroEntryWaitTimeChanged Queue m
q =
  forall (m :: * -> *) a b.
MonadDES m =>
(a -> Event m b) -> Signal m a -> Signal m b
mapSignalM (forall a b. a -> b -> a
const forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
MonadDES m =>
Queue m -> Event m (SamplingStats Double)
queueNonZeroEntryWaitTime Queue m
q) (forall (m :: * -> *). MonadDES m => Queue m -> Signal m ()
queueNonZeroEntryWaitTimeChanged_ Queue m
q)
  
-- | Signal when the 'queueNonZeroEntryWaitTime' property value has changed.
queueNonZeroEntryWaitTimeChanged_ :: MonadDES m => Queue m -> Signal m ()
{-# INLINABLE queueNonZeroEntryWaitTimeChanged_ #-}
queueNonZeroEntryWaitTimeChanged_ :: forall (m :: * -> *). MonadDES m => Queue m -> Signal m ()
queueNonZeroEntryWaitTimeChanged_ Queue m
q =
  forall (m :: * -> *) a b.
MonadDES m =>
(a -> b) -> Signal m a -> Signal m b
mapSignal (forall a b. a -> b -> a
const ()) (forall (m :: * -> *). MonadDES m => Queue m -> Signal m ()
dequeued Queue m
q)

-- | Return a long-term average queue rate calculated as
-- the average queue size divided by the average wait time.
--
-- See also 'queueRateChanged' and 'queueRateChanged_'.
queueRate :: MonadDES m => Queue m -> Event m Double
{-# INLINABLE queueRate #-}
queueRate :: forall (m :: * -> *). MonadDES m => Queue m -> Event m Double
queueRate Queue m
q =
  forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p ->
  do TimingStats Int
x <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *). Queue m -> Ref m (TimingStats Int)
queueContentStatsRef Queue m
q)
     SamplingStats Double
y <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *). Queue m -> Ref m (SamplingStats Double)
queueWaitTimeRef Queue m
q)
     forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. TimingData a => TimingStats a -> Double
timingStatsMean TimingStats Int
x forall a. Fractional a => a -> a -> a
/ forall a. SamplingStats a -> Double
samplingStatsMean SamplingStats Double
y) 
      
-- | Signal when the 'queueRate' property value has changed.
queueRateChanged :: MonadDES m => Queue m -> Signal m Double
{-# INLINABLE queueRateChanged #-}
queueRateChanged :: forall (m :: * -> *). MonadDES m => Queue m -> Signal m Double
queueRateChanged Queue m
q =
  forall (m :: * -> *) a b.
MonadDES m =>
(a -> Event m b) -> Signal m a -> Signal m b
mapSignalM (forall a b. a -> b -> a
const forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *). MonadDES m => Queue m -> Event m Double
queueRate Queue m
q) (forall (m :: * -> *). MonadDES m => Queue m -> Signal m ()
queueRateChanged_ Queue m
q)
      
-- | Signal when the 'queueRate' property value has changed.
queueRateChanged_ :: MonadDES m => Queue m -> Signal m ()
{-# INLINABLE queueRateChanged_ #-}
queueRateChanged_ :: forall (m :: * -> *). MonadDES m => Queue m -> Signal m ()
queueRateChanged_ Queue m
q =
  forall (m :: * -> *) a b.
MonadDES m =>
(a -> b) -> Signal m a -> Signal m b
mapSignal (forall a b. a -> b -> a
const ()) (forall (m :: * -> *). MonadDES m => Queue m -> Signal m ()
enqueued Queue m
q) forall a. Semigroup a => a -> a -> a
<>
  forall (m :: * -> *) a b.
MonadDES m =>
(a -> b) -> Signal m a -> Signal m b
mapSignal (forall a b. a -> b -> a
const ()) (forall (m :: * -> *). MonadDES m => Queue m -> Signal m ()
dequeued Queue m
q)

-- | Return a signal that notifies when enqueuing an item.
enqueued:: MonadDES m => Queue m -> Signal m ()
{-# INLINABLE enqueued #-}
enqueued :: forall (m :: * -> *). MonadDES m => Queue m -> Signal m ()
enqueued Queue m
q = forall (m :: * -> *) a. SignalSource m a -> Signal m a
publishSignal (forall (m :: * -> *). Queue m -> SignalSource m ()
enqueuedSource Queue m
q)

-- | Return a signal that notifies when the dequeuing the item.
dequeued :: MonadDES m => Queue m -> Signal m ()
{-# INLINABLE dequeued #-}
dequeued :: forall (m :: * -> *). MonadDES m => Queue m -> Signal m ()
dequeued Queue m
q = forall (m :: * -> *) a. SignalSource m a -> Signal m a
publishSignal (forall (m :: * -> *). Queue m -> SignalSource m ()
dequeuedSource Queue m
q)

-- | Enqueue the item.
enqueue :: MonadDES m
           => Queue m
           -- ^ the queue
           -> Transact m a
           -- ^ the item to be enqueued
           -> Int
           -- ^ the content increment
           -> Event m ()
{-# INLINABLE enqueue #-}
enqueue :: forall (m :: * -> *) a.
MonadDES m =>
Queue m -> Transact m a -> Int -> Event m ()
enqueue Queue m
q Transact m a
transact Int
increment =
  forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p ->
  do let t :: Double
t = forall (m :: * -> *). Point m -> Double
pointTime Point m
p
         e :: QueueEntry m
e = QueueEntry { entryQueue :: Queue m
entryQueue = Queue m
q,
                          entryEnqueueTime :: Double
entryEnqueueTime = Double
t }
     Int
n <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *). Queue m -> Ref m Int
enqueueCountRef Queue m
q)
     let n' :: Int
n' = Int
n forall a. Num a => a -> a -> a
+ Int
1
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
       forall (m :: * -> *) a. MonadDES m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *). Queue m -> Ref m Int
enqueueCountRef Queue m
q) Int
n'
     Int
c <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *). Queue m -> Ref m Int
queueContentRef Queue m
q)
     let c' :: Int
c' = Int
c forall a. Num a => a -> a -> a
+ Int
increment
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
       forall (m :: * -> *) a. MonadDES m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *). Queue m -> Ref m Int
queueContentRef Queue m
q) Int
c'
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
       forall (m :: * -> *) a.
MonadDES m =>
Ref m a -> (a -> a) -> Event m ()
modifyRef (forall (m :: * -> *). Queue m -> Ref m (TimingStats Int)
queueContentStatsRef Queue m
q) (forall a.
TimingData a =>
Double -> a -> TimingStats a -> TimingStats a
addTimingStats Double
t Int
c')
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
       forall (m :: * -> *) a.
MonadDES m =>
Transact m a -> QueueEntry m -> Event m ()
registerTransactQueueEntry Transact m a
transact QueueEntry m
e
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
       forall (m :: * -> *) a. SignalSource m a -> a -> Event m ()
triggerSignal (forall (m :: * -> *). Queue m -> SignalSource m ()
enqueuedSource Queue m
q) ()

-- | Dequeue the item.
dequeue :: MonadDES m
           => Queue m
           -- ^ the queue
           -> Transact m a
           -- ^ the item to be dequeued
           -> Int
           -- ^ the content decrement
           -> Event m ()
{-# INLINABLE dequeue #-}
dequeue :: forall (m :: * -> *) a.
MonadDES m =>
Queue m -> Transact m a -> Int -> Event m ()
dequeue Queue m
q Transact m a
transact Int
decrement =
  forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p ->
  do QueueEntry m
e <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
          forall (m :: * -> *) a.
MonadDES m =>
Transact m a -> Queue m -> Event m (QueueEntry m)
unregisterTransactQueueEntry Transact m a
transact Queue m
q
     let t :: Double
t  = forall (m :: * -> *). Point m -> Double
pointTime Point m
p
         t0 :: Double
t0 = forall (m :: * -> *). QueueEntry m -> Double
entryEnqueueTime QueueEntry m
e
         dt :: Double
dt = Double
t forall a. Num a => a -> a -> a
- Double
t0
     Int
c <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *). Queue m -> Ref m Int
queueContentRef Queue m
q)
     let c' :: Int
c' = Int
c forall a. Num a => a -> a -> a
- Int
decrement
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
       forall (m :: * -> *) a. MonadDES m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *). Queue m -> Ref m Int
queueContentRef Queue m
q) Int
c'
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
       forall (m :: * -> *) a.
MonadDES m =>
Ref m a -> (a -> a) -> Event m ()
modifyRef (forall (m :: * -> *). Queue m -> Ref m (TimingStats Int)
queueContentStatsRef Queue m
q) (forall a.
TimingData a =>
Double -> a -> TimingStats a -> TimingStats a
addTimingStats Double
t Int
c')
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
       forall (m :: * -> *) a.
MonadDES m =>
Ref m a -> (a -> a) -> Event m ()
modifyRef (forall (m :: * -> *). Queue m -> Ref m (SamplingStats Double)
queueWaitTimeRef Queue m
q) forall a b. (a -> b) -> a -> b
$
       forall a. SamplingData a => a -> SamplingStats a -> SamplingStats a
addSamplingStats Double
dt
     if Double
t forall a. Eq a => a -> a -> Bool
== Double
t0
       then forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
            forall (m :: * -> *) a.
MonadDES m =>
Ref m a -> (a -> a) -> Event m ()
modifyRef (forall (m :: * -> *). Queue m -> Ref m Int
enqueueZeroEntryCountRef Queue m
q) (forall a. Num a => a -> a -> a
+ Int
1)
       else forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
            forall (m :: * -> *) a.
MonadDES m =>
Ref m a -> (a -> a) -> Event m ()
modifyRef (forall (m :: * -> *). Queue m -> Ref m (SamplingStats Double)
queueNonZeroEntryWaitTimeRef Queue m
q) forall a b. (a -> b) -> a -> b
$
            forall a. SamplingData a => a -> SamplingStats a -> SamplingStats a
addSamplingStats Double
dt
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
       forall (m :: * -> *) a. SignalSource m a -> a -> Event m ()
triggerSignal (forall (m :: * -> *). Queue m -> SignalSource m ()
dequeuedSource Queue m
q) ()

-- | Signal whenever any property of the queue changes.
--
-- The property must have the corresponded signal. There are also characteristics
-- similar to the properties but that have no signals. As a rule, such characteristics
-- already depend on the simulation time and therefore they may change at any
-- time point.
queueChanged_ :: MonadDES m => Queue m -> Signal m ()
{-# INLINABLE queueChanged_ #-}
queueChanged_ :: forall (m :: * -> *). MonadDES m => Queue m -> Signal m ()
queueChanged_ Queue m
q =
  forall (m :: * -> *) a b.
MonadDES m =>
(a -> b) -> Signal m a -> Signal m b
mapSignal (forall a b. a -> b -> a
const ()) (forall (m :: * -> *). MonadDES m => Queue m -> Signal m ()
enqueued Queue m
q) forall a. Semigroup a => a -> a -> a
<>
  forall (m :: * -> *) a b.
MonadDES m =>
(a -> b) -> Signal m a -> Signal m b
mapSignal (forall a b. a -> b -> a
const ()) (forall (m :: * -> *). MonadDES m => Queue m -> Signal m ()
dequeued Queue m
q)

-- | Reset the statistics.
resetQueue :: MonadDES m => Queue m -> Event m ()
{-# INLINABLE resetQueue #-}
resetQueue :: forall (m :: * -> *). MonadDES m => Queue m -> Event m ()
resetQueue Queue m
q =
  do Double
t  <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
DynamicsLift t m =>
Dynamics m a -> t m a
liftDynamics forall (m :: * -> *). Monad m => Dynamics m Double
time
     Int
content <- forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *). Queue m -> Ref m Int
queueContentRef Queue m
q)
     forall (m :: * -> *) a. MonadDES m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *). Queue m -> Ref m (TimingStats Int)
queueContentStatsRef Queue m
q) forall a b. (a -> b) -> a -> b
$
       forall a. TimingData a => Double -> a -> TimingStats a
returnTimingStats Double
t Int
content
     forall (m :: * -> *) a. MonadDES m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *). Queue m -> Ref m Int
enqueueCountRef Queue m
q) Int
0
     forall (m :: * -> *) a. MonadDES m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *). Queue m -> Ref m Int
enqueueZeroEntryCountRef Queue m
q) Int
0
     forall (m :: * -> *) a. MonadDES m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *). Queue m -> Ref m (SamplingStats Double)
queueWaitTimeRef Queue m
q) forall a. Monoid a => a
mempty
     forall (m :: * -> *) a. MonadDES m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *). Queue m -> Ref m (SamplingStats Double)
queueNonZeroEntryWaitTimeRef Queue m
q) forall a. Monoid a => a
mempty