module Simulation.Aivika.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.IORef
import Data.Monoid
import Data.Maybe
import Control.Monad
import Control.Monad.Trans
import Simulation.Aivika.Internal.Specs
import Simulation.Aivika.Internal.Simulation
import Simulation.Aivika.Internal.Dynamics
import Simulation.Aivika.Internal.Event
import Simulation.Aivika.Internal.Process
import Simulation.Aivika.Resource.Base
import Simulation.Aivika.QueueStrategy
import qualified Simulation.Aivika.DoubleLinkedList as DLL
import qualified Simulation.Aivika.Vector as V
import qualified Simulation.Aivika.PriorityQueue as PQ
type FCFSQueue a = Queue FCFS FCFS a
type LCFSQueue a = Queue LCFS FCFS a
type SIROQueue a = Queue SIRO FCFS a
type PriorityQueue a = Queue StaticPriorities FCFS a
data Queue sm so a =
Queue { forall sm so a. Queue sm so a -> sm
enqueueStoringStrategy :: sm,
forall sm so a. Queue sm so a -> so
dequeueStrategy :: so,
forall sm so a. Queue sm so a -> StrategyQueue sm a
queueStore :: StrategyQueue sm a,
forall sm so a. Queue sm so a -> Resource so
dequeueRes :: Resource so,
forall sm so a. Queue sm so a -> IORef Int
queueCountRef :: IORef Int }
newFCFSQueue :: Simulation (FCFSQueue a)
newFCFSQueue :: forall a. Simulation (FCFSQueue a)
newFCFSQueue = forall sm so a.
(QueueStrategy sm, QueueStrategy so) =>
sm -> so -> Simulation (Queue sm so a)
newQueue FCFS
FCFS FCFS
FCFS
newLCFSQueue :: Simulation (LCFSQueue a)
newLCFSQueue :: forall a. Simulation (LCFSQueue a)
newLCFSQueue = forall sm so a.
(QueueStrategy sm, QueueStrategy so) =>
sm -> so -> Simulation (Queue sm so a)
newQueue LCFS
LCFS FCFS
FCFS
newSIROQueue :: Simulation (SIROQueue a)
newSIROQueue :: forall a. Simulation (SIROQueue a)
newSIROQueue = forall sm so a.
(QueueStrategy sm, QueueStrategy so) =>
sm -> so -> Simulation (Queue sm so a)
newQueue SIRO
SIRO FCFS
FCFS
newPriorityQueue :: Simulation (PriorityQueue a)
newPriorityQueue :: forall a. Simulation (PriorityQueue a)
newPriorityQueue = forall sm so a.
(QueueStrategy sm, QueueStrategy so) =>
sm -> so -> Simulation (Queue sm so a)
newQueue StaticPriorities
StaticPriorities FCFS
FCFS
newQueue :: (QueueStrategy sm,
QueueStrategy so) =>
sm
-> so
-> Simulation (Queue sm so a)
newQueue :: forall sm so a.
(QueueStrategy sm, QueueStrategy so) =>
sm -> so -> Simulation (Queue sm so a)
newQueue sm
sm so
so =
do IORef Int
i <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. a -> IO (IORef a)
newIORef Int
0
StrategyQueue sm a
qm <- forall s i. QueueStrategy s => s -> Simulation (StrategyQueue s i)
newStrategyQueue sm
sm
Resource so
ro <- forall s.
QueueStrategy s =>
s -> Int -> Maybe Int -> Simulation (Resource s)
newResourceWithMaxCount so
so Int
0 forall a. Maybe a
Nothing
forall (m :: * -> *) a. Monad m => a -> m a
return Queue { enqueueStoringStrategy :: sm
enqueueStoringStrategy = sm
sm,
dequeueStrategy :: so
dequeueStrategy = so
so,
queueStore :: StrategyQueue sm a
queueStore = StrategyQueue sm a
qm,
dequeueRes :: Resource so
dequeueRes = Resource so
ro,
queueCountRef :: IORef Int
queueCountRef = IORef Int
i }
queueNull :: Queue sm so a -> Event Bool
queueNull :: forall sm so a. Queue sm so a -> Event Bool
queueNull Queue sm so a
q =
forall a. (Point -> IO a) -> Event a
Event forall a b. (a -> b) -> a -> b
$ \Point
p ->
do Int
n <- forall a. IORef a -> IO a
readIORef (forall sm so a. Queue sm so a -> IORef Int
queueCountRef Queue sm so a
q)
forall (m :: * -> *) a. Monad m => a -> m a
return (Int
n forall a. Eq a => a -> a -> Bool
== Int
0)
queueCount :: Queue sm so a -> Event Int
queueCount :: forall sm so a. Queue sm so a -> Event Int
queueCount Queue sm so a
q =
forall a. (Point -> IO a) -> Event a
Event forall a b. (a -> b) -> a -> b
$ \Point
p -> forall a. IORef a -> IO a
readIORef (forall sm so a. Queue sm so a -> IORef Int
queueCountRef Queue sm so a
q)
dequeue :: (DequeueStrategy sm,
EnqueueStrategy so)
=> Queue sm so a
-> Process a
dequeue :: forall sm so a.
(DequeueStrategy sm, EnqueueStrategy so) =>
Queue sm so a -> Process a
dequeue Queue sm so a
q =
do forall s. EnqueueStrategy s => Resource s -> Process ()
requestResource (forall sm so a. Queue sm so a -> Resource so
dequeueRes Queue sm so a
q)
forall (m :: * -> *) a. EventLift m => Event a -> m a
liftEvent forall a b. (a -> b) -> a -> b
$ forall sm so a. DequeueStrategy sm => Queue sm so a -> Event a
dequeueExtract Queue sm so a
q
dequeueWithOutputPriority :: (DequeueStrategy sm,
PriorityQueueStrategy so po)
=> Queue sm so a
-> po
-> Process a
dequeueWithOutputPriority :: forall sm so po a.
(DequeueStrategy sm, PriorityQueueStrategy so po) =>
Queue sm so a -> po -> Process a
dequeueWithOutputPriority Queue sm so a
q po
po =
do forall s p.
PriorityQueueStrategy s p =>
Resource s -> p -> Process ()
requestResourceWithPriority (forall sm so a. Queue sm so a -> Resource so
dequeueRes Queue sm so a
q) po
po
forall (m :: * -> *) a. EventLift m => Event a -> m a
liftEvent forall a b. (a -> b) -> a -> b
$ forall sm so a. DequeueStrategy sm => Queue sm so a -> Event a
dequeueExtract Queue sm so a
q
tryDequeue :: DequeueStrategy sm
=> Queue sm so a
-> Event (Maybe a)
tryDequeue :: forall sm so a.
DequeueStrategy sm =>
Queue sm so a -> Event (Maybe a)
tryDequeue Queue sm so a
q =
do Bool
x <- forall s. Resource s -> Event Bool
tryRequestResourceWithinEvent (forall sm so a. Queue sm so a -> Resource so
dequeueRes Queue sm so a
q)
if Bool
x
then forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall sm so a. DequeueStrategy sm => Queue sm so a -> Event a
dequeueExtract Queue sm so a
q
else forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
queueDelete :: (Eq a,
DeletingQueueStrategy sm,
DequeueStrategy so)
=> Queue sm so a
-> a
-> Event Bool
queueDelete :: forall a sm so.
(Eq a, DeletingQueueStrategy sm, DequeueStrategy so) =>
Queue sm so a -> a -> Event Bool
queueDelete Queue sm so a
q a
a = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Maybe a -> Bool
isJust forall a b. (a -> b) -> a -> b
$ forall sm so a.
(DeletingQueueStrategy sm, DequeueStrategy so) =>
Queue sm so a -> (a -> Bool) -> Event (Maybe a)
queueDeleteBy Queue sm so a
q (forall a. Eq a => a -> a -> Bool
== a
a)
queueDelete_ :: (Eq a,
DeletingQueueStrategy sm,
DequeueStrategy so)
=> Queue sm so a
-> a
-> Event ()
queueDelete_ :: forall a sm so.
(Eq a, DeletingQueueStrategy sm, DequeueStrategy so) =>
Queue sm so a -> a -> Event ()
queueDelete_ Queue sm so a
q a
a = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a b. a -> b -> a
const ()) forall a b. (a -> b) -> a -> b
$ forall sm so a.
(DeletingQueueStrategy sm, DequeueStrategy so) =>
Queue sm so a -> (a -> Bool) -> Event (Maybe a)
queueDeleteBy Queue sm so a
q (forall a. Eq a => a -> a -> Bool
== a
a)
queueDeleteBy :: (DeletingQueueStrategy sm,
DequeueStrategy so)
=> Queue sm so a
-> (a -> Bool)
-> Event (Maybe a)
queueDeleteBy :: forall sm so a.
(DeletingQueueStrategy sm, DequeueStrategy so) =>
Queue sm so a -> (a -> Bool) -> Event (Maybe a)
queueDeleteBy Queue sm so a
q a -> Bool
pred =
do Bool
x <- forall s. Resource s -> Event Bool
tryRequestResourceWithinEvent (forall sm so a. Queue sm so a -> Resource so
dequeueRes Queue sm so a
q)
if Bool
x
then do Maybe a
i <- forall s i.
DeletingQueueStrategy s =>
StrategyQueue s i -> (i -> Bool) -> Event (Maybe i)
strategyQueueDeleteBy (forall sm so a. Queue sm so a -> StrategyQueue sm a
queueStore Queue sm so a
q) a -> Bool
pred
case Maybe a
i of
Maybe a
Nothing ->
do forall s. DequeueStrategy s => Resource s -> Event ()
releaseResourceWithinEvent (forall sm so a. Queue sm so a -> Resource so
dequeueRes Queue sm so a
q)
forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
Just a
i ->
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall sm so a. DequeueStrategy sm => Queue sm so a -> a -> Event a
dequeuePostExtract Queue sm so a
q a
i
else forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
queueDeleteBy_ :: (DeletingQueueStrategy sm,
DequeueStrategy so)
=> Queue sm so a
-> (a -> Bool)
-> Event ()
queueDeleteBy_ :: forall sm so a.
(DeletingQueueStrategy sm, DequeueStrategy so) =>
Queue sm so a -> (a -> Bool) -> Event ()
queueDeleteBy_ Queue sm so a
q a -> Bool
pred = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a b. a -> b -> a
const ()) forall a b. (a -> b) -> a -> b
$ forall sm so a.
(DeletingQueueStrategy sm, DequeueStrategy so) =>
Queue sm so a -> (a -> Bool) -> Event (Maybe a)
queueDeleteBy Queue sm so a
q a -> Bool
pred
queueContains :: (Eq a,
DeletingQueueStrategy sm)
=> Queue sm so a
-> a
-> Event Bool
queueContains :: forall a sm so.
(Eq a, DeletingQueueStrategy sm) =>
Queue sm so a -> a -> Event Bool
queueContains Queue sm so a
q a
a = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Maybe a -> Bool
isJust forall a b. (a -> b) -> a -> b
$ forall sm so a.
DeletingQueueStrategy sm =>
Queue sm so a -> (a -> Bool) -> Event (Maybe a)
queueContainsBy Queue sm so a
q (forall a. Eq a => a -> a -> Bool
== a
a)
queueContainsBy :: DeletingQueueStrategy sm
=> Queue sm so a
-> (a -> Bool)
-> Event (Maybe a)
queueContainsBy :: forall sm so a.
DeletingQueueStrategy sm =>
Queue sm so a -> (a -> Bool) -> Event (Maybe a)
queueContainsBy Queue sm so a
q a -> Bool
pred =
forall s i.
DeletingQueueStrategy s =>
StrategyQueue s i -> (i -> Bool) -> Event (Maybe i)
strategyQueueContainsBy (forall sm so a. Queue sm so a -> StrategyQueue sm a
queueStore Queue sm so a
q) a -> Bool
pred
clearQueue :: DequeueStrategy sm
=> Queue sm so a
-> Event ()
clearQueue :: forall sm so a. DequeueStrategy sm => Queue sm so a -> Event ()
clearQueue Queue sm so a
q =
do Maybe a
x <- forall sm so a.
DequeueStrategy sm =>
Queue sm so a -> Event (Maybe a)
tryDequeue Queue sm so a
q
case Maybe a
x of
Maybe a
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
Just a
a -> forall sm so a. DequeueStrategy sm => Queue sm so a -> Event ()
clearQueue Queue sm so a
q
enqueue :: (EnqueueStrategy sm,
DequeueStrategy so)
=> Queue sm so a
-> a
-> Event ()
enqueue :: forall sm so a.
(EnqueueStrategy sm, DequeueStrategy so) =>
Queue sm so a -> a -> Event ()
enqueue = forall sm so a.
(EnqueueStrategy sm, DequeueStrategy so) =>
Queue sm so a -> a -> Event ()
enqueueStore
enqueueWithStoringPriority :: (PriorityQueueStrategy sm pm,
DequeueStrategy so)
=> Queue sm so a
-> pm
-> a
-> Event ()
enqueueWithStoringPriority :: forall sm pm so a.
(PriorityQueueStrategy sm pm, DequeueStrategy so) =>
Queue sm so a -> pm -> a -> Event ()
enqueueWithStoringPriority = forall sm pm so a.
(PriorityQueueStrategy sm pm, DequeueStrategy so) =>
Queue sm so a -> pm -> a -> Event ()
enqueueStoreWithPriority
enqueueStore :: (EnqueueStrategy sm,
DequeueStrategy so)
=> Queue sm so a
-> a
-> Event ()
enqueueStore :: forall sm so a.
(EnqueueStrategy sm, DequeueStrategy so) =>
Queue sm so a -> a -> Event ()
enqueueStore Queue sm so a
q a
a =
forall a. (Point -> IO a) -> Event a
Event forall a b. (a -> b) -> a -> b
$ \Point
p ->
do forall a. Point -> Event a -> IO a
invokeEvent Point
p forall a b. (a -> b) -> a -> b
$
forall s i. EnqueueStrategy s => StrategyQueue s i -> i -> Event ()
strategyEnqueue (forall sm so a. Queue sm so a -> StrategyQueue sm a
queueStore Queue sm so a
q) a
a
Int
c <- forall a. IORef a -> IO a
readIORef (forall sm so a. Queue sm so a -> IORef Int
queueCountRef Queue sm so a
q)
let c' :: Int
c' = Int
c forall a. Num a => a -> a -> a
+ Int
1
Int
c' seq :: forall a b. a -> b -> b
`seq` forall a. IORef a -> a -> IO ()
writeIORef (forall sm so a. Queue sm so a -> IORef Int
queueCountRef Queue sm so a
q) Int
c'
forall a. Point -> Event a -> IO a
invokeEvent Point
p forall a b. (a -> b) -> a -> b
$
forall s. DequeueStrategy s => Resource s -> Event ()
releaseResourceWithinEvent (forall sm so a. Queue sm so a -> Resource so
dequeueRes Queue sm so a
q)
enqueueStoreWithPriority :: (PriorityQueueStrategy sm pm,
DequeueStrategy so)
=> Queue sm so a
-> pm
-> a
-> Event ()
enqueueStoreWithPriority :: forall sm pm so a.
(PriorityQueueStrategy sm pm, DequeueStrategy so) =>
Queue sm so a -> pm -> a -> Event ()
enqueueStoreWithPriority Queue sm so a
q pm
pm a
a =
forall a. (Point -> IO a) -> Event a
Event forall a b. (a -> b) -> a -> b
$ \Point
p ->
do forall a. Point -> Event a -> IO a
invokeEvent Point
p forall a b. (a -> b) -> a -> b
$
forall s p i.
PriorityQueueStrategy s p =>
StrategyQueue s i -> p -> i -> Event ()
strategyEnqueueWithPriority (forall sm so a. Queue sm so a -> StrategyQueue sm a
queueStore Queue sm so a
q) pm
pm a
a
Int
c <- forall a. IORef a -> IO a
readIORef (forall sm so a. Queue sm so a -> IORef Int
queueCountRef Queue sm so a
q)
let c' :: Int
c' = Int
c forall a. Num a => a -> a -> a
+ Int
1
Int
c' seq :: forall a b. a -> b -> b
`seq` forall a. IORef a -> a -> IO ()
writeIORef (forall sm so a. Queue sm so a -> IORef Int
queueCountRef Queue sm so a
q) Int
c'
forall a. Point -> Event a -> IO a
invokeEvent Point
p forall a b. (a -> b) -> a -> b
$
forall s. DequeueStrategy s => Resource s -> Event ()
releaseResourceWithinEvent (forall sm so a. Queue sm so a -> Resource so
dequeueRes Queue sm so a
q)
dequeueExtract :: DequeueStrategy sm
=> Queue sm so a
-> Event a
Queue sm so a
q =
forall a. (Point -> IO a) -> Event a
Event forall a b. (a -> b) -> a -> b
$ \Point
p ->
do a
a <- forall a. Point -> Event a -> IO a
invokeEvent Point
p forall a b. (a -> b) -> a -> b
$
forall s i. DequeueStrategy s => StrategyQueue s i -> Event i
strategyDequeue (forall sm so a. Queue sm so a -> StrategyQueue sm a
queueStore Queue sm so a
q)
forall a. Point -> Event a -> IO a
invokeEvent Point
p forall a b. (a -> b) -> a -> b
$
forall sm so a. DequeueStrategy sm => Queue sm so a -> a -> Event a
dequeuePostExtract Queue sm so a
q a
a
dequeuePostExtract :: DequeueStrategy sm
=> Queue sm so a
-> a
-> Event a
Queue sm so a
q a
a =
forall a. (Point -> IO a) -> Event a
Event forall a b. (a -> b) -> a -> b
$ \Point
p ->
do Int
c <- forall a. IORef a -> IO a
readIORef (forall sm so a. Queue sm so a -> IORef Int
queueCountRef Queue sm so a
q)
let c' :: Int
c' = Int
c forall a. Num a => a -> a -> a
- Int
1
Int
c' seq :: forall a b. a -> b -> b
`seq` forall a. IORef a -> a -> IO ()
writeIORef (forall sm so a. Queue sm so a -> IORef Int
queueCountRef Queue sm so a
q) Int
c'
forall (m :: * -> *) a. Monad m => a -> m a
return a
a