on aaa775b help sign in
44 lines 1.3 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 Control.Monad.Primitive (PrimMonad(PrimState))
17import Data.IORef (modifyIORef', newIORef, readIORef, writeIORef, IORef)
18import Data.Primitive.Array (newArray, writeArray, MutableArray)
20data Ring a = Ring
21 { arr :: MutableArray (PrimState IO) a
22 , ringHead :: IORef Int -- current index to be over-written
23 , ringMax :: !Int -- first index beyond allocated memory
24 }
26{-# INLINE createRing #-}
27createRing :: Int -> IO (Ring a)
28createRing count = do
29 arr' <- newArray count (undefined :: a)
30 head' <- newIORef 0
31 return (Ring
32 { arr = arr'
33 , ringHead = head'
34 , ringMax = count
35 })
37{-# INLINE unsafeInsertRing #-}
38unsafeInsertRing :: Ring a -> Int -> a -> IO ()
39unsafeInsertRing Ring{..} idx x = do
40 writeArray arr (mod idx ringMax) x
41 ref <- readIORef ringHead
42 if (ref+1) < ringMax
43 then modifyIORef' ringHead ( + 1)
44 else writeIORef ringHead 0