{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE TypeFamilies #-} module HaskellWorks.Data.PackedVector.PackedVector64 ( PackedVector64(..) , empty , fromList , fromListN , toList ) where import Control.DeepSeq import Data.Int import Data.Word import GHC.Generics import HaskellWorks.Data.AtIndex import HaskellWorks.Data.Bits.BitWise import HaskellWorks.Data.Bits.LoBitsSized import HaskellWorks.Data.PackedVector.Internal import HaskellWorks.Data.Positioning import HaskellWorks.Data.Unsign import Prelude hiding (length) import qualified Data.Vector.Storable as DVS data PackedVector64 = PackedVector64 { swBuffer :: !(DVS.Vector Word64) , swBitSize :: !Word , swBufferLen :: !Int } deriving (Eq, Show, Generic) instance NFData PackedVector64 empty :: PackedVector64 empty = PackedVector64 { swBuffer = DVS.empty , swBufferLen = 0 , swBitSize = 1 } instance Container PackedVector64 where type Elem PackedVector64 = Word64 instance Length PackedVector64 where length = fromIntegral . swBufferLen {-# INLINE length #-} instance AtIndex PackedVector64 where atIndex v i = let bitSize = fromIntegral (swBitSize v) :: Count bitIndex = fromIntegral (swBitSize v) * i (q, r) = bitIndex `quotRem` 64 vv = swBuffer v in if r <= 64 - fromIntegral bitSize then -- Not crossing boundary ((vv !!! q) .>. unsign r) .&. loBitsSized bitSize else -- Crossing boundary let loBitsSize = 64 - toCount r hiBitsSize = bitSize - loBitsSize loBits = ((vv !!! q) .>. unsign r) .&. loBitsSized loBitsSize hiBits = (vv !!! (q + 1)) .&. loBitsSized hiBitsSize in loBits .|. (hiBits .<. loBitsSize) (!!!) = atIndex {-# INLINE (!!!) #-} {-# INLINE atIndex #-} fromList :: Count -> [Word64] -> PackedVector64 fromList wordLength ws = PackedVector64 { swBuffer = DVS.fromList (packBits wordLength ws) , swBufferLen = fromIntegral (length ws) , swBitSize = fromIntegral wordLength } fromListN :: Count -> Count -> [Word64] -> PackedVector64 fromListN vectorSize wordLength ws = PackedVector64 { swBuffer = DVS.fromListN (fromIntegral vectorSize) (packBits wordLength ws) , swBufferLen = fromIntegral (length ws) , swBitSize = fromIntegral wordLength } toList :: PackedVector64 -> [Word64] toList v = unpackBits (swBufferLen v) (fromIntegral (swBitSize v)) (DVS.toList (swBuffer v))