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
{ Ring a -> ForeignPtr a
ringStart :: {-# UNPACK #-} !(ForeignPtr a)
, Ring a -> Ptr a
ringBound :: {-# UNPACK #-} !(Ptr a)
}
startOf :: Ring a -> Ptr a
startOf :: Ring a -> Ptr a
startOf = ForeignPtr a -> Ptr a
forall a. ForeignPtr a -> Ptr a
unsafeForeignPtrToPtr (ForeignPtr a -> Ptr a)
-> (Ring a -> ForeignPtr a) -> Ring a -> Ptr a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ring a -> ForeignPtr a
forall a. Ring a -> ForeignPtr a
ringStart
{-# INLINE new #-}
new :: forall a. Storable a => Int -> IO (Ring a, Ptr a)
new :: Int -> IO (Ring a, Ptr a)
new Int
count = do
let size :: Int
size = Int
count Int -> Int -> Int
forall a. Num a => a -> a -> a
* SIZE_OF(a)
ForeignPtr a
fptr <- Int -> Int -> IO (ForeignPtr a)
forall a. Int -> Int -> IO (ForeignPtr a)
mallocPlainForeignPtrAlignedBytes Int
size (a -> Int
forall a. Storable a => a -> Int
alignment (a
forall a. HasCallStack => a
undefined :: a))
let p :: Ptr a
p = ForeignPtr a -> Ptr a
forall a. ForeignPtr a -> Ptr a
unsafeForeignPtrToPtr ForeignPtr a
fptr
(Ring a, Ptr a) -> IO (Ring a, Ptr a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Ring :: forall a. ForeignPtr a -> Ptr a -> Ring a
Ring
{ ringStart :: ForeignPtr a
ringStart = ForeignPtr a
fptr
, ringBound :: Ptr a
ringBound = Ptr a
p Ptr a -> Int -> Ptr a
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
size
}, Ptr a
p)
{-# INLINE newRing #-}
newRing :: Int -> m (Ring a)
newRing :: Int -> m (Ring a)
newRing = Int -> m (Ring a)
forall a. HasCallStack => a
undefined
{-# INLINE advance #-}
advance :: forall a. Storable a => Ring a -> Ptr a -> Ptr a
advance :: 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 Ptr a
forall b. Ptr b
ptr Ptr a -> Ptr a -> Bool
forall a. Ord a => a -> a -> Bool
< Ptr a
ringBound
then Ptr a
forall b. Ptr b
ptr
else ForeignPtr a -> Ptr a
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 :: 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 Ptr a -> Int -> Ptr a
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
advanceFromHead
where
elemSize :: Int
elemSize = SIZE_OF(a)
ringStartPtr :: Ptr a
ringStartPtr = ForeignPtr a -> Ptr a
forall a. ForeignPtr a -> Ptr a
unsafeForeignPtrToPtr ForeignPtr a
ringStart
lenInBytes :: Int
lenInBytes = Ptr a
ringBound Ptr a -> Ptr a -> Int
forall a b. Ptr a -> Ptr b -> Int
`minusPtr` Ptr a
ringStartPtr
offInBytes :: Int
offInBytes = Ptr a
ringHead Ptr a -> Ptr a -> Int
forall a b. Ptr a -> Ptr b -> Int
`minusPtr` Ptr a
ringStartPtr
len :: Int
len = Bool -> Int -> Int
forall a. HasCallStack => Bool -> a -> a
assert (Int
lenInBytes Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
elemSize Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0) (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$ Int
lenInBytes Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
elemSize
off :: Int
off = Bool -> Int -> Int
forall a. HasCallStack => Bool -> a -> a
assert (Int
offInBytes Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
elemSize Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0) (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$ Int
offInBytes Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
elemSize
advanceFromHead :: Int
advanceFromHead = (Int
off Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
by Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
len) Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
elemSize
{-# INLINE writeN #-}
writeN ::
Int -> Fold m a (Ring a)
writeN :: Int -> Fold m a (Ring a)
writeN = Int -> Fold m a (Ring a)
forall a. HasCallStack => a
undefined
fromArray :: Array a -> Ring a
fromArray :: Array a -> Ring a
fromArray = Array a -> Ring a
forall a. HasCallStack => a
undefined
modifyIndex ::
Ring a -> Int -> (a -> (a, b)) -> m b
modifyIndex :: Ring a -> Int -> (a -> (a, b)) -> m b
modifyIndex = Ring a -> Int -> (a -> (a, b)) -> m b
forall a. HasCallStack => a
undefined
{-# INLINE putIndex #-}
putIndex ::
Ring a -> Int -> a -> m ()
putIndex :: Ring a -> Int -> a -> m ()
putIndex = Ring a -> Int -> a -> m ()
forall a. HasCallStack => a
undefined
{-# INLINE unsafeInsert #-}
unsafeInsert :: Storable a => Ring a -> Ptr a -> a -> IO (Ptr a)
unsafeInsert :: Ring a -> Ptr a -> a -> IO (Ptr a)
unsafeInsert Ring a
rb Ptr a
ringHead a
newVal = do
Ptr a -> a -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr a
ringHead a
newVal
Ptr a -> IO (Ptr a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Ptr a -> IO (Ptr a)) -> Ptr a -> IO (Ptr a)
forall a b. (a -> b) -> a -> b
$ Ring a -> Ptr a -> Ptr a
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 :: Ring a -> a -> m (Ring a)
slide = Ring a -> a -> m (Ring a)
forall a. HasCallStack => a
undefined
{-# INLINE_NORMAL getIndexUnsafe #-}
getIndexUnsafe ::
Ring a -> Int -> m a
getIndexUnsafe :: Ring a -> Int -> m a
getIndexUnsafe = Ring a -> Int -> m a
forall a. HasCallStack => a
undefined
{-# INLINE getIndex #-}
getIndex ::
Ring a -> Int -> m a
getIndex :: Ring a -> Int -> m a
getIndex = Ring a -> Int -> m a
forall a. HasCallStack => a
undefined
{-# INLINE getIndexRev #-}
getIndexRev ::
Ring a -> Int -> m a
getIndexRev :: Ring a -> Int -> m a
getIndexRev = Ring a -> Int -> m a
forall a. HasCallStack => a
undefined
{-# INLINE byteLength #-}
byteLength :: Ring a -> Int
byteLength :: Ring a -> Int
byteLength = Ring a -> Int
forall a. HasCallStack => a
undefined
{-# INLINE length #-}
length ::
Ring a -> Int
length :: Ring a -> Int
length = Ring a -> Int
forall a. HasCallStack => a
undefined
{-# INLINE byteCapacity #-}
byteCapacity :: Ring a -> Int
byteCapacity :: Ring a -> Int
byteCapacity = Ring a -> Int
forall a. HasCallStack => a
undefined
{-# INLINE bytesFree #-}
bytesFree :: Ring a -> Int
bytesFree :: Ring a -> Int
bytesFree = Ring a -> Int
forall a. HasCallStack => a
undefined
{-# INLINE_NORMAL read #-}
read ::
Unfold m (Ring a) a
read :: Unfold m (Ring a) a
read = Unfold m (Ring a) a
forall a. HasCallStack => a
undefined
{-# INLINE_NORMAL readRev #-}
readRev ::
Unfold m (Array a) a
readRev :: Unfold m (Array a) a
readRev = Unfold m (Array a) a
forall a. HasCallStack => a
undefined
{-# INLINE_NORMAL ringsOf #-}
ringsOf ::
Int -> SerialT m a -> SerialT m (Array a)
ringsOf :: Int -> SerialT m a -> SerialT m (Array a)
ringsOf = Int -> SerialT m a -> SerialT m (Array a)
forall a. HasCallStack => a
undefined
castUnsafe :: Ring a -> Ring b
castUnsafe :: Ring a -> Ring b
castUnsafe = Ring a -> Ring b
forall a. HasCallStack => a
undefined
asBytes :: Ring a -> Ring Word8
asBytes :: Ring a -> Ring Word8
asBytes = Ring a -> Ring Word8
forall a b. Ring a -> Ring b
castUnsafe
cast :: forall a b. Storable b => Ring a -> Maybe (Ring b)
cast :: Ring a -> Maybe (Ring b)
cast Ring a
arr =
let len :: Int
len = Ring a -> Int
forall a. Ring a -> Int
byteLength Ring a
arr
r :: Int
r = Int
len Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` SIZE_OF(b)
in if Int
r Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
0
then Maybe (Ring b)
forall a. Maybe a
Nothing
else Ring b -> Maybe (Ring b)
forall a. a -> Maybe a
Just (Ring b -> Maybe (Ring b)) -> Ring b -> Maybe (Ring b)
forall a b. (a -> b) -> a -> b
$ Ring a -> Ring 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 :: 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 = IO Bool -> Bool
forall a. IO a -> a
unsafeInlineIO (IO Bool -> Bool) -> IO Bool -> Bool
forall a b. (a -> b) -> a -> b
$ do
let rs :: Ptr a
rs = ForeignPtr a -> Ptr a
forall a. ForeignPtr a -> Ptr a
unsafeForeignPtrToPtr ForeignPtr a
ringStart
as :: Ptr a
as = Ptr a
arrStart
Bool -> IO () -> IO ()
forall a. HasCallStack => Bool -> a -> a
assert (Ptr a
aEnd Ptr a -> Ptr a -> Int
forall a b. Ptr a -> Ptr b -> Int
`minusPtr` Ptr a
as Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Ptr a
ringBound Ptr a -> Ptr a -> Int
forall a b. Ptr a -> Ptr b -> Int
`minusPtr` Ptr a
rs) (() -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ())
let len :: Int
len = Ptr a
ringBound Ptr a -> Ptr a -> Int
forall a b. Ptr a -> Ptr b -> Int
`minusPtr` Ptr a
rh
Bool
r1 <- Ptr Word8 -> Ptr Word8 -> Int -> IO Bool
memcmp (Ptr a -> Ptr Word8
forall a b. Ptr a -> Ptr b
castPtr Ptr a
rh) (Ptr a -> Ptr Word8
forall a b. Ptr a -> Ptr b
castPtr Ptr a
as) (Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
len Int
n)
Bool
r2 <- if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
len
then Ptr Word8 -> Ptr Word8 -> Int -> IO Bool
memcmp (Ptr a -> Ptr Word8
forall a b. Ptr a -> Ptr b
castPtr Ptr a
rs) (Ptr Any -> Ptr Word8
forall a b. Ptr a -> Ptr b
castPtr (Ptr a
as Ptr a -> Int -> Ptr Any
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
len))
(Int -> Int -> Int
forall a. Ord a => a -> a -> a
min (Ptr a
rh Ptr a -> Ptr a -> Int
forall a b. Ptr a -> Ptr b -> Int
`minusPtr` Ptr a
rs) (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
len))
else Bool -> IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
Bool -> IO Bool
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 :: 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 = IO Bool -> Bool
forall a. IO a -> a
unsafeInlineIO (IO Bool -> Bool) -> IO Bool -> Bool
forall a b. (a -> b) -> a -> b
$ do
let rs :: Ptr a
rs = ForeignPtr a -> Ptr a
forall a. ForeignPtr a -> Ptr a
unsafeForeignPtrToPtr ForeignPtr a
ringStart
let as :: Ptr a
as = Ptr a
arrStart
Bool -> IO () -> IO ()
forall a. HasCallStack => Bool -> a -> a
assert (Ptr a
aEnd Ptr a -> Ptr a -> Int
forall a b. Ptr a -> Ptr b -> Int
`minusPtr` Ptr a
as Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Ptr a
ringBound Ptr a -> Ptr a -> Int
forall a b. Ptr a -> Ptr b -> Int
`minusPtr` Ptr a
rs)
(() -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ())
let len :: Int
len = Ptr a
ringBound Ptr a -> Ptr a -> Int
forall a b. Ptr a -> Ptr b -> Int
`minusPtr` Ptr a
rh
Bool
r1 <- Ptr Word8 -> Ptr Word8 -> Int -> IO Bool
memcmp (Ptr a -> Ptr Word8
forall a b. Ptr a -> Ptr b
castPtr Ptr a
rh) (Ptr a -> Ptr Word8
forall a b. Ptr a -> Ptr b
castPtr Ptr a
as) Int
len
Bool
r2 <- Ptr Word8 -> Ptr Word8 -> Int -> IO Bool
memcmp (Ptr a -> Ptr Word8
forall a b. Ptr a -> Ptr b
castPtr Ptr a
rs) (Ptr Any -> Ptr Word8
forall a b. Ptr a -> Ptr b
castPtr (Ptr a
as Ptr a -> Int -> Ptr Any
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
len))
(Ptr a
rh Ptr a -> Ptr a -> Int
forall a b. Ptr a -> Ptr b -> Int
`minusPtr` Ptr a
rs)
Bool -> IO Bool
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 :: 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 = IO b -> b
forall a. IO a -> a
unsafeInlineIO (IO b -> b) -> IO b -> b
forall a b. (a -> b) -> a -> b
$ ForeignPtr a -> (Ptr a -> IO b) -> IO b
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr a
ringStart ((Ptr a -> IO b) -> IO b) -> (Ptr a -> IO b) -> IO b
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 Ptr a -> Ptr a -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr a
q = b -> IO b
forall (m :: * -> *) a. Monad m => a -> m a
return b
acc
| Bool
otherwise = do
a
x <- Ptr a -> IO a
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 :: 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 (Ptr a -> m b) -> Ptr a -> m b
forall a b. (a -> b) -> a -> b
$ ForeignPtr a -> Ptr a
forall a. ForeignPtr a -> Ptr a
unsafeForeignPtrToPtr ForeignPtr a
fp
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ ForeignPtr a -> IO ()
forall a. ForeignPtr a -> IO ()
touchForeignPtr ForeignPtr a
fp
b -> m b
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 :: 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
..} =
ForeignPtr a -> (Ptr a -> m b) -> m b
forall (m :: * -> *) a b.
MonadIO m =>
ForeignPtr a -> (Ptr a -> m b) -> m b
withForeignPtrM ForeignPtr a
ringStart ((Ptr a -> m b) -> m b) -> (Ptr a -> m b) -> m b
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 Ptr a -> Ptr a -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr a
end = b -> m b
forall (m :: * -> *) a. Monad m => a -> m a
return b
acc
| Bool
otherwise = do
let !x :: a
x = IO a -> a
forall a. IO a -> a
unsafeInlineIO (IO a -> a) -> IO a -> a
forall a b. (a -> b) -> a -> b
$ Ptr a -> IO a
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 :: 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
..} =
ForeignPtr a -> (Ptr a -> m b) -> m b
forall (m :: * -> *) a b.
MonadIO m =>
ForeignPtr a -> (Ptr a -> m b) -> m b
withForeignPtrM ForeignPtr a
ringStart ((Ptr a -> m b) -> m b) -> (Ptr a -> m b) -> m b
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 = IO a -> a
forall a. IO a -> a
unsafeInlineIO (IO a -> a) -> IO a -> a
forall a b. (a -> b) -> a -> b
$ Ptr a -> IO a
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 = Ring a -> Ptr a -> Ptr a
forall a. Storable a => Ring a -> Ptr a -> Ptr a
advance Ring a
rb Ptr a
start
if Ptr a
ptr Ptr a -> Ptr a -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr a
rh
then b -> m b
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 :: 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
..} =
ForeignPtr a -> (Ptr a -> m b) -> m b
forall (m :: * -> *) a b.
MonadIO m =>
ForeignPtr a -> (Ptr a -> m b) -> m b
withForeignPtrM ForeignPtr a
ringStart ((Ptr a -> m b) -> m b) -> (Ptr a -> m b) -> m b
forall a b. (a -> b) -> a -> b
$ \Ptr a
_ -> Int -> b -> Ptr a -> m b
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
_ = b -> m b
forall (m :: * -> *) a. Monad m => a -> m a
return b
acc
go !t
n !b
acc !Ptr a
start = do
let !x :: a
x = IO a -> a
forall a. IO a -> a
unsafeInlineIO (IO a -> a) -> IO a -> a
forall a b. (a -> b) -> a -> b
$ Ptr a -> IO a
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 = Ring a -> Ptr a -> Ptr a
forall a. Storable a => Ring a -> Ptr a -> Ptr a
advance Ring a
rb Ptr a
start
if Ptr a
ptr Ptr a -> Ptr a -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr a
rh Bool -> Bool -> Bool
|| t
n t -> t -> Bool
forall a. Eq a => a -> a -> Bool
== t
0
then b -> m b
forall (m :: * -> *) a. Monad m => a -> m a
return b
acc'
else t -> b -> Ptr a -> m b
go (t
n t -> t -> t
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
[Tuple4' a b c d] -> ShowS
Tuple4' a b c d -> String
(Int -> Tuple4' a b c d -> ShowS)
-> (Tuple4' a b c d -> String)
-> ([Tuple4' a b c d] -> ShowS)
-> Show (Tuple4' a b c d)
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 :: 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)= (Tuple4' (Ring a) (Ptr a) Int s
-> a -> m (Step (Tuple4' (Ring a) (Ptr a) Int s) b))
-> m (Step (Tuple4' (Ring a) (Ptr a) Int s) b)
-> (Tuple4' (Ring a) (Ptr a) Int s -> m b)
-> Fold m a b
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 Tuple4' (Ring a) (Ptr a) Int s -> m b
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) <- IO (Ring a, Ptr a) -> m (Ring a, Ptr a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Ring a, Ptr a) -> m (Ring a, Ptr a))
-> IO (Ring a, Ptr a) -> m (Ring a, Ptr a)
forall a b. (a -> b) -> a -> b
$ Int -> IO (Ring a, Ptr a)
forall a. Storable a => Int -> IO (Ring a, Ptr a)
new Int
n
Step (Tuple4' (Ring a) (Ptr a) Int s) b
-> m (Step (Tuple4' (Ring a) (Ptr a) Int s) b)
forall (m :: * -> *) a. Monad m => a -> m a
return (Step (Tuple4' (Ring a) (Ptr a) Int s) b
-> m (Step (Tuple4' (Ring a) (Ptr a) Int s) b))
-> Step (Tuple4' (Ring a) (Ptr a) Int s) b
-> m (Step (Tuple4' (Ring a) (Ptr a) Int s) b)
forall a b. (a -> b) -> a -> b
$
case Step s b
r of
Partial s
s -> Tuple4' (Ring a) (Ptr a) Int s
-> Step (Tuple4' (Ring a) (Ptr a) Int s) b
forall s b. s -> Step s b
Partial (Tuple4' (Ring a) (Ptr a) Int s
-> Step (Tuple4' (Ring a) (Ptr a) Int s) b)
-> Tuple4' (Ring a) (Ptr a) Int s
-> Step (Tuple4' (Ring a) (Ptr a) Int s) b
forall a b. (a -> b) -> a -> b
$ Ring a -> Ptr a -> Int -> s -> Tuple4' (Ring a) (Ptr a) Int s
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 -> b -> Step (Tuple4' (Ring a) (Ptr a) Int s) 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 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
n = do
Ptr a
rh1 <- IO (Ptr a) -> m (Ptr a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Ptr a) -> m (Ptr a)) -> IO (Ptr a) -> m (Ptr a)
forall a b. (a -> b) -> a -> b
$ Ring a -> Ptr a -> a -> IO (Ptr a)
forall a. Storable a => Ring a -> Ptr a -> a -> IO (Ptr a)
unsafeInsert Ring a
rb Ptr a
rh a
a
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ ForeignPtr a -> IO ()
forall a. ForeignPtr a -> IO ()
touchForeignPtr (Ring a -> ForeignPtr a
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, Maybe a
forall a. Maybe a
Nothing)
Step (Tuple4' (Ring a) (Ptr a) Int s) b
-> m (Step (Tuple4' (Ring a) (Ptr a) Int s) b)
forall (m :: * -> *) a. Monad m => a -> m a
return (Step (Tuple4' (Ring a) (Ptr a) Int s) b
-> m (Step (Tuple4' (Ring a) (Ptr a) Int s) b))
-> Step (Tuple4' (Ring a) (Ptr a) Int s) b
-> m (Step (Tuple4' (Ring a) (Ptr a) Int s) b)
forall a b. (a -> b) -> a -> b
$
case Step s b
r of
Partial s
s -> Tuple4' (Ring a) (Ptr a) Int s
-> Step (Tuple4' (Ring a) (Ptr a) Int s) b
forall s b. s -> Step s b
Partial (Tuple4' (Ring a) (Ptr a) Int s
-> Step (Tuple4' (Ring a) (Ptr a) Int s) b)
-> Tuple4' (Ring a) (Ptr a) Int s
-> Step (Tuple4' (Ring a) (Ptr a) Int s) b
forall a b. (a -> b) -> a -> b
$ Ring a -> Ptr a -> Int -> s -> Tuple4' (Ring a) (Ptr a) Int s
forall a b c d. a -> b -> c -> d -> Tuple4' a b c d
Tuple4' Ring a
rb Ptr a
rh1 (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) s
s
Done b
b -> b -> Step (Tuple4' (Ring a) (Ptr a) Int s) b
forall s b. b -> Step s b
Done b
b
| Bool
otherwise = do
a
old <- IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO a -> m a) -> IO a -> m a
forall a b. (a -> b) -> a -> b
$ Ptr a -> IO a
forall a. Storable a => Ptr a -> IO a
peek Ptr a
rh
Ptr a
rh1 <- IO (Ptr a) -> m (Ptr a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Ptr a) -> m (Ptr a)) -> IO (Ptr a) -> m (Ptr a)
forall a b. (a -> b) -> a -> b
$ Ring a -> Ptr a -> a -> IO (Ptr a)
forall a. Storable a => Ring a -> Ptr a -> a -> IO (Ptr a)
unsafeInsert Ring a
rb Ptr a
rh a
a
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ ForeignPtr a -> IO ()
forall a. ForeignPtr a -> IO ()
touchForeignPtr (Ring a -> ForeignPtr a
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, a -> Maybe a
forall a. a -> Maybe a
Just a
old)
Step (Tuple4' (Ring a) (Ptr a) Int s) b
-> m (Step (Tuple4' (Ring a) (Ptr a) Int s) b)
forall (m :: * -> *) a. Monad m => a -> m a
return (Step (Tuple4' (Ring a) (Ptr a) Int s) b
-> m (Step (Tuple4' (Ring a) (Ptr a) Int s) b))
-> Step (Tuple4' (Ring a) (Ptr a) Int s) b
-> m (Step (Tuple4' (Ring a) (Ptr a) Int s) b)
forall a b. (a -> b) -> a -> b
$
case Step s b
r of
Partial s
s -> Tuple4' (Ring a) (Ptr a) Int s
-> Step (Tuple4' (Ring a) (Ptr a) Int s) b
forall s b. s -> Step s b
Partial (Tuple4' (Ring a) (Ptr a) Int s
-> Step (Tuple4' (Ring a) (Ptr a) Int s) b)
-> Tuple4' (Ring a) (Ptr a) Int s
-> Step (Tuple4' (Ring a) (Ptr a) Int s) b
forall a b. (a -> b) -> a -> b
$ Ring a -> Ptr a -> Int -> s -> Tuple4' (Ring a) (Ptr a) Int s
forall a b c d. a -> b -> c -> d -> Tuple4' a b c d
Tuple4' Ring a
rb Ptr a
rh1 (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) s
s
Done b
b -> b -> Step (Tuple4' (Ring a) (Ptr a) Int s) 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