@@ -81,7 +81,7 @@ module Streamly.Memory.Array
81 -- Monadic APIs
81 -- Monadic APIs
82 -- , newArray
82 -- , newArray
83 , A.writeN -- drop new
83 , A.writeN -- drop new
84− , write -- full buffer
84+ , A.write -- full buffer
85 -- , writeLastN -- drop old (ring buffer)
85 -- , writeLastN -- drop old (ring buffer)
87 -- Stream Folds
87 -- Stream Folds
@@ -137,12 +137,9 @@ module Streamly.Memory.Array
140−import Control.Monad (when)
141import Control.Monad.IO.Class (MonadIO(..))
140import Control.Monad.IO.Class (MonadIO(..))
142-- import Data.Functor.Identity (Identity)
141-- import Data.Functor.Identity (Identity)
143import Foreign.ForeignPtr (withForeignPtr)
142import Foreign.ForeignPtr (withForeignPtr)
144−import Foreign.ForeignPtr.Unsafe (unsafeForeignPtrToPtr)
145−import Foreign.Ptr (minusPtr, plusPtr)
146import Foreign.Storable (Storable(..))
143import Foreign.Storable (Storable(..))
147import Prelude hiding (length, null, last, map, (!!), read, concat)
144import Prelude hiding (length, null, last, map, (!!), read, concat)
@@ -180,51 +177,6 @@ _writeNS n m = do
180 if n < 0 then error "writeN: negative write count specified" else return ()
177 if n < 0 then error "writeN: negative write count specified" else return ()
181 A.fromStreamDN n $ D.toStreamD m
178 A.fromStreamDN n $ D.toStreamD m
183−-- XXX The realloc based implementation needs to make one extra copy if we use
184−-- shrinkToFit. On the other hand, the stream of arrays implementation may
185−-- buffer the array chunk pointers in memory but it does not have to shrink as
186−-- we know the exact size in the end. However, memory copying does not seems to
187−-- be as expensive as the allocations. Therefore, we need to reduce the number
188−-- of allocations instead. Also, the size of allocations matters, right sizing
189−-- an allocation even at the cost of copying sems to help. Should be measured
190−-- on a big stream with heavy calls to toArray to see the effect.
192−-- XXX check if GHC's memory allocator is efficient enough. We can try the C
193−-- malloc to compare against.
195−{-# INLINE_NORMAL toArrayMinChunk #-}
196−toArrayMinChunk :: forall m a. (MonadIO m, Storable a)
197− => Int -> Fold m a (Array a)
198−-- toArrayMinChunk n = FL.mapM spliceArrays $ toArraysOf n
199−toArrayMinChunk elemCount = Fold step initial extract
203− insertElem (Array start end bound) x = do
205− return $ Array start (end `plusPtr` sizeOf (undefined :: a)) bound
208− when (elemCount < 0) $ error "toArrayMinChunk: elemCount is negative"
209− liftIO $ A.newArray elemCount
210− step arr@(Array start end bound) x | end == bound = do
211− let p = unsafeForeignPtrToPtr start
212− oldSize = end `minusPtr` p
213− newSize = max (oldSize * 2) 1
214− arr1 <- liftIO $ A.realloc newSize arr
216− step arr x = insertElem arr x
217− extract = liftIO . A.shrinkToFit
219−-- | Fold the whole input to a single array.
221−-- /Caution! Do not use this on infinite streams./
225−write :: forall m a. (MonadIO m, Storable a) => Fold m a (Array a)
226−write = toArrayMinChunk (A.bytesToElemCount (undefined :: a) (A.mkChunkSize 1024))
228-- | Create an 'Array' from a stream. This is useful when we want to create a
180-- | Create an 'Array' from a stream. This is useful when we want to create a
229-- single array from a stream of unknown size. 'writeN' is at least twice
181-- single array from a stream of unknown size. 'writeN' is at least twice
230-- as efficient when the size is already known.
182-- as efficient when the size is already known.
@@ -235,7 +187,7 @@ write = toArrayMinChunk (A.bytesToElemCount (undefined :: a) (A.mkChunkSize 1024
236{-# INLINE _writeS #-}
188{-# INLINE _writeS #-}
237_writeS :: (MonadIO m, Storable a) => SerialT m a -> m (Array a)
189_writeS :: (MonadIO m, Storable a) => SerialT m a -> m (Array a)
238−_writeS = P.runFold write
190+_writeS = P.runFold A.write
239-- write m = A.fromStreamD $ D.toStreamD m
191-- write m = A.fromStreamD $ D.toStreamD m
241-------------------------------------------------------------------------------
193-------------------------------------------------------------------------------
@@ -458,7 +410,7 @@ runPipe f arr = P.runPipe (toArrayMinChunk (length arr)) $ f (A.read arr)
458{-# INLINE _runTransform #-}
410{-# INLINE _runTransform #-}
459_runTransform :: (MonadIO m, Storable a, Storable b)
411_runTransform :: (MonadIO m, Storable a, Storable b)
460 => (SerialT m a -> SerialT m b) -> Array a -> m (Array b)
412 => (SerialT m a -> SerialT m b) -> Array a -> m (Array b)
461−_runTransform f arr = P.runFold (toArrayMinChunk (length arr)) $ f (A.read arr)
413+_runTransform f arr = P.runFold (A.toArrayMinChunk (length arr)) $ f (A.read arr)
463-- | Fold an array using a 'Fold'.
415-- | Fold an array using a 'Fold'.