on master help sign in
Add lastN combinator
46643d1adithyaov
benchmark/Linear.hs+4
@@ -24,6 +24,7 @@ import qualified Streamly.Memory.Array as A
24import qualified Streamly.Prelude as S
24import qualified Streamly.Prelude as S
25import qualified Streamly.Internal.Data.Sink as Sink
25import qualified Streamly.Internal.Data.Sink as Sink
26
26
27+import qualified Streamly.Internal.Memory.Array as IA
27import qualified Streamly.Internal.Data.Fold as IFL
28import qualified Streamly.Internal.Data.Fold as IFL
28import qualified Streamly.Internal.Prelude as IP
29import qualified Streamly.Internal.Prelude as IP
29import qualified Streamly.Internal.Data.Pipe as Pipe
30import qualified Streamly.Internal.Data.Pipe as Pipe
@@ -200,6 +201,9 @@ main =
200 -- this is too low and causes all benchmarks reported in ns
201 -- this is too low and causes all benchmarks reported in ns
201 -- , benchIOSink "head" Ops.head
202 -- , benchIOSink "head" Ops.head
202 , benchIOSink "last" Ops.last
203 , benchIOSink "last" Ops.last
204+ , benchIOSink "lastN.1" (S.fold (IA.lastN 1))
205+ , benchIOSink "lastN.10" (S.fold (IA.lastN 10))
206+ , benchIOSink "lastN.Max" (S.fold (IA.lastN Ops.maxValue))
203 -- , benchIOSink "lookup" Ops.lookup
207 -- , benchIOSink "lookup" Ops.lookup
204 , benchIOSink "find" Ops.find
208 , benchIOSink "find" Ops.find
205 , benchIOSink "findIndex" Ops.findIndex
209 , benchIOSink "findIndex" Ops.findIndex
src/Streamly/Internal/Data/Stream/StreamD.hs+23
@@ -305,6 +305,10 @@ module Streamly.Internal.Data.Stream.StreamD
305 , mkParallel
305 , mkParallel
306 , applyParallel
306 , applyParallel
307 , foldParallel
307 , foldParallel
308+
309+ -- XXX Move this later
310+ -- XXX Exported from Array again
311+ , lastN
308 )
312 )
309where
313where
310
314
@@ -346,6 +350,7 @@ import Streamly.Internal.Data.Fold.Types (Fold(..))
346import Streamly.Internal.Data.Pipe.Types (Pipe(..), PipeState(..))
350import Streamly.Internal.Data.Pipe.Types (Pipe(..), PipeState(..))
347import Streamly.Internal.Data.Time.Clock (Clock(Monotonic), getTime)
351import Streamly.Internal.Data.Time.Clock (Clock(Monotonic), getTime)
348import Streamly.Internal.Data.Unfold.Types (Unfold(..))
352import Streamly.Internal.Data.Unfold.Types (Unfold(..))
353+import Streamly.Internal.Data.Strict (Tuple3'(..))
349
354
350import Streamly.Internal.Data.Stream.StreamD.Type
355import Streamly.Internal.Data.Stream.StreamD.Type
351import Streamly.Internal.Data.SVar
356import Streamly.Internal.Data.SVar
@@ -4013,3 +4018,21 @@ tapAsync f (Stream step1 state1) = Stream step TapInit
4013 Yield a s -> Yield a (TapDone s)
4018 Yield a s -> Yield a (TapDone s)
4014 Skip s -> Skip (TapDone s)
4019 Skip s -> Skip (TapDone s)
4015 Stop -> Stop
4020 Stop -> Stop
4021+
4022+-- XXX Is there room for improvement?
4023+-- | Take last 'n' elements from the stream and discard the rest.
4024+{-# INLINABLE lastN #-}
4025+lastN :: (Storable a, MonadIO m) => Int -> Fold m a (Array a)
4026+lastN n = Fold step initial done
4027+ where
4028+ step (Tuple3' rb rh i) a = do
4029+ rh1 <- liftIO $ RB.unsafeInsert rb rh a
4030+ return $ Tuple3' rb rh1 (i + 1)
4031+ initial = fmap (\(a, b) -> Tuple3' a b 0) $ liftIO $ RB.new n
4032+ done (Tuple3' rb rh i) = do
4033+ arr <- liftIO $ A.newArray n
4034+ foldFunc i rh snoc' arr rb
4035+ snoc' b a = liftIO $ A.unsafeSnoc b a
4036+ foldFunc i
4037+ | i < n = RB.unsafeFoldRingM
4038+ | otherwise = RB.unsafeFoldRingFullM
src/Streamly/Internal/Memory/Array.hs+3
@@ -124,6 +124,9 @@ module Streamly.Internal.Memory.Array
124 -- * Folding Arrays
124 -- * Folding Arrays
125 , streamFold
125 , streamFold
126 , fold
126 , fold
127+
128+ -- * Folds with Array as the container
129+ , D.lastN
127 )
130 )
128where
131where
129
132