@@ -18,6 +18,7 @@ module Streamly.Internal.Data.Array
18 -- * Construction
18 -- * Construction
22 , fromStreamDN
23 , fromStreamDN
23 , fromStreamD
24 , fromStreamD
@@ -52,6 +53,7 @@ import Control.DeepSeq (NFData(..))
52import Control.Monad (when)
53import Control.Monad (when)
53import Control.Monad.IO.Class (liftIO, MonadIO)
54import Control.Monad.IO.Class (liftIO, MonadIO)
54import Data.Functor.Identity (runIdentity)
55import Data.Functor.Identity (runIdentity)
55import GHC.Base (Int(..))
57import GHC.Base (Int(..))
56import GHC.IO (unsafePerformIO)
58import GHC.IO (unsafePerformIO)
@@ -62,6 +64,7 @@ import Streamly.Internal.Data.Unfold.Type (Unfold(..))
63import qualified GHC.Exts as Exts
65import qualified GHC.Exts as Exts
64import qualified Streamly.Internal.Data.Fold.Type as FL
66import qualified Streamly.Internal.Data.Fold.Type as FL
67+import qualified Streamly.Internal.Data.Ring as RB
65import qualified Streamly.Internal.Data.Stream.StreamD as D
68import qualified Streamly.Internal.Data.Stream.StreamD as D
67import Data.Primitive.Array hiding (fromList, fromListN)
70import Data.Primitive.Array hiding (fromList, fromListN)
@@ -248,3 +251,30 @@ streamFold f arr = f (toStream arr)
248{-# INLINE getIndexUnsafe #-}
251{-# INLINE getIndexUnsafe #-}
249getIndexUnsafe :: Array a -> Int -> a
252getIndexUnsafe :: Array a -> Int -> a
250getIndexUnsafe = indexArray
253getIndexUnsafe = indexArray
255+{-# INLINE writeLastN #-}
256+writeLastN :: MonadIO m => Int -> Fold m a (Array a)
258+ | n <= 0 = fmap (const mempty) FL.drain
259+ | otherwise = Fold step initial done
264+ rb <- liftIO $ RB.createRing n
265+ return $ FL.Partial $ Tuple' rb (0 :: Int)
267+ step (Tuple' rb rh) x = do
268+ liftIO $ RB.unsafeInsertRing rb rh x
269+ return $ FL.Partial $ Tuple' rb (rh + 1)
271+ done (Tuple' rb rh) = do
272+ arr' <- liftIO $ newArray (min rh n) (undefined :: a)
273+ ref <- liftIO $ readIORef $ RB.ringHead rb
276+ liftIO $ copyMutableArray arr' 0 (RB.arr rb) 0 ref
278+ liftIO $ copyMutableArray arr' 0 (RB.arr rb) ref (n - ref)
279+ liftIO $ copyMutableArray arr' (n - ref) (RB.arr rb) 0 ref
280+ liftIO $ unsafeFreezeArray arr'