module Simulation.Aivika.Trans.Queue.Infinite.Base
(
FCFSQueue,
LCFSQueue,
SIROQueue,
PriorityQueue,
Queue,
newFCFSQueue,
newLCFSQueue,
newSIROQueue,
newPriorityQueue,
newQueue,
enqueueStoringStrategy,
dequeueStrategy,
queueNull,
queueCount,
dequeue,
dequeueWithOutputPriority,
tryDequeue,
enqueue,
enqueueWithStoringPriority,
queueDelete,
queueDelete_,
queueDeleteBy,
queueDeleteBy_,
queueContains,
queueContainsBy,
clearQueue) where
import Data.Monoid
import Data.Maybe
import Control.Monad
import Control.Monad.Trans
import Simulation.Aivika.Trans.Ref.Base
import Simulation.Aivika.Trans.DES
import Simulation.Aivika.Trans.Internal.Specs
import Simulation.Aivika.Trans.Internal.Parameter
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.Resource.Base
import Simulation.Aivika.Trans.QueueStrategy
type FCFSQueue m a = Queue m FCFS FCFS a
type LCFSQueue m a = Queue m LCFS FCFS a
type SIROQueue m a = Queue m SIRO FCFS a
type PriorityQueue m a = Queue m StaticPriorities FCFS a
data Queue m sm so a =
Queue { enqueueStoringStrategy :: sm,
dequeueStrategy :: so,
queueStore :: StrategyQueue m sm a,
dequeueRes :: Resource m so,
queueCountRef :: Ref m Int }
newFCFSQueue :: MonadDES m => Simulation m (FCFSQueue m a)
newFCFSQueue = newQueue FCFS FCFS
newLCFSQueue :: MonadDES m => Simulation m (LCFSQueue m a)
newLCFSQueue = newQueue LCFS FCFS
newSIROQueue :: (MonadDES m, QueueStrategy m SIRO) => Simulation m (SIROQueue m a)
newSIROQueue = newQueue SIRO FCFS
newPriorityQueue :: (MonadDES m, QueueStrategy m StaticPriorities) => Simulation m (PriorityQueue m a)
newPriorityQueue = newQueue StaticPriorities FCFS
newQueue :: (MonadDES m,
QueueStrategy m sm,
QueueStrategy m so) =>
sm
-> so
-> Simulation m (Queue m sm so a)
newQueue sm so =
do i <- newRef 0
qm <- newStrategyQueue sm
ro <- newResourceWithMaxCount so 0 Nothing
return Queue { enqueueStoringStrategy = sm,
dequeueStrategy = so,
queueStore = qm,
dequeueRes = ro,
queueCountRef = i }
queueNull :: MonadDES m => Queue m sm so a -> Event m Bool
queueNull q =
Event $ \p ->
do n <- invokeEvent p $ readRef (queueCountRef q)
return (n == 0)
queueCount :: MonadDES m => Queue m sm so a -> Event m Int
queueCount q =
Event $ \p -> invokeEvent p $ readRef (queueCountRef q)
dequeue :: (MonadDES m,
DequeueStrategy m sm,
EnqueueStrategy m so)
=> Queue m sm so a
-> Process m a
dequeue q =
do requestResource (dequeueRes q)
liftEvent $ dequeueExtract q
dequeueWithOutputPriority :: (MonadDES m,
DequeueStrategy m sm,
PriorityQueueStrategy m so po)
=> Queue m sm so a
-> po
-> Process m a
dequeueWithOutputPriority q po =
do requestResourceWithPriority (dequeueRes q) po
liftEvent $ dequeueExtract q
tryDequeue :: (MonadDES m,
DequeueStrategy m sm)
=> Queue m sm so a
-> Event m (Maybe a)
tryDequeue q =
do x <- tryRequestResourceWithinEvent (dequeueRes q)
if x
then fmap Just $ dequeueExtract q
else return Nothing
queueDelete :: (MonadDES m,
Eq a,
DeletingQueueStrategy m sm,
DequeueStrategy m so)
=> Queue m sm so a
-> a
-> Event m Bool
queueDelete q a = fmap isJust $ queueDeleteBy q (== a)
queueDelete_ :: (MonadDES m,
Eq a,
DeletingQueueStrategy m sm,
DequeueStrategy m so)
=> Queue m sm so a
-> a
-> Event m ()
queueDelete_ q a = fmap (const ()) $ queueDeleteBy q (== a)
queueDeleteBy :: (MonadDES m,
DeletingQueueStrategy m sm,
DequeueStrategy m so)
=> Queue m sm so a
-> (a -> Bool)
-> Event m (Maybe a)
queueDeleteBy q pred =
do x <- tryRequestResourceWithinEvent (dequeueRes q)
if x
then do i <- strategyQueueDeleteBy (queueStore q) pred
case i of
Nothing ->
do releaseResourceWithinEvent (dequeueRes q)
return Nothing
Just i ->
fmap Just $ dequeuePostExtract q i
else return Nothing
queueDeleteBy_ :: (MonadDES m,
DeletingQueueStrategy m sm,
DequeueStrategy m so)
=> Queue m sm so a
-> (a -> Bool)
-> Event m ()
queueDeleteBy_ q pred = fmap (const ()) $ queueDeleteBy q pred
queueContains :: (MonadDES m,
Eq a,
DeletingQueueStrategy m sm)
=> Queue m sm so a
-> a
-> Event m Bool
queueContains q a = fmap isJust $ queueContainsBy q (== a)
queueContainsBy :: (MonadDES m,
DeletingQueueStrategy m sm)
=> Queue m sm so a
-> (a -> Bool)
-> Event m (Maybe a)
queueContainsBy q pred =
strategyQueueContainsBy (queueStore q) pred
clearQueue :: (MonadDES m,
DequeueStrategy m sm)
=> Queue m sm so a
-> Event m ()
clearQueue q =
do x <- tryDequeue q
case x of
Nothing -> return ()
Just a -> clearQueue q
enqueue :: (MonadDES m,
EnqueueStrategy m sm,
DequeueStrategy m so)
=> Queue m sm so a
-> a
-> Event m ()
enqueue = enqueueStore
enqueueWithStoringPriority :: (MonadDES m,
PriorityQueueStrategy m sm pm,
DequeueStrategy m so)
=> Queue m sm so a
-> pm
-> a
-> Event m ()
enqueueWithStoringPriority = enqueueStoreWithPriority
enqueueStore :: (MonadDES m,
EnqueueStrategy m sm,
DequeueStrategy m so)
=> Queue m sm so a
-> a
-> Event m ()
enqueueStore q a =
Event $ \p ->
do invokeEvent p $
strategyEnqueue (queueStore q) a
c <- invokeEvent p $
readRef (queueCountRef q)
let c' = c + 1
c' `seq` invokeEvent p $
writeRef (queueCountRef q) c'
invokeEvent p $
releaseResourceWithinEvent (dequeueRes q)
enqueueStoreWithPriority :: (MonadDES m,
PriorityQueueStrategy m sm pm,
DequeueStrategy m so)
=> Queue m sm so a
-> pm
-> a
-> Event m ()
enqueueStoreWithPriority q pm a =
Event $ \p ->
do invokeEvent p $
strategyEnqueueWithPriority (queueStore q) pm a
c <- invokeEvent p $
readRef (queueCountRef q)
let c' = c + 1
c' `seq` invokeEvent p $
writeRef (queueCountRef q) c'
invokeEvent p $
releaseResourceWithinEvent (dequeueRes q)
dequeueExtract :: (MonadDES m,
DequeueStrategy m sm)
=> Queue m sm so a
-> Event m a
dequeueExtract q =
Event $ \p ->
do a <- invokeEvent p $
strategyDequeue (queueStore q)
invokeEvent p $
dequeuePostExtract q a
dequeuePostExtract :: (MonadDES m,
DequeueStrategy m sm)
=> Queue m sm so a
-> a
-> Event m a
dequeuePostExtract q a =
Event $ \p ->
do c <- invokeEvent p $
readRef (queueCountRef q)
let c' = c 1
c' `seq` invokeEvent p $
writeRef (queueCountRef q) c'
return a