Skip to content

Commit 9da80f8

Browse files
authored
Merge pull request #90 from haskell-works/fix-construct64UnzipN-with-tests
Fix construct64UnzipN with tests
2 parents 8bae29f + 04a8b40 commit 9da80f8

File tree

5 files changed

+40
-14
lines changed

5 files changed

+40
-14
lines changed

.vscode/tasks.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
"label": "Test",
3838
"type": "shell",
3939
"command": "bash",
40-
"args": ["-lc", "cabal new-test --enable-tests && echo 'Done'"],
40+
"args": ["-lc", "cabal new-test --enable-tests --test-show-details=direct && echo 'Done'"],
4141
"group": {
4242
"kind": "test",
4343
"isDefault": true

hw-prim.cabal

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ common deepseq { build-depends: deepseq >= 1.4
3535
common directory { build-depends: directory >= 1.2 && < 1.4 }
3636
common exceptions { build-depends: exceptions >= 0.8 && < 0.11 }
3737
common ghc-prim { build-depends: ghc-prim >= 0.5 && < 0.6 }
38-
common hedgehog { build-depends: hedgehog >= 0.5 && < 1.1 }
38+
common hedgehog { build-depends: hedgehog >= 1.0 && < 1.1 }
3939
common hspec { build-depends: hspec >= 2.4 && < 2.8 }
4040
common hw-hspec-hedgehog { build-depends: hw-hspec-hedgehog >= 0.1 && < 0.2 }
4141
common mmap { build-depends: mmap >= 0.5 && < 0.6 }

src/HaskellWorks/Data/ByteString.hs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ module HaskellWorks.Data.ByteString
88
, ToByteString(..)
99
, ToByteStrings(..)
1010
, mmap
11+
, padded
1112
, rechunk
1213
, rechunkPadded
1314
, resegment
@@ -219,3 +220,7 @@ mmap filepath = do
219220
(fptr :: ForeignPtr Word8, offset, size) <- IO.mmapFileForeignPtr filepath IO.ReadOnly Nothing
220221
let !bs = BSI.fromForeignPtr (castForeignPtr fptr) offset size
221222
return bs
223+
224+
padded :: Int -> BS.ByteString -> BS.ByteString
225+
padded n v = v <> BS.replicate ((n - BS.length v) `max` 0) 0
226+
{-# INLINE padded #-}

src/HaskellWorks/Data/Vector/Storable.hs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -108,20 +108,21 @@ construct2N nb fb nc fc as = runST $ do
108108
construct64UnzipN :: Int -> [(BS.ByteString, BS.ByteString)] -> (DVS.Vector Word64, DVS.Vector Word64)
109109
construct64UnzipN nBytes xs = (DVS.unsafeCast ibv, DVS.unsafeCast bpv)
110110
where [ibv, bpv] = DVS.createT $ do
111-
let nW64s = (nBytes + 7) `div` 8
112-
ibmv <- DVSM.new nW64s
113-
bpmv <- DVSM.new nW64s
111+
let nW8s = (nBytes + 7) `div` 8 * 8
112+
ibmv <- DVSM.new nW8s
113+
bpmv <- DVSM.new nW8s
114114
(ibmvRemaining, bpmvRemaining) <- go ibmv bpmv xs
115-
return
116-
[ DVSM.take (((DVSM.length ibmv - ibmvRemaining) `div` 8) * 8) ibmv
117-
, DVSM.take (((DVSM.length bpmv - bpmvRemaining) `div` 8) * 8) bpmv
118-
]
115+
let ibl = ((DVSM.length ibmv - ibmvRemaining + 7) `div` 8) * 8
116+
let bpl = ((DVSM.length bpmv - bpmvRemaining + 7) `div` 8) * 8
117+
return [ DVSM.take ibl ibmv, DVSM.take bpl bpmv]
119118
go :: DVSM.MVector s Word8 -> DVSM.MVector s Word8 -> [(BS.ByteString, BS.ByteString)] -> ST s (Int, Int)
120119
go ibmv bpmv ((ib, bp):ys) = do
121120
DVS.copy (DVSM.take (BS.length ib) ibmv) (asVector8 ib)
122121
DVS.copy (DVSM.take (BS.length bp) bpmv) (asVector8 bp)
123122
go (DVSM.drop (BS.length ib) ibmv) (DVSM.drop (BS.length bp) bpmv) ys
124123
go ibmv bpmv [] = do
125-
DVSM.set (DVSM.take 8 ibmv) 0
126-
DVSM.set (DVSM.take 8 bpmv) 0
127-
return (DVSM.length (DVSM.drop 8 ibmv), DVSM.length (DVSM.drop 8 bpmv))
124+
let ibl = DVSM.length ibmv `mod` 8
125+
let bpl = DVSM.length bpmv `mod` 8
126+
DVSM.set (DVSM.take ibl ibmv) 0
127+
DVSM.set (DVSM.take bpl bpmv) 0
128+
return (DVSM.length (DVSM.drop ibl ibmv), DVSM.length (DVSM.drop bpl bpmv))

test/HaskellWorks/Data/Vector/StorableSpec.hs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,18 @@ module HaskellWorks.Data.Vector.StorableSpec
66
( spec
77
) where
88

9-
import Control.Monad.ST (ST)
10-
import Data.Vector.Storable (Storable)
9+
import Control.Monad.ST (ST)
10+
import Data.Vector.Storable (Storable)
11+
import HaskellWorks.Data.Vector.Storable (construct64UnzipN)
1112
import HaskellWorks.Hspec.Hedgehog
1213
import Hedgehog
1314
import Test.Hspec
1415

16+
import qualified Data.ByteString as BS
1517
import qualified Data.List as L
1618
import qualified Data.Vector.Storable as DVS
1719
import qualified Data.Vector.Storable.Mutable as DVSM
20+
import qualified HaskellWorks.Data.ByteString as BS
1821
import qualified HaskellWorks.Data.Vector.Storable as DVS
1922
import qualified Hedgehog.Gen as G
2023
import qualified Hedgehog.Range as R
@@ -36,6 +39,23 @@ spec = describe "HaskellWorks.Data.Vector.StorableSpec" $ do
3639
let (bs, cs) = DVS.construct2N (length as) stepb (length as * 2) stepc as
3740
DVS.fromList as === bs
3841
DVS.fromList (dupList as) === cs
42+
describe "construct64UnzipN" $ do
43+
it "property" $ requireProperty $ do
44+
abss <- forAll $ G.list (R.linear 1 8) $ (,)
45+
<$> (fmap BS.pack (G.list (R.linear 1 8) (G.word8 R.constantBounded)))
46+
<*> (fmap BS.pack (G.list (R.linear 1 8) (G.word8 R.constantBounded)))
47+
ass <- forAll $ pure $ fmap fst abss
48+
bss <- forAll $ pure $ fmap snd abss
49+
as <- forAll $ pure $ mconcat ass
50+
bs <- forAll $ pure $ mconcat bss
51+
al <- forAll $ pure $ BS.length (mconcat ass)
52+
bl <- forAll $ pure $ BS.length (mconcat bss)
53+
len <- forAll $ pure $ al + bl
54+
let res = construct64UnzipN len (zip ass bss)
55+
let ra = BS.toByteString (fst res)
56+
let rb = BS.toByteString (snd res)
57+
ra === BS.padded ((BS.length as + 7) `div` 8 * 8) as
58+
rb === BS.padded ((BS.length bs + 7) `div` 8 * 8) bs
3959

4060
dupList :: [a] -> [a]
4161
dupList (a:as) = (a:a:dupList as)

0 commit comments

Comments
 (0)