on master help sign in
Return an Array generating action in slidingWindowWith
3eae020Harendra Kumar
core/src/Streamly/Internal/Data/Ring/Foreign.hs+26−17
@@ -87,6 +87,7 @@ import Streamly.Internal.Data.Stream.Serial (SerialT(..))
87import Streamly.Internal.Data.Unfold.Type (Unfold(..))
87import Streamly.Internal.Data.Unfold.Type (Unfold(..))
88import Streamly.Internal.System.IO (unsafeInlineIO)
88import Streamly.Internal.System.IO (unsafeInlineIO)
89
89
90+import qualified Streamly.Internal.Data.Array.Foreign.Mut.Type as MA
90import qualified Streamly.Internal.Data.Array.Foreign.Type as A
91import qualified Streamly.Internal.Data.Array.Foreign.Type as A
91
92
92import Prelude hiding (length, concat, read)
93import Prelude hiding (length, concat, read)
@@ -513,23 +514,12 @@ unsafeFoldRingNM count rh f z rb@Ring {..} =
513
514
514data Tuple4' a b c d = Tuple4' !a !b !c !d deriving Show
515data Tuple4' a b c d = Tuple4' !a !b !c !d deriving Show
515
516
516−-- | @slidingWindow collector@ is an incremental sliding window
517+-- | IMPORTANT NOTE: The ring is mutable, therefore, the result of @(m (Array
517−-- fold that does not require all the intermediate elements in a computation.
518+-- a))@ action depends on when it is executed. It does not capture the sanpshot
518−-- This maintains n elements in the window, when a new element comes it slides
519+-- of the ring at a particular time.
519−-- out the oldest element and the new element along with the old element are
520−-- supplied to the collector fold.
521−--
522−-- The Maybe is for the case when initially the window is filling and
523−-- there is no old element.
524−--
525−{-# INLINE slidingWindow #-}
526−slidingWindow :: forall m a b. (MonadIO m, Storable a)
527− => Int -> Fold m (a, Maybe a) b -> Fold m a b
528−slidingWindow n f = slidingWindowWith n (lmap fst f)
529−
530{-# INLINE slidingWindowWith #-}
520{-# INLINE slidingWindowWith #-}
531slidingWindowWith :: forall m a b. (MonadIO m, Storable a)
521slidingWindowWith :: forall m a b. (MonadIO m, Storable a)
532− => Int -> Fold m ((a, Maybe a), (Ring a, Ptr a, Int)) b -> Fold m a b
522+ => Int -> Fold m ((a, Maybe a), (m (Array a))) b -> Fold m a b
533slidingWindowWith n (Fold step1 initial1 extract1) = Fold step initial extract
523slidingWindowWith n (Fold step1 initial1 extract1) = Fold step initial extract
534
524
535 where
525 where
@@ -545,11 +535,16 @@ slidingWindowWith n (Fold step1 initial1 extract1) = Fold step initial extract
545 Partial s -> Partial $ Tuple4' rb rh (0 :: Int) s
535 Partial s -> Partial $ Tuple4' rb rh (0 :: Int) s
546 Done b -> Done b
536 Done b -> Done b
547
537
538+ toArray foldRing rb rh = do
539+ arr <- liftIO $ MA.newArray n
540+ let snoc' b a = liftIO $ MA.snocUnsafe b a
541+ foldRing rh snoc' arr rb
542+
548 step (Tuple4' rb rh i st) a
543 step (Tuple4' rb rh i st) a
549 | i < n = do
544 | i < n = do
550 rh1 <- liftIO $ unsafeInsert rb rh a
545 rh1 <- liftIO $ unsafeInsert rb rh a
551 liftIO $ touchForeignPtr (ringStart rb)
546 liftIO $ touchForeignPtr (ringStart rb)
552− r <- step1 st ((a, Nothing), (rb, rh1, i + 1))
547+ r <- step1 st ((a, Nothing), toArray unsafeFoldRingM rb rh)
553 return $
548 return $
554 case r of
549 case r of
555 Partial s -> Partial $ Tuple4' rb rh1 (i + 1) s
550 Partial s -> Partial $ Tuple4' rb rh1 (i + 1) s
@@ -558,10 +553,24 @@ slidingWindowWith n (Fold step1 initial1 extract1) = Fold step initial extract
558 old <- liftIO $ peek rh
553 old <- liftIO $ peek rh
559 rh1 <- liftIO $ unsafeInsert rb rh a
554 rh1 <- liftIO $ unsafeInsert rb rh a
560 liftIO $ touchForeignPtr (ringStart rb)
555 liftIO $ touchForeignPtr (ringStart rb)
561− r <- step1 st ((a, Just old),(rb, rh1, n) )
556+ r <- step1 st ((a, Just old), toArray unsafeFoldRingFullM rb rh)
562 return $
557 return $
563 case r of
558 case r of
564 Partial s -> Partial $ Tuple4' rb rh1 (i + 1) s
559 Partial s -> Partial $ Tuple4' rb rh1 (i + 1) s
565 Done b -> Done b
560 Done b -> Done b
566
561
567 extract (Tuple4' _ _ _ st) = extract1 st
562 extract (Tuple4' _ _ _ st) = extract1 st
563+
564+-- | @slidingWindow collector@ is an incremental sliding window
565+-- fold that does not require all the intermediate elements in a computation.
566+-- This maintains @n@ elements in the window, when a new element comes it slides
567+-- out the oldest element and the new element along with the old element are
568+-- supplied to the collector fold.
569+--
570+-- The 'Maybe' type is for the case when initially the window is filling and
571+-- there is no old element.
572+--
573+{-# INLINE slidingWindow #-}
574+slidingWindow :: forall m a b. (MonadIO m, Storable a)
575+ => Int -> Fold m (a, Maybe a) b -> Fold m a b
576+slidingWindow n f = slidingWindowWith n (lmap fst f)