module Simulation.Aivika.Trans.QueueStrategy where
import Control.Monad.Trans
import Simulation.Aivika.Trans.Comp
import Simulation.Aivika.Trans.Comp.Template
import Simulation.Aivika.Trans.Parameter
import Simulation.Aivika.Trans.Parameter.Random
import Simulation.Aivika.Trans.Simulation
import Simulation.Aivika.Trans.Event
import qualified Simulation.Aivika.Trans.DoubleLinkedList as LL
import qualified Simulation.Aivika.Trans.PriorityQueue as PQ
import qualified Simulation.Aivika.Trans.Vector as V
class MonadComp m => QueueStrategy m s where
data StrategyQueue m s :: * -> *
newStrategyQueue :: s
-> Simulation m (StrategyQueue m s a)
strategyQueueNull :: StrategyQueue m s a
-> Event m Bool
class QueueStrategy m s => DequeueStrategy m s where
strategyDequeue :: StrategyQueue m s a
-> Event m a
class DequeueStrategy m s => EnqueueStrategy m s where
strategyEnqueue :: StrategyQueue m s a
-> a
-> Event m ()
class DequeueStrategy m s => PriorityQueueStrategy m s p | s -> p where
strategyEnqueueWithPriority :: StrategyQueue m s a
-> p
-> a
-> Event m ()
data FCFS = FCFS deriving (Eq, Ord, Show)
data LCFS = LCFS deriving (Eq, Ord, Show)
data SIRO = SIRO deriving (Eq, Ord, Show)
data StaticPriorities = StaticPriorities deriving (Eq, Ord, Show)
instance MonadComp m => QueueStrategy m FCFS where
newtype StrategyQueue m FCFS a = FCFSQueue (LL.DoubleLinkedList m a)
newStrategyQueue s =
fmap FCFSQueue $
do session <- liftParameter simulationSession
liftComp $ LL.newList session
strategyQueueNull (FCFSQueue q) = liftComp $ LL.listNull q
instance QueueStrategy m FCFS => DequeueStrategy m FCFS where
strategyDequeue (FCFSQueue q) =
liftComp $
do i <- LL.listFirst q
LL.listRemoveFirst q
return i
instance DequeueStrategy m FCFS => EnqueueStrategy m FCFS where
strategyEnqueue (FCFSQueue q) i = liftComp $ LL.listAddLast q i
instance MonadComp m => QueueStrategy m LCFS where
newtype StrategyQueue m LCFS a = LCFSQueue (LL.DoubleLinkedList m a)
newStrategyQueue s =
fmap LCFSQueue $
do session <- liftParameter simulationSession
liftComp $ LL.newList session
strategyQueueNull (LCFSQueue q) = liftComp $ LL.listNull q
instance QueueStrategy m LCFS => DequeueStrategy m LCFS where
strategyDequeue (LCFSQueue q) =
liftComp $
do i <- LL.listFirst q
LL.listRemoveFirst q
return i
instance DequeueStrategy m LCFS => EnqueueStrategy m LCFS where
strategyEnqueue (LCFSQueue q) i = liftComp $ LL.listInsertFirst q i
instance MonadComp m => QueueStrategy m StaticPriorities where
newtype StrategyQueue m StaticPriorities a = StaticPriorityQueue (PQ.PriorityQueue m a)
newStrategyQueue s =
fmap StaticPriorityQueue $
do session <- liftParameter simulationSession
liftComp $ PQ.newQueue session
strategyQueueNull (StaticPriorityQueue q) = liftComp $ PQ.queueNull q
instance QueueStrategy m StaticPriorities => DequeueStrategy m StaticPriorities where
strategyDequeue (StaticPriorityQueue q) =
liftComp $
do (_, i) <- PQ.queueFront q
PQ.dequeue q
return i
instance DequeueStrategy m StaticPriorities => PriorityQueueStrategy m StaticPriorities Double where
strategyEnqueueWithPriority (StaticPriorityQueue q) p i = liftComp $ PQ.enqueue q p i
instance MonadComp m => QueueStrategy m SIRO where
newtype StrategyQueue m SIRO a = SIROQueue (V.Vector m a)
newStrategyQueue s =
fmap SIROQueue $
do session <- liftParameter simulationSession
liftComp $ V.newVector session
strategyQueueNull (SIROQueue q) =
liftComp $
do n <- V.vectorCount q
return (n == 0)
instance QueueStrategy m SIRO => DequeueStrategy m SIRO where
strategyDequeue (SIROQueue q) =
do n <- liftComp $ V.vectorCount q
i <- liftParameter $ randomUniformInt 0 (n 1)
x <- liftComp $ V.readVector q i
liftComp $ V.vectorDeleteAt q i
return x
instance DequeueStrategy m SIRO => EnqueueStrategy m SIRO where
strategyEnqueue (SIROQueue q) i = liftComp $ V.appendVector q i