ring-buffer 0.3 → 0.4
raw patch · 4 files changed
+62/−14 lines, 4 filesdep +HUnitdep ~basedep ~vector
Dependencies added: HUnit
Dependency ranges changed: base, vector
Files
- Properties.hs +2/−2
- Test.hs +36/−0
- ring-buffer.cabal +16/−7
- src/Data/RingBuffer.hs +8/−5
Properties.hs view
@@ -4,13 +4,13 @@ import qualified Data.RingBuffer as R import qualified Data.Vector as V -testAppend :: (Eq a)+testAppend :: (Eq a, Show 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+ return $ counterexample (show xs') $ xs' == take cap xs main :: IO () main = quickCheck (testAppend :: Positive Int -> [Int] -> Property)
+ Test.hs view
@@ -0,0 +1,36 @@+{-# LANGUAGE FlexibleContexts #-}++import Data.List+import qualified Data.Vector as V+import qualified Data.Vector.Generic as VG+import Data.RingBuffer as RB+import Test.HUnit++main :: IO ()+main = do+ runTestTT $ test [testConcat]+ return ()++testConcat :: Test+testConcat = TestCase $ do+ rb <- RB.new 40 :: IO (RB.RingBuffer V.Vector Int)+ --mapM_ (flip RB.append rb) [0..44]+ RB.concat (V.fromList [0..4]) rb+ RB.concat (V.fromList [0..50]) rb++ checkLength rb 40+ checkItems rb [50,49..11]+ withItems rb $ \items -> do+ let expected = [11..50]+ assertEqual "withItems: expected" expected (sort $ V.toList items)++checkLength :: VG.Vector v a => RingBuffer v a -> Int -> Assertion+checkLength rb expected = do+ len <- RB.length rb+ assertEqual ("Expected length "++show expected) expected len++checkItems :: (Eq a, Show a, VG.Vector v a)+ => RingBuffer v a -> [a] -> Assertion+checkItems rb expected = do+ items <- RB.toList rb+ assertEqual ("Expected items "++show expected) expected items
ring-buffer.cabal view
@@ -1,7 +1,7 @@ name: ring-buffer-version: 0.3+version: 0.4 synopsis: A concurrent, mutable ring-buffer-description: A concurrent, mutable ring-buffer+description: A mutable ring-buffer implementation suitable for concurrent access. homepage: http://github.com/bgamari/ring-buffer license: BSD3 license-file: LICENSE@@ -18,8 +18,8 @@ library exposed-modules: Data.RingBuffer- build-depends: base >=4.7 && <4.10,- vector >=0.10 && <0.12,+ build-depends: base >=4.7 && <4.11,+ vector >=0.10 && <0.13, mtl >=2.2 && <2.3, primitive >=0.5 && <0.7, exceptions >=0.8 && <0.9@@ -30,7 +30,16 @@ type: exitcode-stdio-1.0 main-is: Properties.hs default-language: Haskell2010- build-depends: base >= 4.9,- QuickCheck >= 2.7,- vector >= 0.11,+ build-depends: base,+ QuickCheck >= 2.7 && < 2.11,+ vector,+ ring-buffer++test-suite tests+ type: exitcode-stdio-1.0+ main-is: Test.hs+ default-language: Haskell2010+ build-depends: base,+ HUnit,+ vector, ring-buffer
src/Data/RingBuffer.hs view
@@ -29,7 +29,9 @@ , ringState :: MVar RingState } -data RingState = RingState { ringFull :: !Bool, ringHead :: !Int }+data RingState = RingState { ringFull :: !Bool -- ^ is the ring full?+ , ringHead :: !Int -- ^ index of next entry to be written+ } -- | We use the @Mutable@ vector type to ensure injectiveness type RingM m vm a = StateT RingState (ReaderT (vm (PrimState IO) a) m)@@ -59,8 +61,8 @@ 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 }+ state0 <- newMVar $ RingState False 0+ return $ RingBuffer { ringBuffer=buffer, ringState=state0 } -- | Reset the ringbuffer to its empty state clear :: VG.Vector v a => RingBuffer v a -> IO ()@@ -114,7 +116,7 @@ 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+-- | 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'@@ -127,7 +129,8 @@ len <- length' cap <- capacity' when (n >= len) $ error "Data.RingBuffer.latest': invalid index"- let idx = (cap + len - n - 1) `mod` cap+ RingState _ hd <- get+ let idx = (hd - n - 1) `mod` cap buf <- ask liftIO $ VGM.unsafeRead buf idx