packages feed

hw-prim 0.6.2.5 → 0.6.2.6

raw patch · 4 files changed

+95/−4 lines, 4 filesdep +semigroupsPVP: minor bump suggested

API additions: PVP suggests at least a minor version bump

Dependencies added: semigroups

API changes (from Hackage documentation)

+ HaskellWorks.Data.ByteString: rechunkSegments :: Int -> [ByteString] -> [ByteString]
+ HaskellWorks.Data.ByteString: rechunkSegmentsPadded :: Int -> [ByteString] -> [ByteString]
+ HaskellWorks.Data.ByteString.Lazy: rechunkSegments :: Int -> ByteString -> ByteString
+ HaskellWorks.Data.ByteString.Lazy: rechunkSegmentsPadded :: Int -> ByteString -> ByteString

Files

hw-prim.cabal view
@@ -3,7 +3,7 @@ -- see: https://github.com/sol/hpack  name:           hw-prim-version:        0.6.2.5+version:        0.6.2.6 synopsis:       Primitive functions and data types description:    Primitive functions and data types. category:       Data@@ -41,6 +41,7 @@     , bytestring      >= 0.9        && < 0.11     , mmap            >= 0.5        && < 0.6     , vector          >= 0.12       && < 0.13+    , semigroups      >= 0.8.4      && < 0.19     , transformers    >= 0.4        && < 0.6   if flag(bounds-checking-enabled)     cpp-options: -DBOUNDS_CHECKING_ENABLED@@ -95,6 +96,7 @@     , bytestring      >= 0.9        && < 0.11     , mmap            >= 0.5        && < 0.6     , vector          >= 0.12       && < 0.13+    , semigroups      >= 0.8.4      && < 0.19     , transformers    >= 0.4        && < 0.6     , QuickCheck          >= 2.10       && < 2.12     , directory           >= 1.2        && < 1.4@@ -106,6 +108,7 @@   if flag(bounds-checking-enabled)     cpp-options: -DBOUNDS_CHECKING_ENABLED   other-modules:+      HaskellWorks.Data.ByteStringSpec       HaskellWorks.Data.FromByteStringSpec       HaskellWorks.Data.FromForeignRegionSpec       HaskellWorks.Data.SearchSpec@@ -127,6 +130,7 @@     , bytestring      >= 0.9        && < 0.11     , mmap            >= 0.5        && < 0.6     , vector          >= 0.12       && < 0.13+    , semigroups      >= 0.8.4      && < 0.19     , transformers    >= 0.4        && < 0.6     , criterion     >= 1.2      && < 1.6     , hw-prim
src/HaskellWorks/Data/ByteString.hs view
@@ -3,8 +3,11 @@ module HaskellWorks.Data.ByteString   ( chunkedBy   , ToByteString(..)+  , rechunkSegments+  , rechunkSegmentsPadded   ) where +import Data.Semigroup ((<>)) import Data.Word  import qualified Data.ByteString          as BS@@ -45,3 +48,38 @@   else case BS.splitAt n bs of     (as, zs) -> as : chunkedBy n zs {-# INLINE chunkedBy #-}++rechunkSegments :: Int -> [BS.ByteString] -> [BS.ByteString]+rechunkSegments multiple = go+  where go (bs:bss) = case BS.length bs of+              bsLen -> if bsLen < multiple+                then case multiple - bsLen of+                  bsNeed -> case bss of+                    (cs:css) -> case BS.length cs of+                      csLen | csLen >  bsNeed -> (bs <> BS.take bsNeed cs ):go (BS.drop bsNeed cs:css)+                      csLen | csLen == bsNeed -> (bs <> cs                ):go                    css+                      _     | otherwise       ->                            go ((bs <> cs)       :css)+                    [] -> [bs]+                else case (bsLen `div` multiple) * multiple of+                  bsCroppedLen -> if bsCroppedLen == bsLen+                    then bs:go bss+                    else BS.take bsCroppedLen bs:go (BS.drop bsCroppedLen bs:bss)+        go [] = []++rechunkSegmentsPadded :: Int -> [BS.ByteString] -> [BS.ByteString]+rechunkSegmentsPadded multiple = go+  where go (bs:bss) = case BS.length bs of+              bsLen -> if bsLen < multiple+                then case multiple - bsLen of+                  bsNeed -> case bss of+                    (cs:css) -> case BS.length cs of+                      csLen | csLen >  bsNeed -> (bs <> BS.take bsNeed cs ):go (BS.drop bsNeed cs:css)+                      csLen | csLen == bsNeed -> (bs <> cs                ):go                    css+                      _     | otherwise       ->                            go ((bs <> cs)       :css)+                    [] -> [bs <> BS.replicate bsNeed 0]+                else case (bsLen `div` multiple) * multiple of+                  bsCroppedLen -> if bsCroppedLen == bsLen+                    then bs:go bss+                    else BS.take bsCroppedLen bs:go (BS.drop bsCroppedLen bs:bss)+        go [] = []+
src/HaskellWorks/Data/ByteString/Lazy.hs view
@@ -1,12 +1,17 @@ {-# LANGUAGE FlexibleInstances #-} -module HaskellWorks.Data.ByteString.Lazy where+module HaskellWorks.Data.ByteString.Lazy+  ( ToLazyByteString(..)+  , rechunkSegments+  , rechunkSegmentsPadded+  ) where  import Data.Word import HaskellWorks.Data.ByteString (ToByteString (..)) -import qualified Data.ByteString.Lazy as LBS-import qualified Data.Vector.Storable as DVS+import qualified Data.ByteString.Lazy         as LBS+import qualified Data.Vector.Storable         as DVS+import qualified HaskellWorks.Data.ByteString as BS  class ToLazyByteString a where   toLazyByteString :: a -> LBS.ByteString@@ -46,3 +51,9 @@ instance ToLazyByteString [DVS.Vector Word64] where   toLazyByteString vs = LBS.fromChunks (toByteString <$> vs)   {-# INLINE toLazyByteString #-}++rechunkSegments :: Int -> LBS.ByteString -> LBS.ByteString+rechunkSegments multiple = LBS.fromChunks . BS.rechunkSegments multiple . LBS.toChunks++rechunkSegmentsPadded :: Int -> LBS.ByteString -> LBS.ByteString+rechunkSegmentsPadded multiple = LBS.fromChunks . BS.rechunkSegmentsPadded multiple . LBS.toChunks
+ test/HaskellWorks/Data/ByteStringSpec.hs view
@@ -0,0 +1,38 @@+module HaskellWorks.Data.ByteStringSpec where++import Control.Monad+import HaskellWorks.Hspec.Hedgehog+import Hedgehog+import Test.Hspec++import qualified Data.ByteString              as BS+import qualified Data.ByteString.Lazy         as LBS+import qualified HaskellWorks.Data.ByteString as BS+import qualified Hedgehog.Gen                 as G+import qualified Hedgehog.Range               as R++{-# ANN module ("HLint: Ignore Redundant do" :: String) #-}++spec :: Spec+spec = describe "HaskellWorks.Data.ByteStringSpec" $ do+  it "rechunkSegments does not modify data" $ requireProperty $ do+    bss       <- forAll $ (BS.pack <$>) <$> G.list (R.linear 0 8) (G.list (R.linear 0 24) (G.word8 R.constantBounded))+    chunkSize <- forAll $ G.int (R.linear 1 4)+    mconcat (BS.rechunkSegments chunkSize bss) === mconcat bss+  it "rechunkSegments creates correctly sized segments" $ requireProperty $ do+    bss       <- forAll $ (BS.pack <$>) <$> G.list (R.linear 0 8) (G.list (R.linear 0 24) (G.word8 R.constantBounded))+    chunkSize <- forAll $ G.int (R.linear 1 4)+    forM_ (drop 1 (reverse (BS.rechunkSegments chunkSize bss))) $ \bs -> do+      (BS.length bs) `mod` chunkSize === 0+  it "rechunkSegmentsPadded does not modify data" $ requireProperty $ do+    bss       <- forAll $ (BS.pack <$>) <$> G.list (R.linear 0 8) (G.list (R.linear 0 24) (G.word8 R.constantBounded))+    chunkSize <- forAll $ G.int (R.linear 1 4)+    elbs      <- forAll $ pure $ LBS.fromChunks bss+    albs      <- forAll $ pure $ LBS.take (LBS.length elbs) (LBS.fromChunks (BS.rechunkSegmentsPadded chunkSize bss))+    albs === elbs+  it "rechunkSegmentsPadded creates correctly sized segments" $ requireProperty $ do+    bss       <- forAll $ (BS.pack <$>) <$> G.list (R.linear 0 8) (G.list (R.linear 0 24) (G.word8 R.constantBounded))+    chunkSize <- forAll $ G.int (R.linear 1 4)+    forM_ (reverse (BS.rechunkSegmentsPadded chunkSize bss)) $ \bs -> do+      (BS.length bs) `mod` chunkSize === 0+