on master help sign in
Add function to fold n items in the ring
40e8275Harendra Kumar
src/Streamly/Memory/Ring.hs+26
@@ -23,6 +23,7 @@ module Streamly.Memory.Ring
23 , unsafeFoldRing
23 , unsafeFoldRing
24 , unsafeFoldRingM
24 , unsafeFoldRingM
25 , unsafeFoldRingFullM
25 , unsafeFoldRingFullM
26+ , unsafeFoldRingNM
26
27
27 -- * Fast Byte Comparisons
28 -- * Fast Byte Comparisons
28 , unsafeEqArray
29 , unsafeEqArray
@@ -209,6 +210,9 @@ unsafeFoldRingM ptr f z Ring {..} =
209-- pointer. Assuming the supplied ringHead pointer points to the oldest item,
210-- pointer. Assuming the supplied ringHead pointer points to the oldest item,
210-- this would fold the ring starting from the oldest item to the newest item in
211-- this would fold the ring starting from the oldest item to the newest item in
211-- the ring.
212-- the ring.
213+--
214+-- Note, this will crash on ring of 0 size.
215+--
212{-# INLINE unsafeFoldRingFullM #-}
216{-# INLINE unsafeFoldRingFullM #-}
213unsafeFoldRingFullM :: forall m a b. (MonadIO m, Storable a)
217unsafeFoldRingFullM :: forall m a b. (MonadIO m, Storable a)
214 => Ptr a -> (b -> a -> m b) -> b -> Ring a -> m b
218 => Ptr a -> (b -> a -> m b) -> b -> Ring a -> m b
@@ -222,3 +226,25 @@ unsafeFoldRingFullM rh f z rb@Ring {..} =
222 if ptr == rh
226 if ptr == rh
223 then return acc'
227 then return acc'
224 else go acc' ptr
228 else go acc' ptr
229+
230+-- | Fold @Int@ items in the ring starting at @Ptr a@. Won't fold more
231+-- than the length of the ring.
232+--
233+-- Note, this will crash on ring of 0 size.
234+--
235+{-# INLINE unsafeFoldRingNM #-}
236+unsafeFoldRingNM :: forall m a b. (MonadIO m, Storable a)
237+ => Int -> Ptr a -> (b -> a -> m b) -> b -> Ring a -> m b
238+unsafeFoldRingNM count rh f z rb@Ring {..} =
239+ withForeignPtrM ringStart $ \_ -> go count z rh
240+
241+ where
242+
243+ go 0 acc _ = return acc
244+ go !n !acc !start = do
245+ let !x = A.unsafeInlineIO $ peek start
246+ acc' <- f acc x
247+ let ptr = advance rb start
248+ if ptr == rh || n == 0
249+ then return acc'
250+ else go (n - 1) acc' ptr