{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
module Data.Vector.Algorithms.Heap
(
sort
, sortUniq
, sortBy
, sortUniqBy
, sortByBounds
, select
, selectBy
, selectByBounds
, partialSort
, partialSortBy
, partialSortByBounds
, heapify
, pop
, popTo
, sortHeap
, heapInsert
, Comparison
) where
import Prelude hiding (read, length)
import Control.Monad
import Control.Monad.Primitive
import Data.Bits
import Data.Vector.Generic.Mutable
import Data.Vector.Algorithms.Common (Comparison, uniqueMutableBy)
import qualified Data.Vector.Algorithms.Optimal as O
sort :: (PrimMonad m, MVector v e, Ord e) => v (PrimState m) e -> m ()
sort :: v (PrimState m) e -> m ()
sort = Comparison e -> v (PrimState m) e -> m ()
forall (m :: * -> *) (v :: * -> * -> *) e.
(PrimMonad m, MVector v e) =>
Comparison e -> v (PrimState m) e -> m ()
sortBy Comparison e
forall a. Ord a => a -> a -> Ordering
compare
{-# INLINABLE sort #-}
sortUniq :: (PrimMonad m, MVector v e, Ord e) => v (PrimState m) e -> m (v (PrimState m) e)
sortUniq :: v (PrimState m) e -> m (v (PrimState m) e)
sortUniq = Comparison e -> v (PrimState m) e -> m (v (PrimState m) e)
forall (m :: * -> *) (v :: * -> * -> *) e.
(PrimMonad m, MVector v e) =>
Comparison e -> v (PrimState m) e -> m (v (PrimState m) e)
sortUniqBy Comparison e
forall a. Ord a => a -> a -> Ordering
compare
{-# INLINABLE sortUniq #-}
sortBy :: (PrimMonad m, MVector v e) => Comparison e -> v (PrimState m) e -> m ()
sortBy :: Comparison e -> v (PrimState m) e -> m ()
sortBy Comparison e
cmp v (PrimState m) e
a = Comparison e -> v (PrimState m) e -> Int -> Int -> m ()
forall (m :: * -> *) (v :: * -> * -> *) e.
(PrimMonad m, MVector v e) =>
Comparison e -> v (PrimState m) e -> Int -> Int -> m ()
sortByBounds Comparison e
cmp v (PrimState m) e
a Int
0 (v (PrimState m) e -> Int
forall (v :: * -> * -> *) a s. MVector v a => v s a -> Int
length v (PrimState m) e
a)
{-# INLINE sortBy #-}
sortUniqBy :: (PrimMonad m, MVector v e)
=> Comparison e -> v (PrimState m) e -> m (v (PrimState m) e)
sortUniqBy :: Comparison e -> v (PrimState m) e -> m (v (PrimState m) e)
sortUniqBy Comparison e
cmp v (PrimState m) e
a = do
Comparison e -> v (PrimState m) e -> Int -> Int -> m ()
forall (m :: * -> *) (v :: * -> * -> *) e.
(PrimMonad m, MVector v e) =>
Comparison e -> v (PrimState m) e -> Int -> Int -> m ()
sortByBounds Comparison e
cmp v (PrimState m) e
a Int
0 (v (PrimState m) e -> Int
forall (v :: * -> * -> *) a s. MVector v a => v s a -> Int
length v (PrimState m) e
a)
Comparison e -> v (PrimState m) e -> m (v (PrimState m) e)
forall (m :: * -> *) (v :: * -> * -> *) e.
(PrimMonad m, MVector v e) =>
Comparison e -> v (PrimState m) e -> m (v (PrimState m) e)
uniqueMutableBy Comparison e
cmp v (PrimState m) e
a
{-# INLINE sortUniqBy #-}
sortByBounds
:: (PrimMonad m, MVector v e)
=> Comparison e
-> v (PrimState m) e
-> Int
-> Int
-> m ()
sortByBounds :: Comparison e -> v (PrimState m) e -> Int -> Int -> m ()
sortByBounds Comparison e
cmp v (PrimState m) e
a Int
l Int
u
| Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
2 = () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Int
len Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
2 = Comparison e -> v (PrimState m) e -> Int -> m ()
forall (m :: * -> *) (v :: * -> * -> *) e.
(PrimMonad m, MVector v e) =>
Comparison e -> v (PrimState m) e -> Int -> m ()
O.sort2ByOffset Comparison e
cmp v (PrimState m) e
a Int
l
| Int
len Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
3 = Comparison e -> v (PrimState m) e -> Int -> m ()
forall (m :: * -> *) (v :: * -> * -> *) e.
(PrimMonad m, MVector v e) =>
Comparison e -> v (PrimState m) e -> Int -> m ()
O.sort3ByOffset Comparison e
cmp v (PrimState m) e
a Int
l
| Int
len Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
4 = Comparison e -> v (PrimState m) e -> Int -> m ()
forall (m :: * -> *) (v :: * -> * -> *) e.
(PrimMonad m, MVector v e) =>
Comparison e -> v (PrimState m) e -> Int -> m ()
O.sort4ByOffset Comparison e
cmp v (PrimState m) e
a Int
l
| Bool
otherwise = Comparison e -> v (PrimState m) e -> Int -> Int -> m ()
forall (m :: * -> *) (v :: * -> * -> *) e.
(PrimMonad m, MVector v e) =>
Comparison e -> v (PrimState m) e -> Int -> Int -> m ()
heapify Comparison e
cmp v (PrimState m) e
a Int
l Int
u m () -> m () -> m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Comparison e -> v (PrimState m) e -> Int -> Int -> Int -> m ()
forall (m :: * -> *) (v :: * -> * -> *) e.
(PrimMonad m, MVector v e) =>
Comparison e -> v (PrimState m) e -> Int -> Int -> Int -> m ()
sortHeap Comparison e
cmp v (PrimState m) e
a Int
l (Int
lInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
4) Int
u m () -> m () -> m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Comparison e -> v (PrimState m) e -> Int -> m ()
forall (m :: * -> *) (v :: * -> * -> *) e.
(PrimMonad m, MVector v e) =>
Comparison e -> v (PrimState m) e -> Int -> m ()
O.sort4ByOffset Comparison e
cmp v (PrimState m) e
a Int
l
where len :: Int
len = Int
u Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
l
{-# INLINE sortByBounds #-}
select
:: (PrimMonad m, MVector v e, Ord e)
=> v (PrimState m) e
-> Int
-> m ()
select :: v (PrimState m) e -> Int -> m ()
select = Comparison e -> v (PrimState m) e -> Int -> m ()
forall (m :: * -> *) (v :: * -> * -> *) e.
(PrimMonad m, MVector v e) =>
Comparison e -> v (PrimState m) e -> Int -> m ()
selectBy Comparison e
forall a. Ord a => a -> a -> Ordering
compare
{-# INLINE select #-}
selectBy
:: (PrimMonad m, MVector v e)
=> Comparison e
-> v (PrimState m) e
-> Int
-> m ()
selectBy :: Comparison e -> v (PrimState m) e -> Int -> m ()
selectBy Comparison e
cmp v (PrimState m) e
a Int
k = Comparison e -> v (PrimState m) e -> Int -> Int -> Int -> m ()
forall (m :: * -> *) (v :: * -> * -> *) e.
(PrimMonad m, MVector v e) =>
Comparison e -> v (PrimState m) e -> Int -> Int -> Int -> m ()
selectByBounds Comparison e
cmp v (PrimState m) e
a Int
k Int
0 (v (PrimState m) e -> Int
forall (v :: * -> * -> *) a s. MVector v a => v s a -> Int
length v (PrimState m) e
a)
{-# INLINE selectBy #-}
selectByBounds
:: (PrimMonad m, MVector v e)
=> Comparison e
-> v (PrimState m) e
-> Int
-> Int
-> Int
-> m ()
selectByBounds :: Comparison e -> v (PrimState m) e -> Int -> Int -> Int -> m ()
selectByBounds Comparison e
cmp v (PrimState m) e
a Int
k Int
l Int
u
| Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
k Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
u = Comparison e -> v (PrimState m) e -> Int -> Int -> m ()
forall (m :: * -> *) (v :: * -> * -> *) e.
(PrimMonad m, MVector v e) =>
Comparison e -> v (PrimState m) e -> Int -> Int -> m ()
heapify Comparison e
cmp v (PrimState m) e
a Int
l (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
k) m () -> m () -> m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Int -> Int -> Int -> m ()
go Int
l (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
k) (Int
u Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
| Bool
otherwise = () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
where
go :: Int -> Int -> Int -> m ()
go Int
l Int
m Int
u
| Int
u Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
m = () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Bool
otherwise = do e
el <- v (PrimState m) e -> Int -> m e
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
unsafeRead v (PrimState m) e
a Int
l
e
eu <- v (PrimState m) e -> Int -> m e
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
unsafeRead v (PrimState m) e
a Int
u
case Comparison e
cmp e
eu e
el of
Ordering
LT -> Comparison e -> v (PrimState m) e -> Int -> Int -> Int -> m ()
forall (m :: * -> *) (v :: * -> * -> *) e.
(PrimMonad m, MVector v e) =>
Comparison e -> v (PrimState m) e -> Int -> Int -> Int -> m ()
popTo Comparison e
cmp v (PrimState m) e
a Int
l Int
m Int
u
Ordering
_ -> () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Int -> Int -> Int -> m ()
go Int
l Int
m (Int
u Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
{-# INLINE selectByBounds #-}
partialSort
:: (PrimMonad m, MVector v e, Ord e)
=> v (PrimState m) e
-> Int
-> m ()
partialSort :: v (PrimState m) e -> Int -> m ()
partialSort = Comparison e -> v (PrimState m) e -> Int -> m ()
forall (m :: * -> *) (v :: * -> * -> *) e.
(PrimMonad m, MVector v e) =>
Comparison e -> v (PrimState m) e -> Int -> m ()
partialSortBy Comparison e
forall a. Ord a => a -> a -> Ordering
compare
{-# INLINE partialSort #-}
partialSortBy
:: (PrimMonad m, MVector v e)
=> Comparison e
-> v (PrimState m) e
-> Int
-> m ()
partialSortBy :: Comparison e -> v (PrimState m) e -> Int -> m ()
partialSortBy Comparison e
cmp v (PrimState m) e
a Int
k = Comparison e -> v (PrimState m) e -> Int -> Int -> Int -> m ()
forall (m :: * -> *) (v :: * -> * -> *) e.
(PrimMonad m, MVector v e) =>
Comparison e -> v (PrimState m) e -> Int -> Int -> Int -> m ()
partialSortByBounds Comparison e
cmp v (PrimState m) e
a Int
k Int
0 (v (PrimState m) e -> Int
forall (v :: * -> * -> *) a s. MVector v a => v s a -> Int
length v (PrimState m) e
a)
{-# INLINE partialSortBy #-}
partialSortByBounds
:: (PrimMonad m, MVector v e)
=> Comparison e
-> v (PrimState m) e
-> Int
-> Int
-> Int
-> m ()
partialSortByBounds :: Comparison e -> v (PrimState m) e -> Int -> Int -> Int -> m ()
partialSortByBounds Comparison e
cmp v (PrimState m) e
a Int
k Int
l Int
u
| Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
2 = () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Int
len Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
2 = Comparison e -> v (PrimState m) e -> Int -> m ()
forall (m :: * -> *) (v :: * -> * -> *) e.
(PrimMonad m, MVector v e) =>
Comparison e -> v (PrimState m) e -> Int -> m ()
O.sort2ByOffset Comparison e
cmp v (PrimState m) e
a Int
l
| Int
len Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
3 = Comparison e -> v (PrimState m) e -> Int -> m ()
forall (m :: * -> *) (v :: * -> * -> *) e.
(PrimMonad m, MVector v e) =>
Comparison e -> v (PrimState m) e -> Int -> m ()
O.sort3ByOffset Comparison e
cmp v (PrimState m) e
a Int
l
| Int
len Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
4 = Comparison e -> v (PrimState m) e -> Int -> m ()
forall (m :: * -> *) (v :: * -> * -> *) e.
(PrimMonad m, MVector v e) =>
Comparison e -> v (PrimState m) e -> Int -> m ()
O.sort4ByOffset Comparison e
cmp v (PrimState m) e
a Int
l
| Int
u Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
k = Comparison e -> v (PrimState m) e -> Int -> Int -> m ()
forall (m :: * -> *) (v :: * -> * -> *) e.
(PrimMonad m, MVector v e) =>
Comparison e -> v (PrimState m) e -> Int -> Int -> m ()
sortByBounds Comparison e
cmp v (PrimState m) e
a Int
l Int
u
| Bool
otherwise = do Comparison e -> v (PrimState m) e -> Int -> Int -> Int -> m ()
forall (m :: * -> *) (v :: * -> * -> *) e.
(PrimMonad m, MVector v e) =>
Comparison e -> v (PrimState m) e -> Int -> Int -> Int -> m ()
selectByBounds Comparison e
cmp v (PrimState m) e
a Int
k Int
l Int
u
Comparison e -> v (PrimState m) e -> Int -> Int -> Int -> m ()
forall (m :: * -> *) (v :: * -> * -> *) e.
(PrimMonad m, MVector v e) =>
Comparison e -> v (PrimState m) e -> Int -> Int -> Int -> m ()
sortHeap Comparison e
cmp v (PrimState m) e
a Int
l (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
4) (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
k)
Comparison e -> v (PrimState m) e -> Int -> m ()
forall (m :: * -> *) (v :: * -> * -> *) e.
(PrimMonad m, MVector v e) =>
Comparison e -> v (PrimState m) e -> Int -> m ()
O.sort4ByOffset Comparison e
cmp v (PrimState m) e
a Int
l
where
len :: Int
len = Int
u Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
l
{-# INLINE partialSortByBounds #-}
heapify
:: (PrimMonad m, MVector v e)
=> Comparison e
-> v (PrimState m) e
-> Int
-> Int
-> m ()
heapify :: Comparison e -> v (PrimState m) e -> Int -> Int -> m ()
heapify Comparison e
cmp v (PrimState m) e
a Int
l Int
u = Int -> m ()
loop (Int -> m ()) -> Int -> m ()
forall a b. (a -> b) -> a -> b
$ (Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftR` Int
2
where
len :: Int
len = Int
u Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
l
loop :: Int -> m ()
loop Int
k
| Int
k Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Bool
otherwise = v (PrimState m) e -> Int -> m e
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
unsafeRead v (PrimState m) e
a (Int
lInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
k) m e -> (e -> m ()) -> m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \e
e ->
Comparison e -> v (PrimState m) e -> e -> Int -> Int -> Int -> m ()
forall (m :: * -> *) (v :: * -> * -> *) e.
(PrimMonad m, MVector v e) =>
Comparison e -> v (PrimState m) e -> e -> Int -> Int -> Int -> m ()
siftByOffset Comparison e
cmp v (PrimState m) e
a e
e Int
l Int
k Int
len m () -> m () -> m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Int -> m ()
loop (Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
{-# INLINE heapify #-}
pop
:: (PrimMonad m, MVector v e)
=> Comparison e
-> v (PrimState m) e
-> Int
-> Int
-> m ()
pop :: Comparison e -> v (PrimState m) e -> Int -> Int -> m ()
pop Comparison e
cmp v (PrimState m) e
a Int
l Int
u = Comparison e -> v (PrimState m) e -> Int -> Int -> Int -> m ()
forall (m :: * -> *) (v :: * -> * -> *) e.
(PrimMonad m, MVector v e) =>
Comparison e -> v (PrimState m) e -> Int -> Int -> Int -> m ()
popTo Comparison e
cmp v (PrimState m) e
a Int
l Int
u Int
u
{-# INLINE pop #-}
popTo
:: (PrimMonad m, MVector v e)
=> Comparison e
-> v (PrimState m) e
-> Int
-> Int
-> Int
-> m ()
popTo :: Comparison e -> v (PrimState m) e -> Int -> Int -> Int -> m ()
popTo Comparison e
cmp v (PrimState m) e
a Int
l Int
u Int
t = do e
al <- v (PrimState m) e -> Int -> m e
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
unsafeRead v (PrimState m) e
a Int
l
e
at <- v (PrimState m) e -> Int -> m e
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
unsafeRead v (PrimState m) e
a Int
t
v (PrimState m) e -> Int -> e -> m ()
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> a -> m ()
unsafeWrite v (PrimState m) e
a Int
t e
al
Comparison e -> v (PrimState m) e -> e -> Int -> Int -> Int -> m ()
forall (m :: * -> *) (v :: * -> * -> *) e.
(PrimMonad m, MVector v e) =>
Comparison e -> v (PrimState m) e -> e -> Int -> Int -> Int -> m ()
siftByOffset Comparison e
cmp v (PrimState m) e
a e
at Int
l Int
0 (Int
u Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
l)
{-# INLINE popTo #-}
sortHeap
:: (PrimMonad m, MVector v e)
=> Comparison e
-> v (PrimState m) e
-> Int
-> Int
-> Int
-> m ()
sortHeap :: Comparison e -> v (PrimState m) e -> Int -> Int -> Int -> m ()
sortHeap Comparison e
cmp v (PrimState m) e
a Int
l Int
m Int
u = Int -> m ()
loop (Int
uInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) m () -> m () -> m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> v (PrimState m) e -> Int -> Int -> m ()
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> Int -> m ()
unsafeSwap v (PrimState m) e
a Int
l Int
m
where
loop :: Int -> m ()
loop Int
k
| Int
m Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
k = Comparison e -> v (PrimState m) e -> Int -> Int -> m ()
forall (m :: * -> *) (v :: * -> * -> *) e.
(PrimMonad m, MVector v e) =>
Comparison e -> v (PrimState m) e -> Int -> Int -> m ()
pop Comparison e
cmp v (PrimState m) e
a Int
l Int
k m () -> m () -> m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Int -> m ()
loop (Int
kInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)
| Bool
otherwise = () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
{-# INLINE sortHeap #-}
heapInsert
:: (PrimMonad m, MVector v e)
=> Comparison e
-> v (PrimState m) e
-> Int
-> Int
-> e
-> m ()
heapInsert :: Comparison e -> v (PrimState m) e -> Int -> Int -> e -> m ()
heapInsert Comparison e
cmp v (PrimState m) e
v Int
l Int
u e
e = Int -> m ()
sift (Int
u Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
l)
where
sift :: Int -> m ()
sift Int
k
| Int
k Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 = v (PrimState m) e -> Int -> e -> m ()
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> a -> m ()
unsafeWrite v (PrimState m) e
v Int
l e
e
| Bool
otherwise = let pi :: Int
pi = Int -> Int -> Int
forall a. Bits a => a -> Int -> a
shiftR (Int
kInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Int
2
in v (PrimState m) e -> Int -> m e
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
unsafeRead v (PrimState m) e
v (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
pi) m e -> (e -> m ()) -> m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \e
p -> case Comparison e
cmp e
p e
e of
Ordering
LT -> v (PrimState m) e -> Int -> e -> m ()
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> a -> m ()
unsafeWrite v (PrimState m) e
v (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
k) e
p m () -> m () -> m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Int -> m ()
sift Int
pi
Ordering
_ -> v (PrimState m) e -> Int -> e -> m ()
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> a -> m ()
unsafeWrite v (PrimState m) e
v (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
k) e
e
{-# INLINE heapInsert #-}
siftByOffset :: (PrimMonad m, MVector v e)
=> Comparison e -> v (PrimState m) e -> e -> Int -> Int -> Int -> m ()
siftByOffset :: Comparison e -> v (PrimState m) e -> e -> Int -> Int -> Int -> m ()
siftByOffset Comparison e
cmp v (PrimState m) e
a e
val Int
off Int
start Int
len = e -> Int -> Int -> m ()
sift e
val Int
start Int
len
where
sift :: e -> Int -> Int -> m ()
sift e
val Int
root Int
len
| Int
child Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
len = do (Int
child', e
ac) <- Comparison e
-> v (PrimState m) e -> Int -> Int -> Int -> m (Int, e)
forall (m :: * -> *) (v :: * -> * -> *) e.
(PrimMonad m, MVector v e) =>
Comparison e
-> v (PrimState m) e -> Int -> Int -> Int -> m (Int, e)
maximumChild Comparison e
cmp v (PrimState m) e
a Int
off Int
child Int
len
case Comparison e
cmp e
val e
ac of
Ordering
LT -> v (PrimState m) e -> Int -> e -> m ()
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> a -> m ()
unsafeWrite v (PrimState m) e
a (Int
root Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
off) e
ac m () -> m () -> m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> e -> Int -> Int -> m ()
sift e
val Int
child' Int
len
Ordering
_ -> v (PrimState m) e -> Int -> e -> m ()
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> a -> m ()
unsafeWrite v (PrimState m) e
a (Int
root Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
off) e
val
| Bool
otherwise = v (PrimState m) e -> Int -> e -> m ()
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> a -> m ()
unsafeWrite v (PrimState m) e
a (Int
root Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
off) e
val
where child :: Int
child = Int
root Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftL` Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
{-# INLINE siftByOffset #-}
maximumChild :: (PrimMonad m, MVector v e)
=> Comparison e -> v (PrimState m) e -> Int -> Int -> Int -> m (Int, e)
maximumChild :: Comparison e
-> v (PrimState m) e -> Int -> Int -> Int -> m (Int, e)
maximumChild Comparison e
cmp v (PrimState m) e
a Int
off Int
child1 Int
len
| Int
child4 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
len = do e
ac1 <- v (PrimState m) e -> Int -> m e
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
unsafeRead v (PrimState m) e
a (Int
child1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
off)
e
ac2 <- v (PrimState m) e -> Int -> m e
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
unsafeRead v (PrimState m) e
a (Int
child2 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
off)
e
ac3 <- v (PrimState m) e -> Int -> m e
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
unsafeRead v (PrimState m) e
a (Int
child3 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
off)
e
ac4 <- v (PrimState m) e -> Int -> m e
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
unsafeRead v (PrimState m) e
a (Int
child4 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
off)
(Int, e) -> m (Int, e)
forall (m :: * -> *) a. Monad m => a -> m a
return ((Int, e) -> m (Int, e)) -> (Int, e) -> m (Int, e)
forall a b. (a -> b) -> a -> b
$ case Comparison e
cmp e
ac1 e
ac2 of
Ordering
LT -> case Comparison e
cmp e
ac2 e
ac3 of
Ordering
LT -> case Comparison e
cmp e
ac3 e
ac4 of
Ordering
LT -> (Int
child4, e
ac4)
Ordering
_ -> (Int
child3, e
ac3)
Ordering
_ -> case Comparison e
cmp e
ac2 e
ac4 of
Ordering
LT -> (Int
child4, e
ac4)
Ordering
_ -> (Int
child2, e
ac2)
Ordering
_ -> case Comparison e
cmp e
ac1 e
ac3 of
Ordering
LT -> case Comparison e
cmp e
ac3 e
ac4 of
Ordering
LT -> (Int
child4, e
ac4)
Ordering
_ -> (Int
child3, e
ac3)
Ordering
_ -> case Comparison e
cmp e
ac1 e
ac4 of
Ordering
LT -> (Int
child4, e
ac4)
Ordering
_ -> (Int
child1, e
ac1)
| Int
child3 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
len = do e
ac1 <- v (PrimState m) e -> Int -> m e
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
unsafeRead v (PrimState m) e
a (Int
child1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
off)
e
ac2 <- v (PrimState m) e -> Int -> m e
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
unsafeRead v (PrimState m) e
a (Int
child2 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
off)
e
ac3 <- v (PrimState m) e -> Int -> m e
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
unsafeRead v (PrimState m) e
a (Int
child3 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
off)
(Int, e) -> m (Int, e)
forall (m :: * -> *) a. Monad m => a -> m a
return ((Int, e) -> m (Int, e)) -> (Int, e) -> m (Int, e)
forall a b. (a -> b) -> a -> b
$ case Comparison e
cmp e
ac1 e
ac2 of
Ordering
LT -> case Comparison e
cmp e
ac2 e
ac3 of
Ordering
LT -> (Int
child3, e
ac3)
Ordering
_ -> (Int
child2, e
ac2)
Ordering
_ -> case Comparison e
cmp e
ac1 e
ac3 of
Ordering
LT -> (Int
child3, e
ac3)
Ordering
_ -> (Int
child1, e
ac1)
| Int
child2 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
len = do e
ac1 <- v (PrimState m) e -> Int -> m e
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
unsafeRead v (PrimState m) e
a (Int
child1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
off)
e
ac2 <- v (PrimState m) e -> Int -> m e
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
unsafeRead v (PrimState m) e
a (Int
child2 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
off)
(Int, e) -> m (Int, e)
forall (m :: * -> *) a. Monad m => a -> m a
return ((Int, e) -> m (Int, e)) -> (Int, e) -> m (Int, e)
forall a b. (a -> b) -> a -> b
$ case Comparison e
cmp e
ac1 e
ac2 of
Ordering
LT -> (Int
child2, e
ac2)
Ordering
_ -> (Int
child1, e
ac1)
| Bool
otherwise = do e
ac1 <- v (PrimState m) e -> Int -> m e
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
unsafeRead v (PrimState m) e
a (Int
child1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
off) ; (Int, e) -> m (Int, e)
forall (m :: * -> *) a. Monad m => a -> m a
return (Int
child1, e
ac1)
where
child2 :: Int
child2 = Int
child1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
child3 :: Int
child3 = Int
child1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2
child4 :: Int
child4 = Int
child1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
3
{-# INLINE maximumChild #-}