module Hans.Time (
module Hans.Time,
H.Entry(..),
H.toUnsortedList,
) where
import qualified Data.Heap as H
import Data.Time.Clock (UTCTime,NominalDiffTime,diffUTCTime)
import Data.Tuple (swap)
type Expires = H.Entry UTCTime
expiresBefore :: UTCTime -> Expires a -> Bool
expiresBefore time entry = time >= H.priority entry
type ExpireHeap a = H.Heap (Expires a)
emptyHeap :: ExpireHeap a
emptyHeap = H.empty
fromListHeap :: [Expires a] -> ExpireHeap a
fromListHeap = H.fromList
filterHeap :: (a -> Bool) -> ExpireHeap a -> ExpireHeap a
filterHeap p = H.filter p'
where
p' H.Entry { .. } = p payload
partitionHeap :: (a -> Bool) -> ExpireHeap a -> (ExpireHeap a,ExpireHeap a)
partitionHeap p = H.partition p'
where
p' H.Entry { .. } = p payload
nextEvent :: ExpireHeap a -> Maybe UTCTime
nextEvent heap =
do (entry,_) <- H.viewMin heap
return (H.priority entry)
dropExpired :: UTCTime -> ExpireHeap a -> ExpireHeap a
dropExpired now heap = H.dropWhile (expiresBefore now) heap
partitionExpired :: UTCTime -> ExpireHeap a -> (ExpireHeap a, ExpireHeap a)
partitionExpired now heap = swap (H.break (expiresBefore now) heap)
expireAt :: UTCTime -> a -> ExpireHeap a -> (ExpireHeap a,UTCTime)
expireAt time a heap =
let heap' = H.insert H.Entry { H.priority = time, H.payload = a } heap
in (heap',H.priority (H.minimum heap'))
nullHeap :: ExpireHeap a -> Bool
nullHeap = H.null
expirationDelay :: UTCTime -> ExpireHeap a -> Maybe NominalDiffTime
expirationDelay now heap =
do (H.Entry { .. }, _) <- H.viewMin heap
return $! diffUTCTime priority now
toUSeconds :: NominalDiffTime -> Int
toUSeconds diff = max 0 (truncate (diff * 1000000))