@@ -54,9 +54,10 @@ import Control.Monad.Catch (MonadCatch)
54import Control.Monad.IO.Class (MonadIO(..))
54import Control.Monad.IO.Class (MonadIO(..))
55import Control.Monad.Trans.Class (lift)
55import Control.Monad.Trans.Class (lift)
56import Control.Monad.Trans.State.Strict (get, put)
56import Control.Monad.Trans.State.Strict (get, put)
57−-- import Data.Hashable (Hashable)
57+import Data.Function ((&))
58import Data.IORef (newIORef, readIORef, modifyIORef')
58import Data.IORef (newIORef, readIORef, modifyIORef')
59import Data.Kind (Type)
59import Data.Kind (Type)
60+import Data.Maybe (isJust)
60#if !(MIN_VERSION_base(4,11,0))
61#if !(MIN_VERSION_base(4,11,0))
61import Data.Semigroup (Semigroup(..))
62import Data.Semigroup (Semigroup(..))
@@ -70,6 +71,7 @@ import Streamly.Internal.Data.Time.Units (NanoSecond64(..), toRelTime64)
70import qualified Data.List as List
71import qualified Data.List as List
71import qualified Data.Map.Strict as Map
72import qualified Data.Map.Strict as Map
72import qualified Streamly.Internal.Data.Array as Array
73import qualified Streamly.Internal.Data.Array as Array
74+import qualified Streamly.Internal.Data.Array.Foreign.Mut.Type as MA
73import qualified Streamly.Internal.Data.Fold as Fold
75import qualified Streamly.Internal.Data.Fold as Fold
74import qualified Streamly.Internal.Data.Parser as Parser
76import qualified Streamly.Internal.Data.Parser as Parser
75import qualified Streamly.Internal.Data.Stream.IsStream.Lift as Stream
77import qualified Streamly.Internal.Data.Stream.IsStream.Lift as Stream
@@ -443,17 +445,29 @@ joinOuter :: MonadIO m =>
443 -> SerialT m (Maybe a, Maybe b)
445 -> SerialT m (Maybe a, Maybe b)
444joinOuter eq s1 s =
446joinOuter eq s1 s =
445 Stream.concatM $ do
447 Stream.concatM $ do
446− arr <- Array.fromStream $ fmap (,False) s
448+ inputArr <- Array.fromStream s
449+ let len = length inputArr
453+ (Stream.fromList (Prelude.replicate len False))
447− return $ go arr <> leftOver arr
454+ return $ go inputArr foundArr <> leftOver inputArr foundArr
451− leftOver =
458+ leftOver inputArr foundArr =
452− fmap (\(x, _) -> (Nothing, Just x))
453− . Stream.filter (not . snd)
454− . Array.toStream
459+ let stream1 = IsStream.fromSerial $ Array.toStream inputArr
455−
460+ stream2 = Stream.unfold MA.read foundArr
463+ ( Stream.zipWith (\x y ->
466+ else Just (Nothing, Just x)
468+ ) & Stream.catMaybes
456− go arr = Stream.evalStateT (return False) $ do
470+ go inputArr foundArr = Stream.evalStateT (return False) $ do
457 a <- Stream.liftInner s1
471 a <- Stream.liftInner s1
458 -- XXX should we use StreamD monad here?
472 -- XXX should we use StreamD monad here?
459 -- XXX Is there a better way to perform some action at the end of a loop
473 -- XXX Is there a better way to perform some action at the end of a loop
@@ -464,16 +478,16 @@ joinOuter eq s1 s =
465 then Stream.nil
479 then Stream.nil
466 else Stream.fromPure Nothing
480 else Stream.fromPure Nothing
467− (_i, b) <-
481+ (i, b) <-
468− let stream = IsStream.fromSerial $ Array.toStream arr
482+ let stream = IsStream.fromSerial $ Array.toStream inputArr
469 in Stream.indexed $ fmap Just (Stream.liftInner stream) <> final
483 in Stream.indexed $ fmap Just (Stream.liftInner stream) <> final
470 case b of
485 case b of
471− Just (b1, _used) ->
486+ Just b1 ->
472 if a `eq` b1
487 if a `eq` b1
474 lift $ put True
489 lift $ put True
475− -- XXX Need to use a mutable array
490+ MA.putIndex i True foundArr
476− -- when (not used) $ Array.writeIndex i True
477 return (Just a, Just b1)
491 return (Just a, Just b1)
478 else Stream.nil
492 else Stream.nil
479 Nothing -> return (Just a, Nothing)
493 Nothing -> return (Just a, Nothing)