module Streamly.Internal.Data.Ring.Foreign
( Ring(..)
, new
, newRing
, writeN
, advance
, moveBy
, startOf
, unsafeInsert
, slide
, putIndex
, modifyIndex
, read
, readRev
, getIndex
, getIndexUnsafe
, getIndexRev
, length
, byteLength
, byteCapacity
, bytesFree
, cast
, castUnsafe
, asBytes
, fromArray
, unsafeFoldRing
, unsafeFoldRingM
, unsafeFoldRingFullM
, unsafeFoldRingNM
, ringsOf
, unsafeEqArray
, unsafeEqArrayN
, slidingWindow
) where
#include "ArrayMacros.h"
#include "inline.hs"
import Control.Exception (assert)
import Control.Monad.IO.Class (MonadIO(..))
import Data.Word (Word8)
import Foreign.ForeignPtr (ForeignPtr, withForeignPtr, touchForeignPtr)
import Foreign.ForeignPtr.Unsafe (unsafeForeignPtrToPtr)
import Foreign.Ptr (plusPtr, minusPtr, castPtr)
import Foreign.Storable (Storable(..))
import GHC.ForeignPtr (mallocPlainForeignPtrAlignedBytes)
import GHC.Ptr (Ptr(..))
import Streamly.Internal.Data.Array.Foreign.Mut.Type (Array, memcmp)
import Streamly.Internal.Data.Fold.Type (Fold(..), Step(..))
import Streamly.Internal.Data.Stream.Serial (SerialT(..))
import Streamly.Internal.Data.Unfold.Type (Unfold(..))
import Streamly.Internal.System.IO (unsafeInlineIO)
import qualified Streamly.Internal.Data.Array.Foreign.Type as A
import Prelude hiding (length, concat, read)
data Ring a = Ring
{ forall a. Ring a -> ForeignPtr a
ringStart :: {-# UNPACK #-} !(ForeignPtr a)
, forall a. Ring a -> Ptr a
ringBound :: {-# UNPACK #-} !(Ptr a)
}
startOf :: Ring a -> Ptr a
startOf :: forall a. Ring a -> Ptr a
startOf = forall a. ForeignPtr a -> Ptr a
unsafeForeignPtrToPtr forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Ring a -> ForeignPtr a
ringStart
{-# INLINE new #-}
new :: forall a. Storable a => Int -> IO (Ring a, Ptr a)
new :: forall a. Storable a => Int -> IO (Ring a, Ptr a)
new Int
count = do
let size :: Int
size = Int
count forall a. Num a => a -> a -> a
* SIZE_OF(a)
ForeignPtr a
fptr <- forall a. Int -> Int -> IO (ForeignPtr a)
mallocPlainForeignPtrAlignedBytes Int
size (forall a. Storable a => a -> Int
alignment (forall a. HasCallStack => a
undefined :: a))
let p :: Ptr a
p = forall a. ForeignPtr a -> Ptr a
unsafeForeignPtrToPtr ForeignPtr a
fptr
forall (m :: * -> *) a. Monad m => a -> m a
return (Ring
{ ringStart :: ForeignPtr a
ringStart = ForeignPtr a
fptr
, ringBound :: Ptr a
ringBound = Ptr a
p forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
size
}, Ptr a
p)
{-# INLINE newRing #-}
newRing :: Int -> m (Ring a)
newRing :: forall (m :: * -> *) a. Int -> m (Ring a)
newRing = forall a. HasCallStack => a
undefined
{-# INLINE advance #-}
advance :: forall a. Storable a => Ring a -> Ptr a -> Ptr a
advance :: forall a. Storable a => Ring a -> Ptr a -> Ptr a
advance Ring{Ptr a
ForeignPtr a
ringBound :: Ptr a
ringStart :: ForeignPtr a
ringBound :: forall a. Ring a -> Ptr a
ringStart :: forall a. Ring a -> ForeignPtr a
..} Ptr a
ringHead =
let ptr :: Ptr b
ptr = Ptr a
PTR_NEXT(ringHead,a)
in if forall {b}. Ptr b
ptr forall a. Ord a => a -> a -> Bool
< Ptr a
ringBound
then forall {b}. Ptr b
ptr
else forall a. ForeignPtr a -> Ptr a
unsafeForeignPtrToPtr ForeignPtr a
ringStart
{-# INLINE moveBy #-}
moveBy :: forall a. Storable a => Int -> Ring a -> Ptr a -> Ptr a
moveBy :: forall a. Storable a => Int -> Ring a -> Ptr a -> Ptr a
moveBy Int
by Ring {Ptr a
ForeignPtr a
ringBound :: Ptr a
ringStart :: ForeignPtr a
ringBound :: forall a. Ring a -> Ptr a
ringStart :: forall a. Ring a -> ForeignPtr a
..} Ptr a
ringHead = Ptr a
ringStartPtr forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
advanceFromHead
where
elemSize :: Int
elemSize = SIZE_OF(a)
ringStartPtr :: Ptr a
ringStartPtr = forall a. ForeignPtr a -> Ptr a
unsafeForeignPtrToPtr ForeignPtr a
ringStart
lenInBytes :: Int
lenInBytes = Ptr a
ringBound forall a b. Ptr a -> Ptr b -> Int
`minusPtr` Ptr a
ringStartPtr
offInBytes :: Int
offInBytes = Ptr a
ringHead forall a b. Ptr a -> Ptr b -> Int
`minusPtr` Ptr a
ringStartPtr
len :: Int
len = forall a. HasCallStack => Bool -> a -> a
assert (Int
lenInBytes forall a. Integral a => a -> a -> a
`mod` Int
elemSize forall a. Eq a => a -> a -> Bool
== Int
0) forall a b. (a -> b) -> a -> b
$ Int
lenInBytes forall a. Integral a => a -> a -> a
`div` Int
elemSize
off :: Int
off = forall a. HasCallStack => Bool -> a -> a
assert (Int
offInBytes forall a. Integral a => a -> a -> a
`mod` Int
elemSize forall a. Eq a => a -> a -> Bool
== Int
0) forall a b. (a -> b) -> a -> b
$ Int
offInBytes forall a. Integral a => a -> a -> a
`div` Int
elemSize
advanceFromHead :: Int
advanceFromHead = (Int
off forall a. Num a => a -> a -> a
+ Int
by forall a. Integral a => a -> a -> a
`mod` Int
len) forall a. Num a => a -> a -> a
* Int
elemSize
{-# INLINE writeN #-}
writeN ::
Int -> Fold m a (Ring a)
writeN :: forall (m :: * -> *) a. Int -> Fold m a (Ring a)
writeN = forall a. HasCallStack => a
undefined
fromArray :: Array a -> Ring a
fromArray :: forall a. Array a -> Ring a
fromArray = forall a. HasCallStack => a
undefined
modifyIndex ::
Ring a -> Int -> (a -> (a, b)) -> m b
modifyIndex :: forall a b (m :: * -> *). Ring a -> Int -> (a -> (a, b)) -> m b
modifyIndex = forall a. HasCallStack => a
undefined
{-# INLINE putIndex #-}
putIndex ::
Ring a -> Int -> a -> m ()
putIndex :: forall a (m :: * -> *). Ring a -> Int -> a -> m ()
putIndex = forall a. HasCallStack => a
undefined
{-# INLINE unsafeInsert #-}
unsafeInsert :: Storable a => Ring a -> Ptr a -> a -> IO (Ptr a)
unsafeInsert :: forall a. Storable a => Ring a -> Ptr a -> a -> IO (Ptr a)
unsafeInsert Ring a
rb Ptr a
ringHead a
newVal = do
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr a
ringHead a
newVal
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Ring a -> Ptr a -> Ptr a
advance Ring a
rb Ptr a
ringHead
slide ::
Ring a -> a -> m (Ring a)
slide :: forall a (m :: * -> *). Ring a -> a -> m (Ring a)
slide = forall a. HasCallStack => a
undefined
{-# INLINE_NORMAL getIndexUnsafe #-}
getIndexUnsafe ::
Ring a -> Int -> m a
getIndexUnsafe :: forall a (m :: * -> *). Ring a -> Int -> m a
getIndexUnsafe = forall a. HasCallStack => a
undefined
{-# INLINE getIndex #-}
getIndex ::
Ring a -> Int -> m a
getIndex :: forall a (m :: * -> *). Ring a -> Int -> m a
getIndex = forall a. HasCallStack => a
undefined
{-# INLINE getIndexRev #-}
getIndexRev ::
Ring a -> Int -> m a
getIndexRev :: forall a (m :: * -> *). Ring a -> Int -> m a
getIndexRev = forall a. HasCallStack => a
undefined
{-# INLINE byteLength #-}
byteLength :: Ring a -> Int
byteLength :: forall a. Ring a -> Int
byteLength = forall a. HasCallStack => a
undefined
{-# INLINE length #-}
length ::
Ring a -> Int
length :: forall a. Ring a -> Int
length = forall a. HasCallStack => a
undefined
{-# INLINE byteCapacity #-}
byteCapacity :: Ring a -> Int
byteCapacity :: forall a. Ring a -> Int
byteCapacity = forall a. HasCallStack => a
undefined
{-# INLINE bytesFree #-}
bytesFree :: Ring a -> Int
bytesFree :: forall a. Ring a -> Int
bytesFree = forall a. HasCallStack => a
undefined
{-# INLINE_NORMAL read #-}
read ::
Unfold m (Ring a) a
read :: forall (m :: * -> *) a. Unfold m (Ring a) a
read = forall a. HasCallStack => a
undefined
{-# INLINE_NORMAL readRev #-}
readRev ::
Unfold m (Array a) a
readRev :: forall (m :: * -> *) a. Unfold m (Array a) a
readRev = forall a. HasCallStack => a
undefined
{-# INLINE_NORMAL ringsOf #-}
ringsOf ::
Int -> SerialT m a -> SerialT m (Array a)
ringsOf :: forall (m :: * -> *) a. Int -> SerialT m a -> SerialT m (Array a)
ringsOf = forall a. HasCallStack => a
undefined
castUnsafe :: Ring a -> Ring b
castUnsafe :: forall a b. Ring a -> Ring b
castUnsafe = forall a. HasCallStack => a
undefined
asBytes :: Ring a -> Ring Word8
asBytes :: forall a. Ring a -> Ring Word8
asBytes = forall a b. Ring a -> Ring b
castUnsafe
cast :: forall a b. Storable b => Ring a -> Maybe (Ring b)
cast :: forall a b. Storable b => Ring a -> Maybe (Ring b)
cast Ring a
arr =
let len :: Int
len = forall a. Ring a -> Int
byteLength Ring a
arr
r :: Int
r = Int
len forall a. Integral a => a -> a -> a
`mod` SIZE_OF(b)
in if Int
r forall a. Eq a => a -> a -> Bool
/= Int
0
then forall a. Maybe a
Nothing
else forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a b. Ring a -> Ring b
castUnsafe Ring a
arr
{-# INLINE unsafeEqArrayN #-}
unsafeEqArrayN :: Ring a -> Ptr a -> A.Array a -> Int -> Bool
unsafeEqArrayN :: forall a. Ring a -> Ptr a -> Array a -> Int -> Bool
unsafeEqArrayN Ring{Ptr a
ForeignPtr a
ringBound :: Ptr a
ringStart :: ForeignPtr a
ringBound :: forall a. Ring a -> Ptr a
ringStart :: forall a. Ring a -> ForeignPtr a
..} Ptr a
rh A.Array{Ptr a
ArrayContents
aEnd :: forall a. Array a -> Ptr a
arrStart :: forall a. Array a -> Ptr a
arrContents :: forall a. Array a -> ArrayContents
aEnd :: Ptr a
arrStart :: Ptr a
arrContents :: ArrayContents
..} Int
n =
let !res :: Bool
res = forall a. IO a -> a
unsafeInlineIO forall a b. (a -> b) -> a -> b
$ do
let rs :: Ptr a
rs = forall a. ForeignPtr a -> Ptr a
unsafeForeignPtrToPtr ForeignPtr a
ringStart
as :: Ptr a
as = Ptr a
arrStart
forall a. HasCallStack => Bool -> a -> a
assert (Ptr a
aEnd forall a b. Ptr a -> Ptr b -> Int
`minusPtr` Ptr a
as forall a. Ord a => a -> a -> Bool
>= Ptr a
ringBound forall a b. Ptr a -> Ptr b -> Int
`minusPtr` Ptr a
rs) (forall (m :: * -> *) a. Monad m => a -> m a
return ())
let len :: Int
len = Ptr a
ringBound forall a b. Ptr a -> Ptr b -> Int
`minusPtr` Ptr a
rh
Bool
r1 <- Ptr Word8 -> Ptr Word8 -> Int -> IO Bool
memcmp (forall a b. Ptr a -> Ptr b
castPtr Ptr a
rh) (forall a b. Ptr a -> Ptr b
castPtr Ptr a
as) (forall a. Ord a => a -> a -> a
min Int
len Int
n)
Bool
r2 <- if Int
n forall a. Ord a => a -> a -> Bool
> Int
len
then Ptr Word8 -> Ptr Word8 -> Int -> IO Bool
memcmp (forall a b. Ptr a -> Ptr b
castPtr Ptr a
rs) (forall a b. Ptr a -> Ptr b
castPtr (Ptr a
as forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
len))
(forall a. Ord a => a -> a -> a
min (Ptr a
rh forall a b. Ptr a -> Ptr b -> Int
`minusPtr` Ptr a
rs) (Int
n forall a. Num a => a -> a -> a
- Int
len))
else forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
r1 Bool -> Bool -> Bool
&& Bool
r2)
in Bool
res
{-# INLINE unsafeEqArray #-}
unsafeEqArray :: Ring a -> Ptr a -> A.Array a -> Bool
unsafeEqArray :: forall a. Ring a -> Ptr a -> Array a -> Bool
unsafeEqArray Ring{Ptr a
ForeignPtr a
ringBound :: Ptr a
ringStart :: ForeignPtr a
ringBound :: forall a. Ring a -> Ptr a
ringStart :: forall a. Ring a -> ForeignPtr a
..} Ptr a
rh A.Array{Ptr a
ArrayContents
aEnd :: Ptr a
arrStart :: Ptr a
arrContents :: ArrayContents
aEnd :: forall a. Array a -> Ptr a
arrStart :: forall a. Array a -> Ptr a
arrContents :: forall a. Array a -> ArrayContents
..} =
let !res :: Bool
res = forall a. IO a -> a
unsafeInlineIO forall a b. (a -> b) -> a -> b
$ do
let rs :: Ptr a
rs = forall a. ForeignPtr a -> Ptr a
unsafeForeignPtrToPtr ForeignPtr a
ringStart
let as :: Ptr a
as = Ptr a
arrStart
forall a. HasCallStack => Bool -> a -> a
assert (Ptr a
aEnd forall a b. Ptr a -> Ptr b -> Int
`minusPtr` Ptr a
as forall a. Ord a => a -> a -> Bool
>= Ptr a
ringBound forall a b. Ptr a -> Ptr b -> Int
`minusPtr` Ptr a
rs)
(forall (m :: * -> *) a. Monad m => a -> m a
return ())
let len :: Int
len = Ptr a
ringBound forall a b. Ptr a -> Ptr b -> Int
`minusPtr` Ptr a
rh
Bool
r1 <- Ptr Word8 -> Ptr Word8 -> Int -> IO Bool
memcmp (forall a b. Ptr a -> Ptr b
castPtr Ptr a
rh) (forall a b. Ptr a -> Ptr b
castPtr Ptr a
as) Int
len
Bool
r2 <- Ptr Word8 -> Ptr Word8 -> Int -> IO Bool
memcmp (forall a b. Ptr a -> Ptr b
castPtr Ptr a
rs) (forall a b. Ptr a -> Ptr b
castPtr (Ptr a
as forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
len))
(Ptr a
rh forall a b. Ptr a -> Ptr b -> Int
`minusPtr` Ptr a
rs)
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
r1 Bool -> Bool -> Bool
&& Bool
r2)
in Bool
res
{-# INLINE unsafeFoldRing #-}
unsafeFoldRing :: forall a b. Storable a
=> Ptr a -> (b -> a -> b) -> b -> Ring a -> b
unsafeFoldRing :: forall a b.
Storable a =>
Ptr a -> (b -> a -> b) -> b -> Ring a -> b
unsafeFoldRing Ptr a
ptr b -> a -> b
f b
z Ring{Ptr a
ForeignPtr a
ringBound :: Ptr a
ringStart :: ForeignPtr a
ringBound :: forall a. Ring a -> Ptr a
ringStart :: forall a. Ring a -> ForeignPtr a
..} =
let !res :: b
res = forall a. IO a -> a
unsafeInlineIO forall a b. (a -> b) -> a -> b
$ forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr a
ringStart forall a b. (a -> b) -> a -> b
$ \Ptr a
p ->
b -> Ptr a -> Ptr a -> IO b
go b
z Ptr a
p Ptr a
ptr
in b
res
where
go :: b -> Ptr a -> Ptr a -> IO b
go !b
acc !Ptr a
p !Ptr a
q
| Ptr a
p forall a. Eq a => a -> a -> Bool
== Ptr a
q = forall (m :: * -> *) a. Monad m => a -> m a
return b
acc
| Bool
otherwise = do
a
x <- forall a. Storable a => Ptr a -> IO a
peek Ptr a
p
b -> Ptr a -> Ptr a -> IO b
go (b -> a -> b
f b
acc a
x) (PTR_NEXT(p,a)) q
withForeignPtrM :: MonadIO m => ForeignPtr a -> (Ptr a -> m b) -> m b
withForeignPtrM :: forall (m :: * -> *) a b.
MonadIO m =>
ForeignPtr a -> (Ptr a -> m b) -> m b
withForeignPtrM ForeignPtr a
fp Ptr a -> m b
fn = do
b
r <- Ptr a -> m b
fn forall a b. (a -> b) -> a -> b
$ forall a. ForeignPtr a -> Ptr a
unsafeForeignPtrToPtr ForeignPtr a
fp
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. ForeignPtr a -> IO ()
touchForeignPtr ForeignPtr a
fp
forall (m :: * -> *) a. Monad m => a -> m a
return b
r
{-# INLINE unsafeFoldRingM #-}
unsafeFoldRingM :: forall m a b. (MonadIO m, Storable a)
=> Ptr a -> (b -> a -> m b) -> b -> Ring a -> m b
unsafeFoldRingM :: forall (m :: * -> *) a b.
(MonadIO m, Storable a) =>
Ptr a -> (b -> a -> m b) -> b -> Ring a -> m b
unsafeFoldRingM Ptr a
ptr b -> a -> m b
f b
z Ring {Ptr a
ForeignPtr a
ringBound :: Ptr a
ringStart :: ForeignPtr a
ringBound :: forall a. Ring a -> Ptr a
ringStart :: forall a. Ring a -> ForeignPtr a
..} =
forall (m :: * -> *) a b.
MonadIO m =>
ForeignPtr a -> (Ptr a -> m b) -> m b
withForeignPtrM ForeignPtr a
ringStart forall a b. (a -> b) -> a -> b
$ \Ptr a
x -> b -> Ptr a -> Ptr a -> m b
go b
z Ptr a
x Ptr a
ptr
where
go :: b -> Ptr a -> Ptr a -> m b
go !b
acc !Ptr a
start !Ptr a
end
| Ptr a
start forall a. Eq a => a -> a -> Bool
== Ptr a
end = forall (m :: * -> *) a. Monad m => a -> m a
return b
acc
| Bool
otherwise = do
let !x :: a
x = forall a. IO a -> a
unsafeInlineIO forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Ptr a -> IO a
peek Ptr a
start
b
acc1 <- b -> a -> m b
f b
acc a
x
b -> Ptr a -> Ptr a -> m b
go b
acc1 (PTR_NEXT(start,a)) end
{-# INLINE unsafeFoldRingFullM #-}
unsafeFoldRingFullM :: forall m a b. (MonadIO m, Storable a)
=> Ptr a -> (b -> a -> m b) -> b -> Ring a -> m b
unsafeFoldRingFullM :: forall (m :: * -> *) a b.
(MonadIO m, Storable a) =>
Ptr a -> (b -> a -> m b) -> b -> Ring a -> m b
unsafeFoldRingFullM Ptr a
rh b -> a -> m b
f b
z rb :: Ring a
rb@Ring {Ptr a
ForeignPtr a
ringBound :: Ptr a
ringStart :: ForeignPtr a
ringBound :: forall a. Ring a -> Ptr a
ringStart :: forall a. Ring a -> ForeignPtr a
..} =
forall (m :: * -> *) a b.
MonadIO m =>
ForeignPtr a -> (Ptr a -> m b) -> m b
withForeignPtrM ForeignPtr a
ringStart forall a b. (a -> b) -> a -> b
$ \Ptr a
_ -> b -> Ptr a -> m b
go b
z Ptr a
rh
where
go :: b -> Ptr a -> m b
go !b
acc !Ptr a
start = do
let !x :: a
x = forall a. IO a -> a
unsafeInlineIO forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Ptr a -> IO a
peek Ptr a
start
b
acc' <- b -> a -> m b
f b
acc a
x
let ptr :: Ptr a
ptr = forall a. Storable a => Ring a -> Ptr a -> Ptr a
advance Ring a
rb Ptr a
start
if Ptr a
ptr forall a. Eq a => a -> a -> Bool
== Ptr a
rh
then forall (m :: * -> *) a. Monad m => a -> m a
return b
acc'
else b -> Ptr a -> m b
go b
acc' Ptr a
ptr
{-# INLINE unsafeFoldRingNM #-}
unsafeFoldRingNM :: forall m a b. (MonadIO m, Storable a)
=> Int -> Ptr a -> (b -> a -> m b) -> b -> Ring a -> m b
unsafeFoldRingNM :: forall (m :: * -> *) a b.
(MonadIO m, Storable a) =>
Int -> Ptr a -> (b -> a -> m b) -> b -> Ring a -> m b
unsafeFoldRingNM Int
count Ptr a
rh b -> a -> m b
f b
z rb :: Ring a
rb@Ring {Ptr a
ForeignPtr a
ringBound :: Ptr a
ringStart :: ForeignPtr a
ringBound :: forall a. Ring a -> Ptr a
ringStart :: forall a. Ring a -> ForeignPtr a
..} =
forall (m :: * -> *) a b.
MonadIO m =>
ForeignPtr a -> (Ptr a -> m b) -> m b
withForeignPtrM ForeignPtr a
ringStart forall a b. (a -> b) -> a -> b
$ \Ptr a
_ -> forall {t}. (Eq t, Num t) => t -> b -> Ptr a -> m b
go Int
count b
z Ptr a
rh
where
go :: t -> b -> Ptr a -> m b
go t
0 b
acc Ptr a
_ = forall (m :: * -> *) a. Monad m => a -> m a
return b
acc
go !t
n !b
acc !Ptr a
start = do
let !x :: a
x = forall a. IO a -> a
unsafeInlineIO forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Ptr a -> IO a
peek Ptr a
start
b
acc' <- b -> a -> m b
f b
acc a
x
let ptr :: Ptr a
ptr = forall a. Storable a => Ring a -> Ptr a -> Ptr a
advance Ring a
rb Ptr a
start
if Ptr a
ptr forall a. Eq a => a -> a -> Bool
== Ptr a
rh Bool -> Bool -> Bool
|| t
n forall a. Eq a => a -> a -> Bool
== t
0
then forall (m :: * -> *) a. Monad m => a -> m a
return b
acc'
else t -> b -> Ptr a -> m b
go (t
n forall a. Num a => a -> a -> a
- t
1) b
acc' Ptr a
ptr
data Tuple4' a b c d = Tuple4' !a !b !c !d deriving Int -> Tuple4' a b c d -> ShowS
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall a b c d.
(Show a, Show b, Show c, Show d) =>
Int -> Tuple4' a b c d -> ShowS
forall a b c d.
(Show a, Show b, Show c, Show d) =>
[Tuple4' a b c d] -> ShowS
forall a b c d.
(Show a, Show b, Show c, Show d) =>
Tuple4' a b c d -> String
showList :: [Tuple4' a b c d] -> ShowS
$cshowList :: forall a b c d.
(Show a, Show b, Show c, Show d) =>
[Tuple4' a b c d] -> ShowS
show :: Tuple4' a b c d -> String
$cshow :: forall a b c d.
(Show a, Show b, Show c, Show d) =>
Tuple4' a b c d -> String
showsPrec :: Int -> Tuple4' a b c d -> ShowS
$cshowsPrec :: forall a b c d.
(Show a, Show b, Show c, Show d) =>
Int -> Tuple4' a b c d -> ShowS
Show
{-# INLINE slidingWindow #-}
slidingWindow :: forall m a b. (MonadIO m, Storable a)
=> Int -> Fold m (a, Maybe a) b -> Fold m a b
slidingWindow :: forall (m :: * -> *) a b.
(MonadIO m, Storable a) =>
Int -> Fold m (a, Maybe a) b -> Fold m a b
slidingWindow Int
n (Fold s -> (a, Maybe a) -> m (Step s b)
step1 m (Step s b)
initial1 s -> m b
extract1)= forall (m :: * -> *) a b s.
(s -> a -> m (Step s b))
-> m (Step s b) -> (s -> m b) -> Fold m a b
Fold Tuple4' (Ring a) (Ptr a) Int s
-> a -> m (Step (Tuple4' (Ring a) (Ptr a) Int s) b)
step m (Step (Tuple4' (Ring a) (Ptr a) Int s) b)
initial forall {a} {b} {c}. Tuple4' a b c s -> m b
extract
where
initial :: m (Step (Tuple4' (Ring a) (Ptr a) Int s) b)
initial = do
Step s b
r <- m (Step s b)
initial1
(Ring a
rb, Ptr a
rh) <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Int -> IO (Ring a, Ptr a)
new Int
n
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
case Step s b
r of
Partial s
s -> forall s b. s -> Step s b
Partial forall a b. (a -> b) -> a -> b
$ forall a b c d. a -> b -> c -> d -> Tuple4' a b c d
Tuple4' Ring a
rb Ptr a
rh (Int
0 :: Int) s
s
Done b
b -> forall s b. b -> Step s b
Done b
b
step :: Tuple4' (Ring a) (Ptr a) Int s
-> a -> m (Step (Tuple4' (Ring a) (Ptr a) Int s) b)
step (Tuple4' Ring a
rb Ptr a
rh Int
i s
st) a
a
| Int
i forall a. Ord a => a -> a -> Bool
< Int
n = do
Ptr a
rh1 <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Ring a -> Ptr a -> a -> IO (Ptr a)
unsafeInsert Ring a
rb Ptr a
rh a
a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. ForeignPtr a -> IO ()
touchForeignPtr (forall a. Ring a -> ForeignPtr a
ringStart Ring a
rb)
Step s b
r <- s -> (a, Maybe a) -> m (Step s b)
step1 s
st (a
a, forall a. Maybe a
Nothing)
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
case Step s b
r of
Partial s
s -> forall s b. s -> Step s b
Partial forall a b. (a -> b) -> a -> b
$ forall a b c d. a -> b -> c -> d -> Tuple4' a b c d
Tuple4' Ring a
rb Ptr a
rh1 (Int
i forall a. Num a => a -> a -> a
+ Int
1) s
s
Done b
b -> forall s b. b -> Step s b
Done b
b
| Bool
otherwise = do
a
old <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Ptr a -> IO a
peek Ptr a
rh
Ptr a
rh1 <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Ring a -> Ptr a -> a -> IO (Ptr a)
unsafeInsert Ring a
rb Ptr a
rh a
a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. ForeignPtr a -> IO ()
touchForeignPtr (forall a. Ring a -> ForeignPtr a
ringStart Ring a
rb)
Step s b
r <- s -> (a, Maybe a) -> m (Step s b)
step1 s
st (a
a, forall a. a -> Maybe a
Just a
old)
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
case Step s b
r of
Partial s
s -> forall s b. s -> Step s b
Partial forall a b. (a -> b) -> a -> b
$ forall a b c d. a -> b -> c -> d -> Tuple4' a b c d
Tuple4' Ring a
rb Ptr a
rh1 (Int
i forall a. Num a => a -> a -> a
+ Int
1) s
s
Done b
b -> forall s b. b -> Step s b
Done b
b
extract :: Tuple4' a b c s -> m b
extract (Tuple4' a
_ b
_ c
_ s
st) = s -> m b
extract1 s
st