vector-mmap-0.0.3: Data/Vector/Storable/MMap.hs
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
module Data.Vector.Storable.MMap (
System.IO.MMap.Mode(..),
unsafeMMapMVector,
unsafeMMapVector,
writeMMapVector
) where
import System.IO.MMap
import Foreign.Storable
import qualified Data.Vector.Storable as I
import qualified Data.Vector.Storable.Mutable as M
import qualified Data.Vector.Generic as G
import Data.Int
import Control.Monad
import Control.Monad.Primitive
-- | Map a file into memory as a mutable vector.
unsafeMMapMVector :: forall a. Storable a => FilePath -- ^ Path of the file to map
-> Mode -- ^ Mapping mode
-> Maybe (Int64, Int) -- ^ 'Nothing' to map entire file into memory, otherwise 'Just (fileOffset, elementCount)'
-> IO (M.MVector (PrimState IO) a)
unsafeMMapMVector path mode range =
do (foreignPtr, offset, size) <- mmapFileForeignPtr path mode $
case range of
Nothing -> Nothing
Just (start, length) -> Just (start, length * sizeOf (undefined :: a))
return $ M.unsafeFromForeignPtr foreignPtr offset (size `div` sizeOf (undefined :: a))
-- | Map a file into memory ('ReadOnly' mode) as an immutable vector.
unsafeMMapVector :: forall a. Storable a => FilePath -- ^ Path of the file to map
-> Maybe (Int64, Int) -- ^ 'Nothing' to map entire file into memory, otherwise 'Just (fileOffset, elementCount)'
-> IO (I.Vector a)
unsafeMMapVector path range =
do (foreignPtr, offset, size) <- mmapFileForeignPtr path ReadOnly $
case range of
Nothing -> Nothing
Just (start, length) -> Just (start, length * sizeOf (undefined :: a))
return $ I.unsafeFromForeignPtr foreignPtr offset (size `div` sizeOf (undefined :: a))
-- | Write a file from a vector
-- Be careful with existing files, parts behind the mapped range will stay
-- as they are before the write operation.
writeMMapVector :: forall v a. (Storable a, G.Vector v a)
=> FilePath -- ^ Path of the file to map
-> v a -- ^ Vector to write
-> IO ()
writeMMapVector path src = do
let len = G.length src
target <- unsafeMMapMVector path ReadWriteEx (Just (0,len))
I.copy target (G.convert src)
{-# INLINABLE writeMMapVector #-}