@@ -388,63 +388,65 @@ fromStreamDArraysOf n str = D.groupsOf n (toArrayN n) str
389-- XXX concatMap does not seem to have the best possible performance so we have
389-- XXX concatMap does not seem to have the best possible performance so we have
390-- a custom way to concat arrays.
390-- a custom way to concat arrays.
391+data FlattenState s a =
391−data CAState s a = CAParent s | CANested s (ForeignPtr a) (Ptr a) (Ptr a)
393+ | InnerLoop s (ForeignPtr a) (Ptr a) (Ptr a)
393{-# INLINE_NORMAL flattenArrays #-}
395{-# INLINE_NORMAL flattenArrays #-}
394flattenArrays :: forall m a. (Monad m, Storable a)
396flattenArrays :: forall m a. (Monad m, Storable a)
395 => D.Stream m (Array a) -> D.Stream m a
397 => D.Stream m (Array a) -> D.Stream m a
396−flattenArrays (D.Stream step state) = D.Stream step' (CAParent state)
398+flattenArrays (D.Stream step state) = D.Stream step' (OuterLoop state)
400 {-# INLINE_LATE step' #-}
402 {-# INLINE_LATE step' #-}
401− step' gst (CAParent st) = do
403+ step' gst (OuterLoop st) = do
402 r <- step (adaptState gst) st
404 r <- step (adaptState gst) st
403 return $ case r of
405 return $ case r of
404 D.Yield Array{..} s ->
406 D.Yield Array{..} s ->
405 let p = unsafeForeignPtrToPtr aStart
407 let p = unsafeForeignPtrToPtr aStart
406− in D.Skip (CANested s aStart p aEnd)
408+ in D.Skip (InnerLoop s aStart p aEnd)
407− D.Skip s -> D.Skip (CAParent s)
409+ D.Skip s -> D.Skip (OuterLoop s)
408 D.Stop -> D.Stop
410 D.Stop -> D.Stop
410− step' _ (CANested st _ p end) | p == end =
412+ step' _ (InnerLoop st _ p end) | p == end =
411− return $ D.Skip $ CAParent st
413+ return $ D.Skip $ OuterLoop st
413− step' _ (CANested st startf p end) = do
415+ step' _ (InnerLoop st startf p end) = do
414 let !x = unsafeInlineIO $ do
416 let !x = unsafeInlineIO $ do
415 r <- peek p
417 r <- peek p
416 touchForeignPtr startf
418 touchForeignPtr startf
418− return $ D.Yield x (CANested st startf
420+ return $ D.Yield x (InnerLoop st startf
419 (p `plusPtr` (sizeOf (undefined :: a))) end)
421 (p `plusPtr` (sizeOf (undefined :: a))) end)
421{-# INLINE_NORMAL flattenArraysRev #-}
423{-# INLINE_NORMAL flattenArraysRev #-}
422flattenArraysRev :: forall m a. (Monad m, Storable a)
424flattenArraysRev :: forall m a. (Monad m, Storable a)
423 => D.Stream m (Array a) -> D.Stream m a
425 => D.Stream m (Array a) -> D.Stream m a
424−flattenArraysRev (D.Stream step state) = D.Stream step' (CAParent state)
426+flattenArraysRev (D.Stream step state) = D.Stream step' (OuterLoop state)
428 {-# INLINE_LATE step' #-}
430 {-# INLINE_LATE step' #-}
429− step' gst (CAParent st) = do
431+ step' gst (OuterLoop st) = do
430 r <- step (adaptState gst) st
432 r <- step (adaptState gst) st
431 return $ case r of
433 return $ case r of
432 D.Yield Array{..} s ->
434 D.Yield Array{..} s ->
433 let p = aEnd `plusPtr` negate (sizeOf (undefined :: a))
435 let p = aEnd `plusPtr` negate (sizeOf (undefined :: a))
434 -- XXX we do not need aEnd
436 -- XXX we do not need aEnd
435− in D.Skip (CANested s aStart p aEnd)
437+ in D.Skip (InnerLoop s aStart p aEnd)
436− D.Skip s -> D.Skip (CAParent s)
438+ D.Skip s -> D.Skip (OuterLoop s)
437 D.Stop -> D.Stop
439 D.Stop -> D.Stop
439− step' _ (CANested st start p _) | p < unsafeForeignPtrToPtr start =
441+ step' _ (InnerLoop st start p _) | p < unsafeForeignPtrToPtr start =
440− return $ D.Skip $ CAParent st
442+ return $ D.Skip $ OuterLoop st
442− step' _ (CANested st startf p end) = do
444+ step' _ (InnerLoop st startf p end) = do
443 let !x = unsafeInlineIO $ do
445 let !x = unsafeInlineIO $ do
444 r <- peek p
446 r <- peek p
445 touchForeignPtr startf
447 touchForeignPtr startf
447− return $ D.Yield x (CANested st startf
449+ return $ D.Yield x (InnerLoop st startf
448 (p `plusPtr` negate (sizeOf (undefined :: a))) end)
450 (p `plusPtr` negate (sizeOf (undefined :: a))) end)
450-- CAUTION: a very large number (millions) of arrays can degrade performance
452-- CAUTION: a very large number (millions) of arrays can degrade performance