{-# 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 = Int -> Nat
forall a b. (Integral a, Num b) => a -> b
fromIntegral
{-# INLINE intFromNat #-}
intFromNat :: Nat -> Int
intFromNat :: Nat -> Int
intFromNat = Nat -> Int
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) Nat -> Nat -> Bool
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' Nat -> Nat -> Bool
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
mNat -> Nat -> Nat
forall 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 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ IntPSQ v -> Int
forall v. IntPSQ v -> Int
size IntPSQ v
l Int -> Int -> Int
forall a. Num a => a -> a -> a
+ IntPSQ v -> Int
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 = IntPSQ v -> Maybe (Prio, v)
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                -> Maybe (Prio, b)
forall a. Maybe a
Nothing
        Tip Key
k' Prio
p' b
x'
          | Key
k Key -> Key -> Bool
forall a. Eq a => a -> a -> Bool
== Key
k'        -> (Prio, b) -> Maybe (Prio, b)
forall a. a -> Maybe a
Just (Prio
p', b
x')
          | Bool
otherwise      -> Maybe (Prio, b)
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 -> Maybe (Prio, b)
forall a. Maybe a
Nothing
          | Key
k Key -> Key -> Bool
forall a. Eq a => a -> a -> Bool
== Key
k'        -> (Prio, b) -> Maybe (Prio, b)
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             -> Maybe (Elem v)
forall a. Maybe a
Nothing
    Tip Key
k Prio
p v
x       -> Elem v -> Maybe (Elem v)
forall a. a -> Maybe a
Just (Key -> Prio -> v -> Elem v
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
_ -> Elem v -> Maybe (Elem v)
forall a. a -> Maybe a
Just (Key -> Prio -> v -> Elem v
forall a. Key -> Prio -> a -> Elem a
E Key
k Prio
p v
x)
empty :: IntPSQ v
empty :: forall v. IntPSQ v
empty = IntPSQ v
forall v. IntPSQ v
Nil
singleton :: Key -> Prio -> v -> IntPSQ v
singleton :: forall v. Key -> Prio -> v -> IntPSQ v
singleton = Key -> Prio -> v -> IntPSQ v
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       -> Key -> Prio -> v -> IntPSQ v
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) (Prio, Key) -> (Prio, Key) -> Bool
forall a. Ord a => a -> a -> Bool
< (Prio
p', Key
k') -> Key -> Prio -> v -> Key -> IntPSQ v -> IntPSQ v -> IntPSQ v
forall v.
Key -> Prio -> v -> Key -> IntPSQ v -> IntPSQ v -> IntPSQ v
link Key
k  Prio
p  v
x  Key
k' IntPSQ v
t           IntPSQ v
forall v. IntPSQ v
Nil
        | Bool
otherwise         -> Key -> Prio -> v -> Key -> IntPSQ v -> IntPSQ v -> IntPSQ v
forall v.
Key -> Prio -> v -> Key -> IntPSQ v -> IntPSQ v -> IntPSQ v
link Key
k' Prio
p' v
x' Key
k  (Key -> Prio -> v -> IntPSQ v
forall v. Key -> Prio -> v -> IntPSQ v
Tip Key
k Prio
p v
x) IntPSQ v
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) (Prio, Key) -> (Prio, Key) -> Bool
forall a. Ord a => a -> a -> Bool
< (Prio
p', Key
k')
              then Key -> Prio -> v -> Key -> IntPSQ v -> IntPSQ v -> IntPSQ v
forall v.
Key -> Prio -> v -> Key -> IntPSQ v -> IntPSQ v -> IntPSQ v
link Key
k  Prio
p  v
x  Key
k' IntPSQ v
t           IntPSQ v
forall v. IntPSQ v
Nil
              else Key -> Prio -> v -> Key -> IntPSQ v -> IntPSQ v -> IntPSQ v
forall v.
Key -> Prio -> v -> Key -> IntPSQ v -> IntPSQ v -> IntPSQ v
link Key
k' Prio
p' v
x' Key
k  (Key -> Prio -> v -> IntPSQ v
forall v. Key -> Prio -> v -> IntPSQ v
Tip Key
k Prio
p v
x) (Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
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) (Prio, Key) -> (Prio, Key) -> Bool
forall a. Ord a => a -> a -> Bool
< (Prio
p', Key
k')
              then
                if Key -> Int -> Bool
zero Key
k' Int
m
                  then Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
forall v.
Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
Bin Key
k  Prio
p  v
x  Int
m (Key -> Prio -> v -> IntPSQ v -> IntPSQ v
forall v. Key -> Prio -> v -> IntPSQ v -> IntPSQ v
unsafeInsertNew Key
k' Prio
p' v
x' IntPSQ v
l) IntPSQ v
r
                  else Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> 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 (Key -> Prio -> v -> IntPSQ v -> IntPSQ v
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 Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
forall v.
Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
Bin Key
k' Prio
p' v
x' Int
m (Key -> Prio -> v -> IntPSQ v -> IntPSQ v
forall v. Key -> Prio -> v -> IntPSQ v -> IntPSQ v
unsafeInsertNew Key
k  Prio
p  v
x  IntPSQ v
l) IntPSQ v
r
                  else Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> 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 (Key -> Prio -> v -> IntPSQ v -> IntPSQ v
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') = Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> 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
k't IntPSQ v
otherTree
  | Bool
otherwise                  = Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> 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
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 = IntPSQ v -> IntPSQ v
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           -> IntPSQ v
forall v. IntPSQ v
Nil
        Tip Key
k' Prio
_ v
_
          | Key
k Key -> Key -> Bool
forall a. Eq a => a -> a -> Bool
== Key
k'   -> IntPSQ v
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 Key -> Key -> Bool
forall a. Eq a => a -> a -> Bool
== Key
k'        -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
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       -> Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
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      -> Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
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 IntPSQ v -> Maybe (Elem v, IntPSQ v)
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 (Maybe (Prio, a) -> ((), Maybe (Prio, a)))
-> Key -> PSQ a -> ((), PSQ a)
forall v b.
(Maybe (Prio, v) -> (b, Maybe (Prio, v)))
-> Key -> IntPSQ v -> (b, IntPSQ v)
alter Maybe (Prio, a) -> ((), Maybe (Prio, a))
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)) = ((), (Prio, b) -> Maybe (Prio, b)
forall a. a -> Maybe a
Just ((Prio -> Prio
f Prio
p), b
v))
        g Maybe (Prio, b)
Nothing       = ((), Maybe (Prio, b)
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 Key -> IntPSQ v -> Maybe (Prio, v, IntPSQ v)
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, Maybe (Prio, v)
forall a. Maybe a
Nothing)
                            Just (Prio
p, v
v, IntPSQ v
t0') -> (IntPSQ v
t0', (Prio, v) -> Maybe (Prio, v)
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, IntPSQ v -> ((Prio, v) -> IntPSQ v) -> Maybe (Prio, v) -> IntPSQ v
forall {t} {t}. t -> (t -> t) -> Maybe t -> t
maybe IntPSQ v
t (\(Prio
p, v
v) -> Key -> Prio -> v -> IntPSQ v -> IntPSQ 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 -> Key -> Prio -> v -> IntPSQ v
forall v. Key -> Prio -> v -> IntPSQ v
Tip Key
k Prio
p v
x; IntPSQ v
_ -> Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> 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
forall v. IntPSQ v
Nil IntPSQ v
r
binShrinkL Key
k Prio
p v
x Int
m IntPSQ v
l   IntPSQ v
r = Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> 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 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 -> Key -> Prio -> v -> IntPSQ v
forall v. Key -> Prio -> v -> IntPSQ v
Tip Key
k Prio
p v
x; IntPSQ v
_ -> Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> 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 IntPSQ v
forall v. IntPSQ v
Nil
binShrinkR Key
k Prio
p v
x Int
m IntPSQ v
l IntPSQ v
r   = Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> 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 IntPSQ v
r
toList :: IntPSQ v -> [Elem v]
toList :: forall v. IntPSQ v -> [Elem v]
toList =
    [Elem v] -> IntPSQ v -> [Elem v]
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')        = (Key -> Prio -> a -> Elem a
forall a. Key -> Prio -> a -> Elem a
E Key
k' Prio
p' a
x') Elem a -> [Elem a] -> [Elem a]
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) = (Key -> Prio -> a -> Elem a
forall a. Key -> Prio -> a -> Elem a
E Key
k' Prio
p' a
x') Elem a -> [Elem a] -> [Elem a]
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 IntPSQ v -> (# IntPSQ v, Maybe (Prio, v) #)
forall {v}. IntPSQ v -> (# IntPSQ v, Maybe (Prio, v) #)
delFrom IntPSQ v
t0 of
      (# IntPSQ v
_, Maybe (Prio, v)
Nothing     #) -> Maybe (Prio, v, IntPSQ v)
forall a. Maybe a
Nothing
      (# IntPSQ v
t, Just (Prio
p, v
x) #) -> (Prio, v, IntPSQ v) -> Maybe (Prio, v, IntPSQ v)
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 -> (# IntPSQ v
forall v. IntPSQ v
Nil, Maybe (Prio, v)
forall a. Maybe a
Nothing #)
      Tip Key
k' Prio
p' v
x'
        | Key
k Key -> Key -> Bool
forall a. Eq a => a -> a -> Bool
== Key
k'   -> (# IntPSQ v
forall v. IntPSQ v
Nil, (Prio, v) -> Maybe (Prio, v)
forall a. a -> Maybe a
Just (Prio
p', v
x') #)
        | Bool
otherwise -> (# IntPSQ v
t,   Maybe (Prio, v)
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, Maybe (Prio, v)
forall a. Maybe a
Nothing #)
        | Key
k Key -> Key -> Bool
forall a. Eq a => a -> a -> Bool
== Key
k'   -> let t' :: IntPSQ v
t' = Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
forall v. Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
merge Int
m IntPSQ v
l IntPSQ v
r
                       in  IntPSQ v
t' IntPSQ v
-> (# IntPSQ v, Maybe (Prio, v) #)
-> (# IntPSQ v, Maybe (Prio, v) #)
forall a b. a -> b -> b
`seq` (# IntPSQ v
t', (Prio, v) -> Maybe (Prio, v)
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' = Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
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' IntPSQ v
-> (# IntPSQ v, Maybe (Prio, v) #)
-> (# IntPSQ v, Maybe (Prio, v) #)
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' = Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
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' IntPSQ v
-> (# IntPSQ v, Maybe (Prio, v) #)
-> (# IntPSQ v, Maybe (Prio, v) #)
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             -> Maybe (Elem v, IntPSQ v)
forall a. Maybe a
Nothing
    Tip Key
k Prio
p v
x       -> (Elem v, IntPSQ v) -> Maybe (Elem v, IntPSQ v)
forall a. a -> Maybe a
Just (Key -> Prio -> v -> Elem v
forall a. Key -> Prio -> a -> Elem a
E Key
k Prio
p v
x, IntPSQ v
forall v. IntPSQ v
Nil)
    Bin Key
k Prio
p v
x Int
m IntPSQ v
l IntPSQ v
r -> (Elem v, IntPSQ v) -> Maybe (Elem v, IntPSQ v)
forall a. a -> Maybe a
Just (Key -> Prio -> v -> Elem v
forall a. Key -> Prio -> a -> Elem a
E Key
k Prio
p v
x, Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
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 = [Elem v] -> IntPSQ v -> ([Elem v], IntPSQ v)
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 Prio -> Prio -> Bool
forall a. Ord a => a -> a -> Bool
> Prio
pt    -> ([Elem a]
acc, IntPSQ a
t)
            | Bool
otherwise -> ((Key -> Prio -> a -> Elem a
forall a. Key -> Prio -> a -> Elem a
E Key
k Prio
p a
x) Elem a -> [Elem a] -> [Elem a]
forall a. a -> [a] -> [a]
: [Elem a]
acc, IntPSQ a
forall v. IntPSQ v
Nil)
        Bin Key
k Prio
p a
x Int
m IntPSQ a
l IntPSQ a
r
            | Prio
p Prio -> Prio -> Bool
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  ((Key -> Prio -> a -> Elem a
forall a. Key -> Prio -> a -> Elem a
E Key
k Prio
p a
x) Elem a -> [Elem a] -> [Elem a]
forall a. a -> [a] -> [a]
: [Elem a]
acc'', Int -> IntPSQ a -> IntPSQ a -> IntPSQ a
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) (Prio, Key) -> (Prio, Key) -> Bool
forall a. Ord a => a -> a -> Bool
< (Prio
rp, Key
rk) -> Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
forall v.
Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
Bin Key
lk Prio
lp v
lx Int
m IntPSQ v
forall v. IntPSQ v
Nil IntPSQ v
r
          | Bool
otherwise           -> Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
forall v.
Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
Bin Key
rk Prio
rp v
rx Int
m IntPSQ v
l   IntPSQ v
forall v. IntPSQ v
Nil
        Bin Key
rk Prio
rp v
rx Int
rm IntPSQ v
rl IntPSQ v
rr
          | (Prio
lp, Key
lk) (Prio, Key) -> (Prio, Key) -> Bool
forall a. Ord a => a -> a -> Bool
< (Prio
rp, Key
rk) -> Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
forall v.
Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
Bin Key
lk Prio
lp v
lx Int
m IntPSQ v
forall v. IntPSQ v
Nil IntPSQ v
r
          | Bool
otherwise           -> Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
forall v.
Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
Bin Key
rk Prio
rp v
rx Int
m IntPSQ v
l   (Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
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) (Prio, Key) -> (Prio, Key) -> Bool
forall a. Ord a => a -> a -> Bool
< (Prio
rp, Key
rk) -> Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
forall v.
Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
Bin Key
lk Prio
lp v
lx Int
m (Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
forall v. Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
merge Int
lm IntPSQ v
ll IntPSQ v
lr) IntPSQ v
r
          | Bool
otherwise           -> Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
forall v.
Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
Bin Key
rk Prio
rp v
rx Int
m IntPSQ v
l                IntPSQ v
forall v. IntPSQ v
Nil
        Bin Key
rk Prio
rp v
rx Int
rm IntPSQ v
rl IntPSQ v
rr
          | (Prio
lp, Key
lk) (Prio, Key) -> (Prio, Key) -> Bool
forall a. Ord a => a -> a -> Bool
< (Prio
rp, Key
rk) -> Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
forall v.
Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
Bin Key
lk Prio
lp v
lx Int
m (Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
forall v. Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
merge Int
lm IntPSQ v
ll IntPSQ v
lr) IntPSQ v
r
          | Bool
otherwise           -> Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
forall v.
Key -> Prio -> v -> Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
Bin Key
rk Prio
rp v
rx Int
m IntPSQ v
l                (Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
forall v. Int -> IntPSQ v -> IntPSQ v -> IntPSQ v
merge Int
rm IntPSQ v
rl IntPSQ v
rr)