packages feed

ring-buffer 0.1.3 → 0.2.0

raw patch · 3 files changed

+55/−1 lines, 3 filesdep +QuickCheckdep +ring-bufferdep ~basedep ~vector

Dependencies added: QuickCheck, ring-buffer

Dependency ranges changed: base, vector

Files

+ Properties.hs view
@@ -0,0 +1,16 @@+import Control.Monad.IO.Class+import Test.QuickCheck+import Test.QuickCheck.Monadic+import qualified Data.RingBuffer as R+import qualified Data.Vector as V++testAppend :: (Eq a)+           => Positive Int -> [a] -> Property+testAppend (Positive cap) xs = monadicIO $ do+    r <- liftIO $ R.new cap :: PropertyM IO (R.RingBuffer V.Vector a)+    liftIO $ mapM_ (`R.append` r) (reverse xs)+    xs' <- liftIO $ R.toList r+    return $ xs' == take cap xs++main :: IO ()+main = quickCheck (testAppend :: Positive Int -> [Int] -> Property)
ring-buffer.cabal view
@@ -1,5 +1,5 @@ name:                ring-buffer-version:             0.1.3+version:             0.2.0 synopsis:            A concurrent, mutable ring-buffer description:         A concurrent, mutable ring-buffer homepage:            http://github.com/bgamari/ring-buffer@@ -24,3 +24,12 @@                        primitive >=0.5 && <0.7   hs-source-dirs:      src   default-language:    Haskell2010++test-suite properties+  type:                exitcode-stdio-1.0+  main-is:             Properties.hs+  default-language:    Haskell2010+  build-depends:       base >= 4.9,+                       QuickCheck >= 2.7,+                       vector >= 0.11,+                       ring-buffer
src/Data/RingBuffer.hs view
@@ -8,6 +8,8 @@                        , concat                        , capacity                        , length+                       , latest+                       , toList                        , withItems                        ) where @@ -49,8 +51,11 @@     put $ RingState (full || a > 0) pos'  -- | Create a new ring of a given length+--+-- /Note:/ size must be non-zero new :: (VG.Vector v a) => Int -> IO (RingBuffer v a) new n = do+    when (n < 1) $ fail "Data.RingBuffer.new: invalid ring size"     buffer <- VGM.new n     state <- newMVar $ RingState False 0     return $ RingBuffer { ringBuffer=buffer, ringState=state }@@ -106,6 +111,30 @@ -- | The current filled length of the ring length :: (VG.Vector v a) => RingBuffer v a -> IO Int length rb = withRing rb length'++-- | Retrieve the $n$th most-recently added item of the ring+latest :: (VG.Vector v a) => RingBuffer v a -> Int -> IO (Maybe a)+latest rb n = withRing rb $ do+    len <- length'+    if n >= len+      then return Nothing+      else Just <$> latest' n++latest' :: (VGM.MVector v a, MonadIO m) => Int -> RingM m v a a+latest' n = do+    len <- length'+    cap <- capacity'+    when (n >= len) $ error "Data.RingBuffer.latest': invalid index"+    let idx = (cap + len - n - 1) `mod` cap+    buf <- ask+    liftIO $ VGM.unsafeRead buf idx++-- | Get the entire contents of the ring, with the most recently added element+-- at the head. Note that this is rather inefficient.+toList :: (VG.Vector v a) => RingBuffer v a -> IO [a]+toList rb = withRing rb $ do+    len <- length'+    mapM latest' [0..len-1]  -- | Execute the given action with the items of the ring. -- Note that no references to the vector may leak out of the action as