module Streamly.Internal.Data.Ring
( 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
, slidingWindowWith
) where
#include "ArrayMacros.h"
#include "inline.hs"
import Control.Exception (assert)
import Control.Monad.IO.Class (MonadIO(..))
import Data.Word (Word8)
import Foreign.Storable
import Foreign.ForeignPtr (ForeignPtr, withForeignPtr, touchForeignPtr)
import Foreign.ForeignPtr.Unsafe (unsafeForeignPtrToPtr)
import Foreign.Ptr (plusPtr, minusPtr, castPtr)
import Streamly.Internal.Data.Unbox as Unboxed (Unbox(peekAt))
import GHC.ForeignPtr (mallocPlainForeignPtrAlignedBytes)
import GHC.Ptr (Ptr(..))
import Streamly.Internal.Data.MutArray.Type (MutArray)
import Streamly.Internal.Data.Fold.Type (Fold(..), Step(..), lmap)
import Streamly.Internal.Data.Stream.Type (Stream)
import Streamly.Internal.Data.Stream.Step (Step(..))
import Streamly.Internal.Data.Unfold.Type (Unfold(..))
import Streamly.Internal.System.IO (unsafeInlineIO)
import qualified Streamly.Internal.Data.MutArray.Type as MA
import qualified Streamly.Internal.Data.Array.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
* forall a. Ord a => a -> a -> a
max Int
1 (forall a. Storable a => a -> Int
sizeOf (forall a. HasCallStack => a
undefined :: 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 = STORABLE_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 :: MutArray a -> Ring a
fromArray :: forall a. MutArray 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 :: forall m a. (MonadIO m, Storable a) => Unfold m (Ring a, Ptr a, Int) a
read :: forall (m :: * -> *) a.
(MonadIO m, Storable a) =>
Unfold m (Ring a, Ptr a, Int) a
read = forall (m :: * -> *) a b s.
(s -> m (Step s b)) -> (a -> m s) -> Unfold m a b
Unfold forall {c} {m :: * -> *} {a}.
(Ord c, Num c, MonadIO m, Storable a) =>
(Ring a, Ptr a, c) -> m (Step (Ring a, Ptr a, c) a)
step forall (m :: * -> *) a. Monad m => a -> m a
return
where
step :: (Ring a, Ptr a, c) -> m (Step (Ring a, Ptr a, c) a)
step (Ring a
rb, Ptr a
rh, c
n) = do
if c
n forall a. Ord a => a -> a -> Bool
<= c
0
then do
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)
forall (m :: * -> *) a. Monad m => a -> m a
return forall s a. Step s a
Stop
else do
a
x <- 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
let rh1 :: Ptr a
rh1 = forall a. Storable a => Ring a -> Ptr a -> Ptr a
advance Ring a
rb Ptr a
rh
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s a. a -> s -> Step s a
Yield a
x (Ring a
rb, Ptr a
rh1, c
n forall a. Num a => a -> a -> a
- c
1)
{-# INLINE_NORMAL readRev #-}
readRev ::
Unfold m (MutArray a) a
readRev :: forall (m :: * -> *) a. Unfold m (MutArray a) a
readRev = forall a. HasCallStack => a
undefined
{-# INLINE_NORMAL ringsOf #-}
ringsOf ::
Int -> Stream m a -> Stream m (MutArray a)
ringsOf :: forall (m :: * -> *) a. Int -> Stream m a -> Stream m (MutArray 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` STORABLE_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{Int
MutByteArray
arrEnd :: forall a. Array a -> Int
arrStart :: forall a. Array a -> Int
arrContents :: forall a. Array a -> MutByteArray
arrEnd :: Int
arrStart :: Int
arrContents :: MutByteArray
..} Int
nBytes
| Int
nBytes forall a. Ord a => a -> a -> Bool
< Int
0 = forall a. HasCallStack => [Char] -> a
error [Char]
"unsafeEqArrayN: n should be >= 0"
| Int
nBytes forall a. Eq a => a -> a -> Bool
== Int
0 = Bool
True
| Bool
otherwise = forall a. IO a -> a
unsafeInlineIO forall a b. (a -> b) -> a -> b
$ Ptr Word8 -> Int -> IO Bool
check (forall a b. Ptr a -> Ptr b
castPtr Ptr a
rh) Int
0
where
w8Contents :: MutByteArray
w8Contents = MutByteArray
arrContents
check :: Ptr Word8 -> Int -> IO Bool
check Ptr Word8
p Int
i = do
(Word8
relem :: Word8) <- forall a. Storable a => Ptr a -> IO a
peek Ptr Word8
p
Word8
aelem <- forall a. Unbox a => Int -> MutByteArray -> IO a
peekAt Int
i MutByteArray
w8Contents
if Word8
relem forall a. Eq a => a -> a -> Bool
== Word8
aelem
then Ptr Word8 -> Int -> IO Bool
go (Ptr Word8
p forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
1) (Int
i forall a. Num a => a -> a -> a
+ Int
1)
else forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
go :: Ptr Word8 -> Int -> IO Bool
go Ptr Word8
p Int
i
| Int
i forall a. Eq a => a -> a -> Bool
== Int
nBytes = forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
| forall a b. Ptr a -> Ptr b
castPtr Ptr Word8
p forall a. Eq a => a -> a -> Bool
== Ptr a
ringBound =
Ptr Word8 -> Int -> IO Bool
go (forall a b. Ptr a -> Ptr b
castPtr (forall a. ForeignPtr a -> Ptr a
unsafeForeignPtrToPtr ForeignPtr a
ringStart)) Int
i
| forall a b. Ptr a -> Ptr b
castPtr Ptr Word8
p forall a. Eq a => a -> a -> Bool
== Ptr a
rh = forall a. ForeignPtr a -> IO ()
touchForeignPtr ForeignPtr a
ringStart forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
| Bool
otherwise = Ptr Word8 -> Int -> IO Bool
check Ptr Word8
p Int
i
{-# 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{Int
MutByteArray
arrEnd :: Int
arrStart :: Int
arrContents :: MutByteArray
arrEnd :: forall a. Array a -> Int
arrStart :: forall a. Array a -> Int
arrContents :: forall a. Array a -> MutByteArray
..} =
forall a. IO a -> a
unsafeInlineIO forall a b. (a -> b) -> a -> b
$ Ptr Word8 -> Int -> IO Bool
check (forall a b. Ptr a -> Ptr b
castPtr Ptr a
rh) Int
0
where
w8Contents :: MutByteArray
w8Contents = MutByteArray
arrContents
check :: Ptr Word8 -> Int -> IO Bool
check Ptr Word8
p Int
i = do
(Word8
relem :: Word8) <- forall a. Storable a => Ptr a -> IO a
peek Ptr Word8
p
Word8
aelem <- forall a. Unbox a => Int -> MutByteArray -> IO a
peekAt Int
i MutByteArray
w8Contents
if Word8
relem forall a. Eq a => a -> a -> Bool
== Word8
aelem
then Ptr Word8 -> Int -> IO Bool
go (Ptr Word8
p forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
1) (Int
i forall a. Num a => a -> a -> a
+ Int
1)
else forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
go :: Ptr Word8 -> Int -> IO Bool
go Ptr Word8
p Int
i
| forall a b. Ptr a -> Ptr b
castPtr Ptr Word8
p forall a. Eq a => a -> a -> Bool
==
Ptr a
ringBound = Ptr Word8 -> Int -> IO Bool
go (forall a b. Ptr a -> Ptr b
castPtr (forall a. ForeignPtr a -> Ptr a
unsafeForeignPtrToPtr ForeignPtr a
ringStart)) Int
i
| forall a b. Ptr a -> Ptr b
castPtr Ptr Word8
p forall a. Eq a => a -> a -> Bool
== Ptr a
rh = forall a. ForeignPtr a -> IO ()
touchForeignPtr ForeignPtr a
ringStart forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
| Bool
otherwise = Ptr Word8 -> Int -> IO Bool
check Ptr Word8
p Int
i
{-# 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 -> [Char]) -> ([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 -> [Char]
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 -> [Char]
$cshow :: forall a b c d.
(Show a, Show b, Show c, Show d) =>
Tuple4' a b c d -> [Char]
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 slidingWindowWith #-}
slidingWindowWith :: forall m a b. (MonadIO m, Storable a, Unbox a)
=> Int -> Fold m ((a, Maybe a), m (MutArray a)) b -> Fold m a b
slidingWindowWith :: forall (m :: * -> *) a b.
(MonadIO m, Storable a, Unbox a) =>
Int -> Fold m ((a, Maybe a), m (MutArray a)) b -> Fold m a b
slidingWindowWith Int
n (Fold s -> ((a, Maybe a), m (MutArray a)) -> m (Step s b)
step1 m (Step s b)
initial1 s -> m b
extract1 s -> m b
final1) =
forall (m :: * -> *) a b s.
(s -> a -> m (Step s b))
-> m (Step s b) -> (s -> m 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 forall {a} {b} {c}. Tuple4' a b c s -> m b
final
where
initial :: m (Step (Tuple4' (Ring a) (Ptr a) Int s) b)
initial = do
if Int
n forall a. Ord a => a -> a -> Bool
<= Int
0
then forall a. HasCallStack => [Char] -> a
error [Char]
"Window size must be > 0"
else 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
toArray :: (t
-> (MutArray a -> a -> m (MutArray a)) -> MutArray a -> t -> m b)
-> t -> t -> m b
toArray t -> (MutArray a -> a -> m (MutArray a)) -> MutArray a -> t -> m b
foldRing t
rb t
rh = do
MutArray a
arr <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
(MonadIO m, Unbox a) =>
Int -> m (MutArray a)
MA.new Int
n
let snoc' :: MutArray a -> a -> m (MutArray a)
snoc' MutArray a
b a
a = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
(MonadIO m, Unbox a) =>
MutArray a -> a -> m (MutArray a)
MA.snocUnsafe MutArray a
b a
a
t -> (MutArray a -> a -> m (MutArray a)) -> MutArray a -> t -> m b
foldRing t
rh forall (m :: * -> *) a.
(MonadIO m, Unbox a) =>
MutArray a -> a -> m (MutArray a)
snoc' MutArray a
arr t
rb
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)
let action :: m (MutArray a)
action = forall {m :: * -> *} {m :: * -> *} {a} {a} {t} {t} {b}.
(MonadIO m, MonadIO m, Unbox a, Unbox a) =>
(t
-> (MutArray a -> a -> m (MutArray a)) -> MutArray a -> t -> m b)
-> t -> t -> m b
toArray forall (m :: * -> *) a b.
(MonadIO m, Storable a) =>
Ptr a -> (b -> a -> m b) -> b -> Ring a -> m b
unsafeFoldRingM Ring a
rb (PTR_NEXT(rh, a))
Step s b
r <- s -> ((a, Maybe a), m (MutArray a)) -> m (Step s b)
step1 s
st ((a
a, forall a. Maybe a
Nothing), m (MutArray a)
action)
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 (MutArray a)) -> m (Step s b)
step1 s
st ((a
a, forall a. a -> Maybe a
Just a
old), forall {m :: * -> *} {m :: * -> *} {a} {a} {t} {t} {b}.
(MonadIO m, MonadIO m, Unbox a, Unbox a) =>
(t
-> (MutArray a -> a -> m (MutArray a)) -> MutArray a -> t -> m b)
-> t -> t -> m b
toArray forall (m :: * -> *) a b.
(MonadIO m, Storable a) =>
Ptr a -> (b -> a -> m b) -> b -> Ring a -> m b
unsafeFoldRingFullM Ring a
rb Ptr a
rh1)
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
final :: Tuple4' a b c s -> m b
final (Tuple4' a
_ b
_ c
_ s
st) = s -> m b
final1 s
st
{-# INLINE slidingWindow #-}
slidingWindow :: forall m a b. (MonadIO m, Storable a, Unbox a)
=> Int -> Fold m (a, Maybe a) b -> Fold m a b
slidingWindow :: forall (m :: * -> *) a b.
(MonadIO m, Storable a, Unbox a) =>
Int -> Fold m (a, Maybe a) b -> Fold m a b
slidingWindow Int
n Fold m (a, Maybe a) b
f = forall (m :: * -> *) a b.
(MonadIO m, Storable a, Unbox a) =>
Int -> Fold m ((a, Maybe a), m (MutArray a)) b -> Fold m a b
slidingWindowWith Int
n (forall a b (m :: * -> *) r. (a -> b) -> Fold m b r -> Fold m a r
lmap forall a b. (a, b) -> a
fst Fold m (a, Maybe a) b
f)