module Swarm.Util.RingBuffer (
RingBuffer,
BufferSize (..),
getValues,
insert,
mkRingBuffer,
) where
import Data.Aeson
import Data.Sequence as S
import Servant.Docs (ToSample)
import Servant.Docs qualified as SD
data BufferSize = Infinite | Finite Int
mkRingBuffer :: BufferSize -> RingBuffer a
mkRingBuffer :: forall a. BufferSize -> RingBuffer a
mkRingBuffer = Seq a -> BufferSize -> RingBuffer a
forall a. Seq a -> BufferSize -> RingBuffer a
RingBuffer Seq a
forall a. Monoid a => a
mempty
data RingBuffer a = RingBuffer (Seq a) BufferSize
instance (ToJSON a) => ToJSON (RingBuffer a) where
toJSON :: RingBuffer a -> Value
toJSON (RingBuffer Seq a
xs BufferSize
_) = Seq a -> Value
forall a. ToJSON a => a -> Value
toJSON Seq a
xs
instance ToSample (RingBuffer a) where
toSamples :: Proxy (RingBuffer a) -> [(Text, RingBuffer a)]
toSamples Proxy (RingBuffer a)
_ = [(Text, RingBuffer a)]
forall a. [(Text, a)]
SD.noSamples
getValues :: RingBuffer a -> Seq a
getValues :: forall a. RingBuffer a -> Seq a
getValues (RingBuffer Seq a
xs BufferSize
_) = Seq a
xs
insert :: a -> RingBuffer a -> RingBuffer a
insert :: forall a. a -> RingBuffer a -> RingBuffer a
insert a
x (RingBuffer Seq a
xs BufferSize
lim) = Seq a -> BufferSize -> RingBuffer a
forall a. Seq a -> BufferSize -> RingBuffer a
RingBuffer Seq a
inserted BufferSize
lim
where
inserted :: Seq a
inserted = Seq a
popped Seq a -> a -> Seq a
forall a. Seq a -> a -> Seq a
:|> a
x
popped :: Seq a
popped = case BufferSize
lim of
BufferSize
Infinite -> Seq a
xs
Finite Int
maxSize -> case Seq a
xs of
Seq a
Empty -> Seq a
xs
a
_ :<| Seq a
back ->
if Seq a -> Int
forall a. Seq a -> Int
S.length Seq a
xs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
maxSize
then Seq a
xs
else Seq a
back