@@ -4,7 +4,7 @@
4{-# LANGUAGE ExistentialQuantification #-}
4{-# LANGUAGE ExistentialQuantification #-}
7−-- Module : Streamly.RingBuffer
7+-- Module : Streamly.Mem.Ring
8-- Copyright : (c) 2019 Composewell Technologies
8-- Copyright : (c) 2019 Composewell Technologies
9-- License : BSD3
9-- License : BSD3
10-- Maintainer : harendra.kumar@gmail.com
10-- Maintainer : harendra.kumar@gmail.com
@@ -12,8 +12,8 @@
12-- Portability : GHC
12-- Portability : GHC
15−module Streamly.RingBuffer
15+module Streamly.Mem.Ring
16− ( RingBuffer(..)
16+ ( Ring(..)
18 -- * Construction
18 -- * Construction
@@ -40,7 +40,7 @@ import GHC.ForeignPtr (mallocPlainForeignPtrAlignedBytes)
40import GHC.Ptr (Ptr(..))
40import GHC.Ptr (Ptr(..))
41import Prelude hiding (length, concat)
41import Prelude hiding (length, concat)
43−import qualified Streamly.Array.Types as A
43+import qualified Streamly.Mem.Array.Types as A
45-- | A ring buffer is a mutable array of fixed size. Initially the array is
45-- | A ring buffer is a mutable array of fixed size. Initially the array is
46-- empty, with ringStart pointing at the start of allocated memory. We call the
46-- empty, with ringStart pointing at the start of allocated memory. We call the
@@ -54,7 +54,7 @@ import qualified Streamly.Array.Types as A
54-- When using it we should keep in mind that a ringBuffer is a mutable data
54-- When using it we should keep in mind that a ringBuffer is a mutable data
55-- structure. We should not leak out references to it for immutable use.
55-- structure. We should not leak out references to it for immutable use.
57−data RingBuffer a = RingBuffer
57+data Ring a = Ring
58 { ringStart :: !(ForeignPtr a) -- first address
58 { ringStart :: !(ForeignPtr a) -- first address
59 , ringBound :: !(Ptr a) -- first address beyond allocated memory
59 , ringBound :: !(Ptr a) -- first address beyond allocated memory
@@ -62,12 +62,12 @@ data RingBuffer a = RingBuffer
62-- | Create a new ringbuffer and return the ring buffer and the ringHead.
62-- | Create a new ringbuffer and return the ring buffer and the ringHead.
63-- Returns the ring and the ringHead, the ringHead is same as ringStart.
63-- Returns the ring and the ringHead, the ringHead is same as ringStart.
64{-# INLINE new #-}
64{-# INLINE new #-}
65−new :: forall a. Storable a => Int -> IO (RingBuffer a, Ptr a)
65+new :: forall a. Storable a => Int -> IO (Ring a, Ptr a)
66new count = do
66new count = do
67 let size = count * sizeOf (undefined :: a)
67 let size = count * sizeOf (undefined :: a)
68 fptr <- mallocPlainForeignPtrAlignedBytes size (alignment (undefined :: a))
68 fptr <- mallocPlainForeignPtrAlignedBytes size (alignment (undefined :: a))
69 let p = unsafeForeignPtrToPtr fptr
69 let p = unsafeForeignPtrToPtr fptr
70− return $ (RingBuffer
70+ return $ (Ring
71 { ringStart = fptr
71 { ringStart = fptr
72 , ringBound = p `plusPtr` size
72 , ringBound = p `plusPtr` size
@@ -75,8 +75,8 @@ new count = do
75-- | Advance the ringHead by 1 item, wrap around if we hit the end of the
75-- | Advance the ringHead by 1 item, wrap around if we hit the end of the
77{-# INLINE advance #-}
77{-# INLINE advance #-}
78−advance :: forall a. Storable a => RingBuffer a -> Ptr a -> Ptr a
78+advance :: forall a. Storable a => Ring a -> Ptr a -> Ptr a
79−advance RingBuffer{..} ringHead =
79+advance Ring{..} ringHead =
80 let ptr = ringHead `plusPtr` sizeOf (undefined :: a)
80 let ptr = ringHead `plusPtr` sizeOf (undefined :: a)
81 in if ptr < ringBound
81 in if ptr < ringBound
@@ -84,10 +84,10 @@ advance RingBuffer{..} ringHead =
85-- | Insert an item at the head of the ring, when the ring is full this
85-- | Insert an item at the head of the ring, when the ring is full this
86-- replaces the oldest item in the ring with the new item. This is unsafe
86-- replaces the oldest item in the ring with the new item. This is unsafe
87−-- beause ringHead supplied is not verified to be within the RingBuffer. Also,
87+-- beause ringHead supplied is not verified to be within the Ring. Also,
88-- the ringStart foreignPtr must be guaranteed to be alive by the caller.
88-- the ringStart foreignPtr must be guaranteed to be alive by the caller.
89{-# INLINE unsafeInsert #-}
89{-# INLINE unsafeInsert #-}
90−unsafeInsert :: Storable a => RingBuffer a -> Ptr a -> a -> IO (Ptr a)
90+unsafeInsert :: Storable a => Ring a -> Ptr a -> a -> IO (Ptr a)
91unsafeInsert rb ringHead newVal = do
91unsafeInsert rb ringHead newVal = do
92 poke ringHead newVal
92 poke ringHead newVal
93 -- touchForeignPtr (ringStart rb)
93 -- touchForeignPtr (ringStart rb)
@@ -99,8 +99,8 @@ unsafeInsert rb ringHead newVal = do
99-- the ring buffer. This is unsafe because the ringHead Ptr is not checked to
99-- the ring buffer. This is unsafe because the ringHead Ptr is not checked to
100-- be in range.
100-- be in range.
101{-# INLINE unsafeEqArrayN #-}
101{-# INLINE unsafeEqArrayN #-}
102−unsafeEqArrayN :: RingBuffer a -> Ptr a -> A.Array a -> Int -> Bool
102+unsafeEqArrayN :: Ring a -> Ptr a -> A.Array a -> Int -> Bool
103−unsafeEqArrayN RingBuffer{..} rh A.Array{..} n =
103+unsafeEqArrayN Ring{..} rh A.Array{..} n =
104 let !res = A.unsafeInlineIO $ do
104 let !res = A.unsafeInlineIO $ do
105 let rs = unsafeForeignPtrToPtr ringStart
105 let rs = unsafeForeignPtrToPtr ringStart
106 let as = unsafeForeignPtrToPtr aStart
106 let as = unsafeForeignPtrToPtr aStart
@@ -125,8 +125,8 @@ unsafeEqArrayN RingBuffer{..} rh A.Array{..} n =
125-- supplied array must be equal to or bigger than the ringBuffer, ARRAY BOUNDS
125-- supplied array must be equal to or bigger than the ringBuffer, ARRAY BOUNDS
126-- ARE NOT CHECKED.
126-- ARE NOT CHECKED.
127{-# INLINE unsafeEqArray #-}
127{-# INLINE unsafeEqArray #-}
128−unsafeEqArray :: RingBuffer a -> Ptr a -> A.Array a -> Bool
128+unsafeEqArray :: Ring a -> Ptr a -> A.Array a -> Bool
129−unsafeEqArray RingBuffer{..} rh A.Array{..} =
129+unsafeEqArray Ring{..} rh A.Array{..} =
130 let !res = A.unsafeInlineIO $ do
130 let !res = A.unsafeInlineIO $ do
131 let rs = unsafeForeignPtrToPtr ringStart
131 let rs = unsafeForeignPtrToPtr ringStart
132 let as = unsafeForeignPtrToPtr aStart
132 let as = unsafeForeignPtrToPtr aStart
@@ -151,8 +151,8 @@ unsafeEqArray RingBuffer{..} rh A.Array{..} =
151-- Unsafe because the supplied Ptr is not checked to be in range.
151-- Unsafe because the supplied Ptr is not checked to be in range.
152{-# INLINE unsafeFoldRing #-}
152{-# INLINE unsafeFoldRing #-}
153unsafeFoldRing :: forall a b. Storable a
153unsafeFoldRing :: forall a b. Storable a
154− => Ptr a -> (b -> a -> b) -> b -> RingBuffer a -> b
154+ => Ptr a -> (b -> a -> b) -> b -> Ring a -> b
155−unsafeFoldRing ptr f z RingBuffer{..} =
155+unsafeFoldRing ptr f z Ring{..} =
156 let !res = A.unsafeInlineIO $ withForeignPtr ringStart $ \p ->
156 let !res = A.unsafeInlineIO $ withForeignPtr ringStart $ \p ->
157 go z p ptr
157 go z p ptr
@@ -166,8 +166,8 @@ unsafeFoldRing ptr f z RingBuffer{..} =
166-- | Like unsafeFoldRing but with a monadic step function.
166-- | Like unsafeFoldRing but with a monadic step function.
167{-# INLINE unsafeFoldRingM #-}
167{-# INLINE unsafeFoldRingM #-}
168unsafeFoldRingM :: forall m a b. (Monad m, Storable a)
168unsafeFoldRingM :: forall m a b. (Monad m, Storable a)
169− => Ptr a -> (b -> a -> m b) -> b -> RingBuffer a -> m b
169+ => Ptr a -> (b -> a -> m b) -> b -> Ring a -> m b
170−unsafeFoldRingM ptr f z RingBuffer{..} = go z (unsafeForeignPtrToPtr ringStart) ptr
170+unsafeFoldRingM ptr f z Ring{..} = go z (unsafeForeignPtrToPtr ringStart) ptr
172 go !acc !start !end
172 go !acc !start !end
173 | start == end = return acc
173 | start == end = return acc
@@ -182,8 +182,8 @@ unsafeFoldRingM ptr f z RingBuffer{..} = go z (unsafeForeignPtrToPtr ringStart)
182-- the ring.
182-- the ring.
183{-# INLINE unsafeFoldRingFullM #-}
183{-# INLINE unsafeFoldRingFullM #-}
184unsafeFoldRingFullM :: forall m a b. (Monad m, Storable a)
184unsafeFoldRingFullM :: forall m a b. (Monad m, Storable a)
185− => Ptr a -> (b -> a -> m b) -> b -> RingBuffer a -> m b
185+ => Ptr a -> (b -> a -> m b) -> b -> Ring a -> m b
186−unsafeFoldRingFullM rh f z rb@RingBuffer{..} = go z rh
186+unsafeFoldRingFullM rh f z rb@Ring{..} = go z rh
188 go !acc !start = do
188 go !acc !start = do
189 let !x = A.unsafeInlineIO $ peek start
189 let !x = A.unsafeInlineIO $ peek start