on da36a01 help sign in
47 lines 1.2 kB history raw
1-- |
2-- Module : Streamly.Internal.Data.Ring
3-- Copyright : (c) 2021 Composewell Technologies
4-- License : BSD-3-Clause
5-- Maintainer : streamly@composewell.com
6-- Stability : experimental
7-- Portability : GHC
8--
10module Streamly.Internal.Data.Ring
11 ( Ring(..)
12 , createRing
13 , unsafeInsertRing
14 ) where
16import Data.IORef (modifyIORef', newIORef, readIORef, writeIORef, IORef)
17import Streamly.Internal.Data.Array.Mut.Type
18 ( Array(..)
19 , newArray
20 , putIndexUnsafe
21 )
23data Ring a = Ring
24 { arr :: Array a
25 , ringHead :: IORef Int -- current index to be over-written
26 , ringMax :: !Int -- first index beyond allocated memory
27 }
29{-# INLINE createRing #-}
30createRing :: Int -> IO (Ring a)
31createRing count = do
32 arr' <- newArray count
33 head' <- newIORef 0
34 return (Ring
35 { arr = arr'
36 , ringHead = head'
37 , ringMax = count
38 })
40{-# INLINE unsafeInsertRing #-}
41unsafeInsertRing :: Ring a -> Int -> a -> IO ()
42unsafeInsertRing Ring{..} idx x = do
43 putIndexUnsafe arr (mod idx ringMax) x
44 ref <- readIORef ringHead
45 if (ref+1) < ringMax
46 then modifyIORef' ringHead ( + 1)
47 else writeIORef ringHead 0