{-# LANGUAGE TypeApplications #-}
module Data.TimerWheel.Internal.Entries
( Entries,
empty,
Data.TimerWheel.Internal.Entries.null,
size,
insert,
delete,
partition,
)
where
import Data.Coerce
import Data.IntPSQ (IntPSQ)
import qualified Data.IntPSQ as IntPSQ
import Data.Word (Word64)
newtype Entries
= Entries (IntPSQ Word64 (IO ()))
empty :: Entries
empty =
Entries IntPSQ.empty
{-# INLINEABLE empty #-}
null :: Entries -> Bool
null =
coerce (IntPSQ.null @Word64 @(IO ()))
{-# INLINEABLE null #-}
size :: Entries -> Int
size =
coerce (IntPSQ.size @Word64 @(IO ()))
{-# INLINEABLE size #-}
insert :: Int -> Word64 -> IO () -> Entries -> Entries
insert i n m =
coerce (IntPSQ.unsafeInsertNew i n m)
{-# INLINEABLE insert #-}
delete :: Int -> Entries -> Maybe Entries
delete =
coerce delete_
{-# INLINEABLE delete #-}
delete_ :: Int -> IntPSQ Word64 (IO ()) -> Maybe (IntPSQ Word64 (IO ()))
delete_ i xs =
(\(_, _, ys) -> ys) <$> IntPSQ.deleteView i xs
partition :: Entries -> ([IO ()], Entries)
partition (Entries entries) =
case IntPSQ.atMostView 0 entries of
(expired, alive) ->
(map f expired, Entries (IntPSQ.unsafeMapMonotonic g alive))
where
f :: (Int, Word64, IO ()) -> IO ()
f (_, _, m) =
m
g :: Int -> Word64 -> IO () -> (Word64, IO ())
g _ n m =
(n -1, m)
{-# INLINEABLE partition #-}