vector-binary-instances-0.2.3.5/0000755000000000000000000000000013073205763014624 5ustar0000000000000000vector-binary-instances-0.2.3.5/Setup.hs0000644000000000000000000000011013073205763016250 0ustar0000000000000000#!/usr/bin/env runhaskell import Distribution.Simple main = defaultMain vector-binary-instances-0.2.3.5/vector-binary-instances.cabal0000644000000000000000000000462313073205763022366 0ustar0000000000000000Name: vector-binary-instances Version: 0.2.3.5 Synopsis: Instances of Data.Binary and Data.Serialize for vector Description: Instances for Binary for the types defined in the vector package, making it easy to serialize vectors to and from disk. We use the generic interface to vectors, so all vector types are supported. Specific instances are provided for unboxed, boxed and storable vectors. . To serialize a vector: . > *Data.Vector.Binary> let v = Data.Vector.fromList [1..10] > *Data.Vector.Binary> v > fromList [1,2,3,4,5,6,7,8,9,10] :: Data.Vector.Vector > *Data.Vector.Binary> encode v > Chunk "\NUL\NUL\NUL\NUL\NUL...\NUL\NUL\NUL\t\NUL\NUL\NUL\NUL\n" Empty . Which you can in turn compress before writing to disk: . > compress . encode $ v > Chunk "\US\139\b\NUL\NUL\N...\229\240,\254:\NUL\NUL\NUL" Empty -- URL for the project homepage or repository. Homepage: https://github.com/bos/vector-binary-instances bug-reports: https://github.com/bos/vector-binary-instances/issues License: BSD3 License-file: LICENSE Author: Don Stewart Maintainer: dons00@gmail.com, bos@serpentine.com, Ben Gamari Tested-With: GHC==8.0.2, GHC==7.10.3, GHC==7.8.4, GHC==7.6.3, GHC==7.4.2 -- A copyright notice. -- Copyright: -- Stability of the pakcage (experimental, provisional, stable...) Stability: Experimental Category: Data Build-type: Simple -- Constraint on the version of Cabal needed to build this package. Cabal-version: >=1.8 Library Ghc-options: -Wall -- Modules exported by the library. Exposed-modules: Data.Vector.Binary -- Packages needed in order to build this package. Build-depends: base > 3 && < 4.11, vector >= 0.6 && < 0.13, binary >= 0.5 && < 0.9 Benchmark benchmarks Type: exitcode-stdio-1.0 Main-is: Benchmarks.hs Build-depends: base, vector-binary-instances, vector, bytestring, binary, criterion, deepseq hs-source-dirs: benchmarks Test-Suite tests Type: exitcode-stdio-1.0 Main-is: test/Main.hs Build-depends: base, vector-binary-instances, vector, binary, tasty, tasty-quickcheck source-repository head type: git location: https://github.com/bos/vector-binary-instances vector-binary-instances-0.2.3.5/LICENSE0000644000000000000000000000276013073205763015636 0ustar0000000000000000Copyright Don Stewart 2010-2012 All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Don Stewart nor the names of other contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. vector-binary-instances-0.2.3.5/Data/0000755000000000000000000000000013073205763015475 5ustar0000000000000000vector-binary-instances-0.2.3.5/Data/Vector/0000755000000000000000000000000013073205763016737 5ustar0000000000000000vector-binary-instances-0.2.3.5/Data/Vector/Binary.hs0000644000000000000000000000737513073205763020533 0ustar0000000000000000{-# OPTIONS_GHC -fno-warn-orphans #-} -------------------------------------------------------------------- -- | -- Module : Data.Vector.Binary -- Copyright : (c) Don Stewart 2010-2012 -- License : BSD3 -- -- Maintainer: Don Stewart -- Stability : provisional -- Portability: GHC only -- Instances for Binary for the types defined in the vector package, -- making it easy to serialize vectors to and from disk. We use the -- generic interface to vectors, so all vector types are supported. -- -- All functions in this module use same data format. Different -- representations for vector length and its elements could be used -- but general shape is same. -- -- > [number of elements] -- > [vector element ] : N times -- -- To serialize a vector: -- -- > *Data.Vector.Binary> let v = Data.Vector.fromList [1..10] -- > *Data.Vector.Binary> v -- > fromList [1,2,3,4,5,6,7,8,9,10] :: Data.Vector.Vector -- > *Data.Vector.Binary> encode v -- > Chunk "\NUL\NUL\NUL\NUL\NUL...\NUL\NUL\NUL\t\NUL\NUL\NUL\NUL\n" Empty -- -- Which you can in turn compress before writing to disk: -- -- > compress . encode $ v -- > Chunk "\US\139\b\NUL\NUL\N...\229\240,\254:\NUL\NUL\NUL" Empty -- -------------------------------------------------------------------- module Data.Vector.Binary ( genericGetVector , genericGetVectorWith , genericPutVector , genericPutVectorWith ) where import Data.Binary import qualified Data.Vector.Generic as G import qualified Data.Vector.Generic.Mutable as GM import qualified Data.Vector.Unboxed as U import qualified Data.Vector.Storable as S import qualified Data.Vector.Primitive as P import Data.Vector (Vector) import System.IO.Unsafe import Foreign.Storable (Storable) -- Enumerate the instances to avoid the nasty overlapping instances. -- | Boxed, generic vectors. instance Binary a => Binary (Vector a) where put = genericPutVector get = genericGetVector {-# INLINE get #-} -- | Unboxed vectors instance (U.Unbox a, Binary a) => Binary (U.Vector a) where put = genericPutVector get = genericGetVector {-# INLINE get #-} -- | Primitive vectors instance (P.Prim a, Binary a) => Binary (P.Vector a) where put = genericPutVector get = genericGetVector {-# INLINE get #-} -- | Storable vectors instance (Storable a, Binary a) => Binary (S.Vector a) where put = genericPutVector get = genericGetVector {-# INLINE get #-} ------------------------------------------------------------------------ -- | Deserialize vector using custom parsers. genericGetVectorWith :: (G.Vector v a, Binary a) => Get Int -- ^ Parser for vector size -> Get a -- ^ Parser for vector's element -> Get (v a) {-# INLINE genericGetVectorWith #-} genericGetVectorWith getN getA = do n <- getN v <- return $ unsafePerformIO $ GM.unsafeNew n let go 0 = return () go i = do x <- getA () <- return $ unsafePerformIO $ GM.unsafeWrite v (n-i) x go (i-1) () <- go n return $ unsafePerformIO $ G.unsafeFreeze v -- | Generic put for anything in the G.Vector class which uses custom -- encoders. genericPutVectorWith :: (G.Vector v a, Binary a) => (Int -> Put) -- ^ Encoder for vector size -> (a -> Put) -- ^ Encoder for vector's element -> v a -> Put {-# INLINE genericPutVectorWith #-} genericPutVectorWith putN putA v = do putN (G.length v) G.mapM_ putA v -- | Generic function for vector deserialization. genericGetVector :: (G.Vector v a, Binary a) => Get (v a) {-# INLINE genericGetVector #-} genericGetVector = genericGetVectorWith get get -- | Generic put for anything in the G.Vector class. genericPutVector :: (G.Vector v a, Binary a) => v a -> Put {-# INLINE genericPutVector #-} genericPutVector = genericPutVectorWith put put vector-binary-instances-0.2.3.5/benchmarks/0000755000000000000000000000000013073205763016741 5ustar0000000000000000vector-binary-instances-0.2.3.5/benchmarks/Benchmarks.hs0000644000000000000000000000462413073205763021360 0ustar0000000000000000{-# LANGUAGE CPP #-} import Criterion.Main import Data.Binary import Data.Binary.Get import Data.Binary.Put import qualified Data.ByteString.Lazy as BS import qualified Data.Vector.Unboxed as U import Data.Vector.Binary #if !(MIN_VERSION_bytestring(0,10,0)) import Control.DeepSeq (NFData(..)) import qualified Data.ByteString.Lazy.Internal as BS instance NFData BS.ByteString where rnf BS.Empty = () rnf (BS.Chunk _ b) = rnf b #endif -- We take care to avoid using the @Binary@ instances here to avoid issues with -- overlapping instances as the install plan will involve two different versions -- of k@vector-binary-instances@ (as @Criterion@ transitively depends upon -- @vector-binary-instances@). See #7 for details. vec1,vec2,vec3,vec4,vec5 :: U.Vector Int vec1 = U.enumFromN 0 3 vec2 = U.enumFromN 0 30 vec3 = U.enumFromN 0 300 vec4 = U.enumFromN 0 30000 vec5 = U.enumFromN 0 300000 bs1,bs2,bs3,bs4,bs5 :: BS.ByteString bs1 = encodeVector vec1 bs2 = encodeVector vec2 bs3 = encodeVector vec3 bs4 = encodeVector vec4 bs5 = encodeVector vec5 naiveGet :: (Binary a, U.Unbox a) => Get (U.Vector a) naiveGet = do n <- get U.replicateM n get naiveGet' :: (Binary a, U.Unbox a) => Get (U.Vector a) naiveGet' = do n <- get U.replicateM n get -- A feeble attempt at simulating what will happen if we end up with a situation -- where we are unable to specialize to the element type {-# NOINLINE naiveGet' #-} type V = BS.ByteString -> U.Vector Int encodeVector :: U.Vector Int -> BS.ByteString encodeVector = runPut . genericPutVector benchGetSize :: String -> BS.ByteString -> Benchmark benchGetSize name bs = bgroup name [ bench "U.Vector Int" $ nf (runGet genericGetVector :: V) bs , bench "naive U.Vector Int" $ nf (runGet naiveGet :: V) bs , bench "noinline naive U.Vector Int" $ nf (runGet naiveGet' :: V) bs ] main = defaultMain [ bgroup "encode" [ bench "U.Vector Int 3" $ nf encodeVector vec1 , bench "U.Vector Int 30" $ nf encodeVector vec2 , bench "U.Vector Int 300" $ nf encodeVector vec3 , bench "U.Vector Int 30000" $ nf encodeVector vec4 , bench "U.Vector Int 300000" $ nf encodeVector vec5 ] , bgroup "decode" [ benchGetSize "size=3" bs1 , benchGetSize "size=30" bs2 , benchGetSize "size=300" bs3 , benchGetSize "size=30000" bs4 , benchGetSize "size=300000" bs5 ] ] vector-binary-instances-0.2.3.5/test/0000755000000000000000000000000013073205763015603 5ustar0000000000000000vector-binary-instances-0.2.3.5/test/Main.hs0000644000000000000000000000135413073205763017026 0ustar0000000000000000{-# LANGUAGE ScopedTypeVariables #-} import Test.Tasty import Test.Tasty.QuickCheck import Data.Binary import Data.Vector.Binary import qualified Data.Vector as V import qualified Data.Vector.Generic as VG import qualified Data.Vector.Unboxed as VU import qualified Data.Vector.Storable as VS roundTrip :: forall v a. (Eq (v a), Binary (v a), VG.Vector v a) => v a -> Property roundTrip v = let v' = decode $ encode v :: v a in property $ v' == v main = defaultMain $ testGroup "Vector Binary instances" [ testProperty "Unboxed" $ roundTrip $ VU.enumFromTo z 100 , testProperty "Storable" $ roundTrip $ VS.enumFromTo z 100 , testProperty "Boxed" $ roundTrip $ V.enumFromTo z 100 ] where z = 0 :: Int