@@ -67,6 +67,7 @@ module Streamly.Memory.Array.Types
68 , writeNUnsafe
68 , writeNUnsafe
@@ -300,14 +301,13 @@ snoc arr@Array {..} x = do
301-- | Reallocate the array to the specified size in bytes. If the size is less
302-- | Reallocate the array to the specified size in bytes. If the size is less
302-- than the original array the array gets truncated.
303-- than the original array the array gets truncated.
303−{-# NOINLINE realloc #-}
304+{-# NOINLINE reallocAligned #-}
304−realloc :: forall a. Storable a => Int -> Array a -> IO (Array a)
305+reallocAligned :: Int -> Int -> Array a -> IO (Array a)
305−realloc newSize Array{..} = do
306+reallocAligned alignSize newSize Array{..} = do
306 assert (aEnd <= aBound) (return ())
307 assert (aEnd <= aBound) (return ())
307 let oldStart = unsafeForeignPtrToPtr aStart
308 let oldStart = unsafeForeignPtrToPtr aStart
308 let size = aEnd `minusPtr` oldStart
309 let size = aEnd `minusPtr` oldStart
309− newPtr <- Malloc.mallocForeignPtrAlignedBytes
310+ newPtr <- Malloc.mallocForeignPtrAlignedBytes newSize alignSize
310− newSize (alignment (undefined :: a))
311 withForeignPtr newPtr $ \pNew -> do
311 withForeignPtr newPtr $ \pNew -> do
312 memcpy (castPtr pNew) (castPtr oldStart) size
312 memcpy (castPtr pNew) (castPtr oldStart) size
313 touchForeignPtr aStart
313 touchForeignPtr aStart
@@ -317,6 +317,10 @@ realloc newSize Array{..} = do
317 , aBound = pNew `plusPtr` newSize
317 , aBound = pNew `plusPtr` newSize
320+{-# INLINABLE realloc #-}
321+realloc :: forall a. Storable a => Int -> Array a -> IO (Array a)
322+realloc = reallocAligned (alignment (undefined :: a))
320-- | Remove the free space from an Array.
324-- | Remove the free space from an Array.
321shrinkToFit :: forall a. Storable a => Array a -> IO (Array a)
325shrinkToFit :: forall a. Storable a => Array a -> IO (Array a)
322shrinkToFit arr@Array{..} = do
326shrinkToFit arr@Array{..} = do
@@ -574,9 +578,9 @@ writeNUnsafe n = Fold step initial extract
575{-# INLINE_NORMAL toArrayMinChunk #-}
579{-# INLINE_NORMAL toArrayMinChunk #-}
576toArrayMinChunk :: forall m a. (MonadIO m, Storable a)
580toArrayMinChunk :: forall m a. (MonadIO m, Storable a)
577− => Int -> Fold m a (Array a)
581+ => Int -> Int -> Fold m a (Array a)
578-- toArrayMinChunk n = FL.mapM spliceArrays $ toArraysOf n
582-- toArrayMinChunk n = FL.mapM spliceArrays $ toArraysOf n
579−toArrayMinChunk elemCount = Fold step initial extract
583+toArrayMinChunk alignSize elemCount = Fold step initial extract
@@ -591,7 +595,7 @@ toArrayMinChunk elemCount = Fold step initial extract
591 let p = unsafeForeignPtrToPtr start
595 let p = unsafeForeignPtrToPtr start
592 oldSize = end `minusPtr` p
596 oldSize = end `minusPtr` p
593 newSize = max (oldSize * 2) 1
597 newSize = max (oldSize * 2) 1
594− arr1 <- liftIO $ realloc newSize arr
598+ arr1 <- liftIO $ reallocAligned alignSize newSize arr
595 insertElem arr1 x
599 insertElem arr1 x
596 step arr x = insertElem arr x
600 step arr x = insertElem arr x
597 extract = liftIO . shrinkToFit
601 extract = liftIO . shrinkToFit
@@ -603,9 +607,25 @@ toArrayMinChunk elemCount = Fold step initial extract
603-- @since 0.7.0
607-- @since 0.7.0
604{-# INLINE write #-}
608{-# INLINE write #-}
605write :: forall m a. (MonadIO m, Storable a) => Fold m a (Array a)
609write :: forall m a. (MonadIO m, Storable a) => Fold m a (Array a)
610+write = toArrayMinChunk (alignment (undefined :: a))
606−write = toArrayMinChunk (bytesToElemCount (undefined :: a)
611+ (bytesToElemCount (undefined :: a)
607 (mkChunkSize 1024))
612 (mkChunkSize 1024))
614+-- | Like 'write' but the array memory is aligned according to the specified
615+-- alignment size. This could be useful when we have specific alignment, for
616+-- example, cache aligned arrays for lookup table etc.
618+-- /Caution! Do not use this on infinite streams./
621+{-# INLINE writeAligned #-}
622+writeAligned :: forall m a. (MonadIO m, Storable a)
623+ => Int -> Fold m a (Array a)
624+writeAligned alignSize =
625+ toArrayMinChunk alignSize
626+ (bytesToElemCount (undefined :: a)
609{-# INLINE_NORMAL fromStreamDN #-}
629{-# INLINE_NORMAL fromStreamDN #-}
610fromStreamDN :: forall m a. (MonadIO m, Storable a)
630fromStreamDN :: forall m a. (MonadIO m, Storable a)
611 => Int -> D.Stream m a -> m (Array a)
631 => Int -> D.Stream m a -> m (Array a)