@@ -769,23 +769,13 @@ foldr f z arr = runIdentity $ D.foldr f z $ toStreamD arr
769{-# INLINE_NORMAL writeNAllocWith #-}
769{-# INLINE_NORMAL writeNAllocWith #-}
770writeNAllocWith :: forall m a. (MonadIO m, Storable a)
770writeNAllocWith :: forall m a. (MonadIO m, Storable a)
771 => (Int -> m (Array a)) -> Int -> Fold m a (Array a)
771 => (Int -> m (Array a)) -> Int -> Fold m a (Array a)
772−writeNAllocWith alloc n = Fold step initial extract
772+writeNAllocWith alloc n = FL.take n (writeNUnsafeWith alloc n)
776− initial = FL.Partial <$> alloc (max n 0)
777− step arr@(Array _ end bound) _ | end == bound = return $ FL.Done arr
778− step (Array start end bound) x = do
780− return $ FL.Partial $ Array start (end `plusPtr` sizeOf (undefined :: a)) bound
781− -- XXX note that shirkToFit does not maintain alignment, in case we are
782− -- using aligned allocation.
783− extract = return -- liftIO . shrinkToFit
785-- | @writeN n@ folds a maximum of @n@ elements from the input stream to an
774-- | @writeN n@ folds a maximum of @n@ elements from the input stream to an
786-- 'Array'.
775-- 'Array'.
777+-- >>> import qualified Streamly.Data.Fold as Fold
788−-- @writeN n = Fold.take n writeNUnsafe@
778+-- >>> writeN n = Fold.take n (writeNUnsafe n)
790-- @since 0.7.0
780-- @since 0.7.0
791{-# INLINE_NORMAL writeN #-}
781{-# INLINE_NORMAL writeN #-}
@@ -819,22 +809,21 @@ data ArrayUnsafe a = ArrayUnsafe
819 {-# UNPACK #-} !(ForeignPtr a) -- first address
809 {-# UNPACK #-} !(ForeignPtr a) -- first address
820 {-# UNPACK #-} !(Ptr a) -- first unused address
810 {-# UNPACK #-} !(Ptr a) -- first unused address
822−-- | Like 'writeN' but does not check the array bounds when writing. The fold
812+-- XXX We can carry bound as well in the state to make sure we do not lose the
823−-- driver must not call the step function more than 'n' times otherwise it will
813+-- remaining capacity. Need to check perf impact.
824−-- corrupt the memory and crash. This function exists mainly because any
825−-- conditional in the step function blocks fusion causing 10x performance
828−-- @since 0.7.0
815+-- | This API is only useful when we do not want to use the remaining space in
816+-- the array to append anything else later as that space is lost.
829−{-# INLINE_NORMAL writeNUnsafe #-}
818+{-# INLINE_NORMAL writeNUnsafeWith #-}
830−writeNUnsafe :: forall m a. (MonadIO m, Storable a)
819+writeNUnsafeWith :: forall m a. (MonadIO m, Storable a)
831− => Int -> Fold m a (Array a)
820+ => (Int -> m (Array a)) -> Int -> Fold m a (Array a)
832−writeNUnsafe n = Fold step initial extract
821+writeNUnsafeWith alloc n = Fold step initial extract
836 initial = do
825 initial = do
837− (Array start end _) <- liftIO $ newArray (max n 0)
826+ (Array start end _) <- alloc (max n 0)
838 return $ FL.Partial $ ArrayUnsafe start end
827 return $ FL.Partial $ ArrayUnsafe start end
840 step (ArrayUnsafe start end) x = do
829 step (ArrayUnsafe start end) x = do
@@ -845,6 +834,18 @@ writeNUnsafe n = Fold step initial extract
846 extract (ArrayUnsafe start end) = return $ Array start end end -- liftIO . shrinkToFit
835 extract (ArrayUnsafe start end) = return $ Array start end end -- liftIO . shrinkToFit
837+-- | Like 'writeN' but does not check the array bounds when writing. The fold
838+-- driver must not call the step function more than 'n' times otherwise it will
839+-- corrupt the memory and crash. This function exists mainly because any
840+-- conditional in the step function blocks fusion causing 10x performance
844+{-# INLINE_NORMAL writeNUnsafe #-}
845+writeNUnsafe :: forall m a. (MonadIO m, Storable a)
846+ => Int -> Fold m a (Array a)
847+writeNUnsafe = writeNUnsafeWith newArray
848-- XXX Buffer to a list instead?
849-- XXX Buffer to a list instead?
850-- | Buffer a stream into a stream of arrays.
851-- | Buffer a stream into a stream of arrays.