module Streamly.Internal.Data.Ring
( Ring(..)
, createRing
, unsafeInsertRing
) where
import Control.Monad.Primitive (PrimMonad(PrimState))
import Data.IORef (modifyIORef', newIORef, readIORef, writeIORef, IORef)
import Data.Primitive.Array (newArray, writeArray, MutableArray)
data Ring a = Ring
{ forall a. Ring a -> MutableArray (PrimState IO) a
arr :: MutableArray (PrimState IO) a
, forall a. Ring a -> IORef Int
ringHead :: IORef Int
, forall a. Ring a -> Int
ringMax :: !Int
}
{-# INLINE createRing #-}
createRing :: Int -> IO (Ring a)
createRing :: forall a. Int -> IO (Ring a)
createRing Int
count = do
MutableArray RealWorld a
arr' <- forall (m :: * -> *) a.
PrimMonad m =>
Int -> a -> m (MutableArray (PrimState m) a)
newArray Int
count (forall a. HasCallStack => a
undefined :: a)
IORef Int
head' <- forall a. a -> IO (IORef a)
newIORef Int
0
forall (m :: * -> *) a. Monad m => a -> m a
return (Ring
{ arr :: MutableArray (PrimState IO) a
arr = MutableArray RealWorld a
arr'
, ringHead :: IORef Int
ringHead = IORef Int
head'
, ringMax :: Int
ringMax = Int
count
})
{-# INLINE unsafeInsertRing #-}
unsafeInsertRing :: Ring a -> Int -> a -> IO ()
unsafeInsertRing :: forall a. Ring a -> Int -> a -> IO ()
unsafeInsertRing Ring{Int
IORef Int
MutableArray (PrimState IO) a
ringMax :: Int
ringHead :: IORef Int
arr :: MutableArray (PrimState IO) a
ringMax :: forall a. Ring a -> Int
ringHead :: forall a. Ring a -> IORef Int
arr :: forall a. Ring a -> MutableArray (PrimState IO) a
..} Int
idx a
x = do
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> a -> m ()
writeArray MutableArray (PrimState IO) a
arr (forall a. Integral a => a -> a -> a
mod Int
idx Int
ringMax) a
x
Int
ref <- forall a. IORef a -> IO a
readIORef IORef Int
ringHead
if (Int
refforall a. Num a => a -> a -> a
+Int
1) forall a. Ord a => a -> a -> Bool
< Int
ringMax
then forall a. IORef a -> (a -> a) -> IO ()
modifyIORef' IORef Int
ringHead ( forall a. Num a => a -> a -> a
+ Int
1)
else forall a. IORef a -> a -> IO ()
writeIORef IORef Int
ringHead Int
0