{-# LANGUAGE CPP #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE Trustworthy #-}
{-# LANGUAGE UnboxedTuples #-}
module GHC.Event.PSQ
(
Elem(..)
, Key
, Prio
, PSQ
, size
, null
, lookup
, empty
, singleton
, unsafeInsertNew
, delete
, adjust
, toList
, findMin
, deleteMin
, minView
, atMost
) where
import GHC.Base hiding (empty)
import GHC.Event.Unique
import GHC.Word (Word64)
import GHC.Num (Num(..))
import GHC.Real (fromIntegral)
#include "MachDeps.h"
type Prio = Word64
type Nat = Word
type Key = Unique
type Mask = Int
type PSQ a = IntPSQ a
data Elem a = E
{ forall a. Elem a -> Key
key :: {-# UNPACK #-} !Key
, forall a. Elem a -> Prio
prio :: {-# UNPACK #-} !Prio
, forall a. Elem a -> a
value :: a
}
data IntPSQ v
= Bin {-# UNPACK #-} !Key {-# UNPACK #-} !Prio !v {-# UNPACK #-} !Mask !(IntPSQ v) !(IntPSQ v)
| Tip {-# UNPACK #-} !Key {-# UNPACK #-} !Prio !v
| Nil
(.&.) :: Nat -> Nat -> Nat
.&. :: Nat -> Nat -> Nat
(.&.) (W# Word#
w1) (W# Word#
w2) = Word# -> Nat
W# (Word#
w1 Word# -> Word# -> Word#
`and#` Word#
w2)
{-# INLINE (.&.) #-}
xor :: Nat -> Nat -> Nat
xor :: Nat -> Nat -> Nat
xor (W# Word#
w1) (W# Word#
w2) = Word# -> Nat
W# (Word#
w1 Word# -> Word# -> Word#
`xor#` Word#
w2)
{-# INLINE xor #-}
complement :: Nat -> Nat
complement :: Nat -> Nat
complement (W# Word#
w) = Word# -> Nat
W# (Word#
w Word# -> Word# -> Word#
`xor#` Word#
mb)
where
#if WORD_SIZE_IN_BITS == 32
mb = 0xFFFFFFFF##
#elif WORD_SIZE_IN_BITS == 64
mb :: Word#
mb = Word#
0xFFFFFFFFFFFFFFFF##
#else
#error Unhandled value for WORD_SIZE_IN_BITS
#endif
{-# INLINE complement #-}
{-# INLINE natFromInt #-}
natFromInt :: Int -> Nat
natFromInt :: Int -> Nat
natFromInt = forall a b. (Integral a, Num b) => a -> b
fromIntegral
{-# INLINE intFromNat #-}
intFromNat :: Nat -> Int
intFromNat :: Nat -> Int
intFromNat = forall a b. (Integral a, Num b) => a -> b
fromIntegral
{-# INLINE zero #-}
zero :: Key -> Mask -> Bool
zero :: Key -> Int -> Bool
zero Key
i Int
m
= (Int -> Nat
natFromInt (Key -> Int
asInt Key
i)) Nat -> Nat -> Nat
.&. (Int -> Nat
natFromInt Int
m) forall a. Eq a => a -> a -> Bool
== Nat
0
{-# INLINE nomatch #-}
nomatch :: Key -> Key -> Mask -> Bool
nomatch :: Key -> Key -> Int -> Bool
nomatch Key
k1 Key
k2 Int
m =
Int -> Nat
natFromInt (Key -> Int
asInt Key
k1) Nat -> Nat -> Nat
.&. Nat
m' forall a. Eq a => a -> a -> Bool
/= Int -> Nat
natFromInt (Key -> Int
asInt Key
k2) Nat -> Nat -> Nat
.&. Nat
m'
where
m' :: Nat
m' = Nat -> Nat
maskW (Int -> Nat
natFromInt Int
m)
{-# INLINE maskW #-}
maskW :: Nat -> Nat
maskW :: Nat -> Nat
maskW Nat
m = Nat -> Nat
complement (Nat
mforall a. Num a => a -> a -> a
-Nat
1) Nat -> Nat -> Nat
`xor` Nat
m
{-# INLINE branchMask #-}
branchMask :: Key -> Key -> Mask
branchMask :: Key -> Key -> Int
branchMask Key
k1' Key
k2' =
Nat -> Int
intFromNat (Nat -> Nat
highestBitMask (Int -> Nat
natFromInt Int
k1 Nat -> Nat -> Nat
`xor` Int -> Nat
natFromInt Int
k2))
where
k1 :: Int
k1 = Key -> Int
asInt Key
k1'
k2 :: Int
k2 = Key -> Int
asInt Key
k2'
highestBitMask :: Nat -> Nat
highestBitMask :: Nat -> Nat
highestBitMask (W# Word#
x) =
Word# -> Nat
W# (Word# -> Int# -> Word#
uncheckedShiftL# Word#
1## (Word# -> Int#
word2Int# (WORD_SIZE_IN_BITS## `minusWord#` 1## `minusWord#` clz# x)))
{-# INLINE highestBitMask #-}
null :: IntPSQ v -> Bool
null :: forall v. IntPSQ v -> Bool
null IntPSQ v
Nil = Bool
True
null IntPSQ v
_ = Bool
False
size :: IntPSQ v -> Int
size :: forall v. IntPSQ v -> Int
size IntPSQ v
Nil = Int
0
size (Tip Key
_ Prio
_ v
_) = Int
1
size (Bin Key
_ Prio
_ v
_ Int
_ IntPSQ v
l IntPSQ v
r) = Int
1 forall a. Num a => a -> a -> a
+ forall v. IntPSQ v -> Int
size IntPSQ v
l forall a. Num a => a -> a -> a
+ forall v. IntPSQ v -> Int
size IntPSQ v
r
lookup :: Key -> IntPSQ v -> Maybe (Prio, v)
lookup :: forall v. Key -> IntPSQ v -> Maybe (Prio, v)
lookup Key
k = forall {b}. IntPSQ b -> Maybe (Prio, b)
go
where
go :: IntPSQ b -> Maybe (Prio, b)
go IntPSQ b
t = case IntPSQ b
t of
IntPSQ b
Nil -> forall a. Maybe a
Nothing
Tip Key
k' Prio
p' b
x'
| Key
k forall a. Eq a => a -> a -> Bool
== Key
k' -> forall a. a -> Maybe a
Just (Prio
p', b
x')
| Bool
otherwise -> forall a. Maybe a
Nothing
Bin Key
k' Prio
p' b
x' Int
m IntPSQ b
l IntPSQ b
r
| Key -> Key -> Int -> Bool
nomatch Key
k Key
k' Int
m -> forall a. Maybe a
Nothing
| Key
k forall a. Eq a => a -> a -> Bool
== Key
k' -> forall a. a -> Maybe a
Just (Prio
p', b
x')
| Key -> Int -> Bool
zero Key
k Int
m -> IntPSQ b -> Maybe (Prio, b)
go IntPSQ b
l
| Bool
otherwise -> IntPSQ b -> Maybe (Prio, b)
go IntPSQ b
r
findMin :: IntPSQ v -> Maybe (Elem v)
findMin :: forall v. IntPSQ v -> Maybe (Elem v)
findMin IntPSQ v
t = case IntPSQ v
t of
IntPSQ v
Nil -> forall a. Maybe a
Nothing
Tip Key
k Prio
p v
x -> forall a. a -> Maybe a
Just (forall a. Key -> Prio -> a -> Elem a
E Key
k Prio
p v
x)
Bin Key
k Prio
p v
x Int
_ IntPSQ v
_ IntPSQ v
_ -> forall a. a -> Maybe a
Just (forall a. Key -> Prio -> a -> Elem a
E Key
k Prio
p v
x)
empty :: IntPSQ v
empty :: forall v. IntPSQ v
empty = forall v. IntPSQ v
Nil
singleton :: Key -> Prio -> v -> IntPSQ v
singleton :: forall v. Key -> Prio -> v -> IntPSQ v
singleton = forall v. Key -> Prio -> v -> IntPSQ v
Tip
{-# INLINABLE unsafeInsertNew #-}
unsafeInsertNew :: Key -> Prio -> v -> IntPSQ v -> IntPSQ v
unsafeInsertNew :: forall v. Key -> Prio -> v -> IntPSQ v -> IntPSQ v
unsafeInsertNew Key
k Prio
p v
x = IntPSQ v -> IntPSQ v
go
where
go :: IntPSQ v -> IntPSQ v
go IntPSQ v
t = case IntPSQ v
t of
IntPSQ v
Nil -> forall v. Key -> Prio -> v -> IntPSQ v
Tip Key
k Prio
p v
x
Tip Key
k' Prio
p' v
x'
| (Prio
p, Key
k) forall a. Ord a => a -> a -> Bool
< (Prio
p', Key
k') -> forall v.
Key -> Prio -> v -> Key -> IntPSQ v -> IntPSQ v -> IntPSQ v
link Key
k Prio
p v
x Key
k' IntPSQ v
t forall v. IntPSQ v
Nil
| Bool
otherwise -> forall v.
Key -> Prio -> v -> Key -> IntPSQ v -> IntPSQ v -> IntPSQ v
link Key
k' Prio
p' v
x' Key
k (forall v. Key -> Prio -> v -> IntPSQ v
Tip Key
k Prio
p v
x) forall v. IntPSQ v
Nil
Bin Key
k' Prio
p' v
x' Int
m IntPSQ v
l IntPSQ v
r
| Key -> Key -> Int -> Bool
nomatch Key
k Key
k' Int
m ->
if (Prio
p, Key
k) forall a. Ord a => a -> a -> Bool
< (Prio
p', Key
k')
then forall v.
Key -> Prio -> v -> Key -> IntPSQ v -> IntPSQ v -> IntPSQ v
link Key
k Prio
p v
x Key
k' IntPSQ v
t forall v. IntPSQ v
Nil
else forall v.
Key -> Prio -> v -> Key -> IntPSQ v -> IntPSQ v -> IntPSQ v
link Key
k' Prio
p' v
x' Key
k (forall v. Key -> Prio -> v -> IntPSQ v
Tip Key
k Prio
p v
x) (forall v. Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
merge Int
m IntPSQ v
l IntPSQ v
r)
| Bool
otherwise ->
if (Prio
p, Key
k) forall a. Ord a => a -> a -> Bool
< (Prio
p', Key
k')
then
if Key -> Int -> Bool
zero Key
k' Int
m
then forall v.
Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
Bin Key
k Prio
p v
x Int
m (forall v. Key -> Prio -> v -> IntPSQ v -> IntPSQ v
unsafeInsertNew Key
k' Prio
p' v
x' IntPSQ v
l) IntPSQ v
r
else forall v.
Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
Bin Key
k Prio
p v
x Int
m IntPSQ v
l (forall v. Key -> Prio -> v -> IntPSQ v -> IntPSQ v
unsafeInsertNew Key
k' Prio
p' v
x' IntPSQ v
r)
else
if Key -> Int -> Bool
zero Key
k Int
m
then forall v.
Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
Bin Key
k' Prio
p' v
x' Int
m (forall v. Key -> Prio -> v -> IntPSQ v -> IntPSQ v
unsafeInsertNew Key
k Prio
p v
x IntPSQ v
l) IntPSQ v
r
else forall v.
Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
Bin Key
k' Prio
p' v
x' Int
m IntPSQ v
l (forall v. Key -> Prio -> v -> IntPSQ v -> IntPSQ v
unsafeInsertNew Key
k Prio
p v
x IntPSQ v
r)
link :: Key -> Prio -> v -> Key -> IntPSQ v -> IntPSQ v -> IntPSQ v
link :: forall v.
Key -> Prio -> v -> Key -> IntPSQ v -> IntPSQ v -> IntPSQ v
link Key
k Prio
p v
x Key
k' IntPSQ v
k't IntPSQ v
otherTree
| Key -> Int -> Bool
zero (Int -> Key
Unique Int
m) (Key -> Int
asInt Key
k') = forall v.
Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
Bin Key
k Prio
p v
x Int
m IntPSQ v
k't IntPSQ v
otherTree
| Bool
otherwise = forall v.
Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
Bin Key
k Prio
p v
x Int
m IntPSQ v
otherTree IntPSQ v
k't
where
m :: Int
m = Key -> Key -> Int
branchMask Key
k Key
k'
{-# INLINABLE delete #-}
delete :: Key -> IntPSQ v -> IntPSQ v
delete :: forall v. Key -> IntPSQ v -> IntPSQ v
delete Key
k = forall {v}. IntPSQ v -> IntPSQ v
go
where
go :: IntPSQ v -> IntPSQ v
go IntPSQ v
t = case IntPSQ v
t of
IntPSQ v
Nil -> forall v. IntPSQ v
Nil
Tip Key
k' Prio
_ v
_
| Key
k forall a. Eq a => a -> a -> Bool
== Key
k' -> forall v. IntPSQ v
Nil
| Bool
otherwise -> IntPSQ v
t
Bin Key
k' Prio
p' v
x' Int
m IntPSQ v
l IntPSQ v
r
| Key -> Key -> Int -> Bool
nomatch Key
k Key
k' Int
m -> IntPSQ v
t
| Key
k forall a. Eq a => a -> a -> Bool
== Key
k' -> forall v. Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
merge Int
m IntPSQ v
l IntPSQ v
r
| Key -> Int -> Bool
zero Key
k Int
m -> forall v.
Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
binShrinkL Key
k' Prio
p' v
x' Int
m (IntPSQ v -> IntPSQ v
go IntPSQ v
l) IntPSQ v
r
| Bool
otherwise -> forall v.
Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
binShrinkR Key
k' Prio
p' v
x' Int
m IntPSQ v
l (IntPSQ v -> IntPSQ v
go IntPSQ v
r)
{-# INLINE deleteMin #-}
deleteMin :: IntPSQ v -> IntPSQ v
deleteMin :: forall {v}. IntPSQ v -> IntPSQ v
deleteMin IntPSQ v
t = case forall v. IntPSQ v -> Maybe (Elem v, IntPSQ v)
minView IntPSQ v
t of
Maybe (Elem v, IntPSQ v)
Nothing -> IntPSQ v
t
Just (Elem v
_, IntPSQ v
t') -> IntPSQ v
t'
adjust
:: (Prio -> Prio)
-> Key
-> PSQ a
-> PSQ a
adjust :: forall a. (Prio -> Prio) -> Key -> PSQ a -> PSQ a
adjust Prio -> Prio
f Key
k PSQ a
q = case forall v b.
(Maybe (Prio, v) -> (b, Maybe (Prio, v)))
-> Key -> IntPSQ v -> (b, IntPSQ v)
alter forall {b}. Maybe (Prio, b) -> ((), Maybe (Prio, b))
g Key
k PSQ a
q of (()
_, PSQ a
q') -> PSQ a
q'
where g :: Maybe (Prio, b) -> ((), Maybe (Prio, b))
g (Just (Prio
p, b
v)) = ((), forall a. a -> Maybe a
Just ((Prio -> Prio
f Prio
p), b
v))
g Maybe (Prio, b)
Nothing = ((), forall a. Maybe a
Nothing)
{-# INLINE adjust #-}
{-# INLINE alter #-}
alter
:: (Maybe (Prio, v) -> (b, Maybe (Prio, v)))
-> Key
-> IntPSQ v
-> (b, IntPSQ v)
alter :: forall v b.
(Maybe (Prio, v) -> (b, Maybe (Prio, v)))
-> Key -> IntPSQ v -> (b, IntPSQ v)
alter Maybe (Prio, v) -> (b, Maybe (Prio, v))
f = \Key
k IntPSQ v
t0 ->
let (IntPSQ v
t, Maybe (Prio, v)
mbX) = case forall v. Key -> IntPSQ v -> Maybe (Prio, v, IntPSQ v)
deleteView Key
k IntPSQ v
t0 of
Maybe (Prio, v, IntPSQ v)
Nothing -> (IntPSQ v
t0, forall a. Maybe a
Nothing)
Just (Prio
p, v
v, IntPSQ v
t0') -> (IntPSQ v
t0', forall a. a -> Maybe a
Just (Prio
p, v
v))
in case Maybe (Prio, v) -> (b, Maybe (Prio, v))
f Maybe (Prio, v)
mbX of
(b
b, Maybe (Prio, v)
mbX') ->
(b
b, forall {t} {t}. t -> (t -> t) -> Maybe t -> t
maybe IntPSQ v
t (\(Prio
p, v
v) -> forall v. Key -> Prio -> v -> IntPSQ v -> IntPSQ v
unsafeInsertNew Key
k Prio
p v
v IntPSQ v
t) Maybe (Prio, v)
mbX')
where
maybe :: t -> (t -> t) -> Maybe t -> t
maybe t
_ t -> t
g (Just t
x) = t -> t
g t
x
maybe t
def t -> t
_ Maybe t
Nothing = t
def
{-# INLINE binShrinkL #-}
binShrinkL :: Key -> Prio -> v -> Mask -> IntPSQ v -> IntPSQ v -> IntPSQ v
binShrinkL :: forall v.
Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
binShrinkL Key
k Prio
p v
x Int
m IntPSQ v
Nil IntPSQ v
r = case IntPSQ v
r of IntPSQ v
Nil -> forall v. Key -> Prio -> v -> IntPSQ v
Tip Key
k Prio
p v
x; IntPSQ v
_ -> forall v.
Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
Bin Key
k Prio
p v
x Int
m forall v. IntPSQ v
Nil IntPSQ v
r
binShrinkL Key
k Prio
p v
x Int
m IntPSQ v
l IntPSQ v
r = forall v.
Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
Bin Key
k Prio
p v
x Int
m IntPSQ v
l IntPSQ v
r
{-# INLINE binShrinkR #-}
binShrinkR :: Key -> Prio -> v -> Mask -> IntPSQ v -> IntPSQ v -> IntPSQ v
binShrinkR :: forall v.
Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
binShrinkR Key
k Prio
p v
x Int
m IntPSQ v
l IntPSQ v
Nil = case IntPSQ v
l of IntPSQ v
Nil -> forall v. Key -> Prio -> v -> IntPSQ v
Tip Key
k Prio
p v
x; IntPSQ v
_ -> forall v.
Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
Bin Key
k Prio
p v
x Int
m IntPSQ v
l forall v. IntPSQ v
Nil
binShrinkR Key
k Prio
p v
x Int
m IntPSQ v
l IntPSQ v
r = forall v.
Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
Bin Key
k Prio
p v
x Int
m IntPSQ v
l IntPSQ v
r
toList :: IntPSQ v -> [Elem v]
toList :: forall v. IntPSQ v -> [Elem v]
toList =
forall {a}. [Elem a] -> IntPSQ a -> [Elem a]
go []
where
go :: [Elem a] -> IntPSQ a -> [Elem a]
go [Elem a]
acc IntPSQ a
Nil = [Elem a]
acc
go [Elem a]
acc (Tip Key
k' Prio
p' a
x') = (forall a. Key -> Prio -> a -> Elem a
E Key
k' Prio
p' a
x') forall a. a -> [a] -> [a]
: [Elem a]
acc
go [Elem a]
acc (Bin Key
k' Prio
p' a
x' Int
_m IntPSQ a
l IntPSQ a
r) = (forall a. Key -> Prio -> a -> Elem a
E Key
k' Prio
p' a
x') forall a. a -> [a] -> [a]
: [Elem a] -> IntPSQ a -> [Elem a]
go ([Elem a] -> IntPSQ a -> [Elem a]
go [Elem a]
acc IntPSQ a
r) IntPSQ a
l
{-# INLINABLE deleteView #-}
deleteView :: Key -> IntPSQ v -> Maybe (Prio, v, IntPSQ v)
deleteView :: forall v. Key -> IntPSQ v -> Maybe (Prio, v, IntPSQ v)
deleteView Key
k IntPSQ v
t0 =
case forall {v}. IntPSQ v -> (# IntPSQ v, Maybe (Prio, v) #)
delFrom IntPSQ v
t0 of
(# IntPSQ v
_, Maybe (Prio, v)
Nothing #) -> forall a. Maybe a
Nothing
(# IntPSQ v
t, Just (Prio
p, v
x) #) -> forall a. a -> Maybe a
Just (Prio
p, v
x, IntPSQ v
t)
where
delFrom :: IntPSQ v -> (# IntPSQ v, Maybe (Prio, v) #)
delFrom IntPSQ v
t = case IntPSQ v
t of
IntPSQ v
Nil -> (# forall v. IntPSQ v
Nil, forall a. Maybe a
Nothing #)
Tip Key
k' Prio
p' v
x'
| Key
k forall a. Eq a => a -> a -> Bool
== Key
k' -> (# forall v. IntPSQ v
Nil, forall a. a -> Maybe a
Just (Prio
p', v
x') #)
| Bool
otherwise -> (# IntPSQ v
t, forall a. Maybe a
Nothing #)
Bin Key
k' Prio
p' v
x' Int
m IntPSQ v
l IntPSQ v
r
| Key -> Key -> Int -> Bool
nomatch Key
k Key
k' Int
m -> (# IntPSQ v
t, forall a. Maybe a
Nothing #)
| Key
k forall a. Eq a => a -> a -> Bool
== Key
k' -> let t' :: IntPSQ v
t' = forall v. Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
merge Int
m IntPSQ v
l IntPSQ v
r
in IntPSQ v
t' seq :: forall a b. a -> b -> b
`seq` (# IntPSQ v
t', forall a. a -> Maybe a
Just (Prio
p', v
x') #)
| Key -> Int -> Bool
zero Key
k Int
m -> case IntPSQ v -> (# IntPSQ v, Maybe (Prio, v) #)
delFrom IntPSQ v
l of
(# IntPSQ v
l', Maybe (Prio, v)
mbPX #) -> let t' :: IntPSQ v
t' = forall v.
Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
binShrinkL Key
k' Prio
p' v
x' Int
m IntPSQ v
l' IntPSQ v
r
in IntPSQ v
t' seq :: forall a b. a -> b -> b
`seq` (# IntPSQ v
t', Maybe (Prio, v)
mbPX #)
| Bool
otherwise -> case IntPSQ v -> (# IntPSQ v, Maybe (Prio, v) #)
delFrom IntPSQ v
r of
(# IntPSQ v
r', Maybe (Prio, v)
mbPX #) -> let t' :: IntPSQ v
t' = forall v.
Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
binShrinkR Key
k' Prio
p' v
x' Int
m IntPSQ v
l IntPSQ v
r'
in IntPSQ v
t' seq :: forall a b. a -> b -> b
`seq` (# IntPSQ v
t', Maybe (Prio, v)
mbPX #)
{-# INLINE minView #-}
minView :: IntPSQ v -> Maybe (Elem v, IntPSQ v)
minView :: forall v. IntPSQ v -> Maybe (Elem v, IntPSQ v)
minView IntPSQ v
t = case IntPSQ v
t of
IntPSQ v
Nil -> forall a. Maybe a
Nothing
Tip Key
k Prio
p v
x -> forall a. a -> Maybe a
Just (forall a. Key -> Prio -> a -> Elem a
E Key
k Prio
p v
x, forall v. IntPSQ v
Nil)
Bin Key
k Prio
p v
x Int
m IntPSQ v
l IntPSQ v
r -> forall a. a -> Maybe a
Just (forall a. Key -> Prio -> a -> Elem a
E Key
k Prio
p v
x, forall v. Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
merge Int
m IntPSQ v
l IntPSQ v
r)
{-# INLINABLE atMost #-}
atMost :: Prio -> IntPSQ v -> ([Elem v], IntPSQ v)
atMost :: forall v. Prio -> IntPSQ v -> ([Elem v], IntPSQ v)
atMost Prio
pt IntPSQ v
t0 = forall {a}. [Elem a] -> IntPSQ a -> ([Elem a], IntPSQ a)
go [] IntPSQ v
t0
where
go :: [Elem a] -> IntPSQ a -> ([Elem a], IntPSQ a)
go [Elem a]
acc IntPSQ a
t = case IntPSQ a
t of
IntPSQ a
Nil -> ([Elem a]
acc, IntPSQ a
t)
Tip Key
k Prio
p a
x
| Prio
p forall a. Ord a => a -> a -> Bool
> Prio
pt -> ([Elem a]
acc, IntPSQ a
t)
| Bool
otherwise -> ((forall a. Key -> Prio -> a -> Elem a
E Key
k Prio
p a
x) forall a. a -> [a] -> [a]
: [Elem a]
acc, forall v. IntPSQ v
Nil)
Bin Key
k Prio
p a
x Int
m IntPSQ a
l IntPSQ a
r
| Prio
p forall a. Ord a => a -> a -> Bool
> Prio
pt -> ([Elem a]
acc, IntPSQ a
t)
| Bool
otherwise ->
let ([Elem a]
acc', IntPSQ a
l') = [Elem a] -> IntPSQ a -> ([Elem a], IntPSQ a)
go [Elem a]
acc IntPSQ a
l
([Elem a]
acc'', IntPSQ a
r') = [Elem a] -> IntPSQ a -> ([Elem a], IntPSQ a)
go [Elem a]
acc' IntPSQ a
r
in ((forall a. Key -> Prio -> a -> Elem a
E Key
k Prio
p a
x) forall a. a -> [a] -> [a]
: [Elem a]
acc'', forall v. Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
merge Int
m IntPSQ a
l' IntPSQ a
r')
{-# INLINABLE merge #-}
merge :: Mask -> IntPSQ v -> IntPSQ v -> IntPSQ v
merge :: forall v. Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
merge Int
m IntPSQ v
l IntPSQ v
r = case IntPSQ v
l of
IntPSQ v
Nil -> IntPSQ v
r
Tip Key
lk Prio
lp v
lx ->
case IntPSQ v
r of
IntPSQ v
Nil -> IntPSQ v
l
Tip Key
rk Prio
rp v
rx
| (Prio
lp, Key
lk) forall a. Ord a => a -> a -> Bool
< (Prio
rp, Key
rk) -> forall v.
Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
Bin Key
lk Prio
lp v
lx Int
m forall v. IntPSQ v
Nil IntPSQ v
r
| Bool
otherwise -> forall v.
Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
Bin Key
rk Prio
rp v
rx Int
m IntPSQ v
l forall v. IntPSQ v
Nil
Bin Key
rk Prio
rp v
rx Int
rm IntPSQ v
rl IntPSQ v
rr
| (Prio
lp, Key
lk) forall a. Ord a => a -> a -> Bool
< (Prio
rp, Key
rk) -> forall v.
Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
Bin Key
lk Prio
lp v
lx Int
m forall v. IntPSQ v
Nil IntPSQ v
r
| Bool
otherwise -> forall v.
Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
Bin Key
rk Prio
rp v
rx Int
m IntPSQ v
l (forall v. Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
merge Int
rm IntPSQ v
rl IntPSQ v
rr)
Bin Key
lk Prio
lp v
lx Int
lm IntPSQ v
ll IntPSQ v
lr ->
case IntPSQ v
r of
IntPSQ v
Nil -> IntPSQ v
l
Tip Key
rk Prio
rp v
rx
| (Prio
lp, Key
lk) forall a. Ord a => a -> a -> Bool
< (Prio
rp, Key
rk) -> forall v.
Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
Bin Key
lk Prio
lp v
lx Int
m (forall v. Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
merge Int
lm IntPSQ v
ll IntPSQ v
lr) IntPSQ v
r
| Bool
otherwise -> forall v.
Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
Bin Key
rk Prio
rp v
rx Int
m IntPSQ v
l forall v. IntPSQ v
Nil
Bin Key
rk Prio
rp v
rx Int
rm IntPSQ v
rl IntPSQ v
rr
| (Prio
lp, Key
lk) forall a. Ord a => a -> a -> Bool
< (Prio
rp, Key
rk) -> forall v.
Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
Bin Key
lk Prio
lp v
lx Int
m (forall v. Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
merge Int
lm IntPSQ v
ll IntPSQ v
lr) IntPSQ v
r
| Bool
otherwise -> forall v.
Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
Bin Key
rk Prio
rp v
rx Int
m IntPSQ v
l (forall v. Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
merge Int
rm IntPSQ v
rl IntPSQ v
rr)