on master help sign in
Fix joinOuter
commit1b8043f6ef862eb8842a5fc5f86ed146afcf81e6 authorRanjeet Kumar Ranjan <ranjeetr@composewell.com> dateSun 20 Mar 2022, 11:14 (5 years ago) parent4428641
2 files changed+30−19
src/Streamly/Internal/Data/Stream/IsStream/Top.hs+28−14 test/Streamly/Test/Prelude/Top.hs+2−5
src/Streamly/Internal/Data/Stream/IsStream/Top.hs+28−14
@@ -54,9 +54,10 @@ import Control.Monad.Catch (MonadCatch)
5454import Control.Monad.IO.Class (MonadIO(..))
5555import Control.Monad.Trans.Class (lift)
5656import Control.Monad.Trans.State.Strict (get, put)
57−-- import Data.Hashable (Hashable)
57+import Data.Function ((&))
5858import Data.IORef (newIORef, readIORef, modifyIORef')
5959import Data.Kind (Type)
60+import Data.Maybe (isJust)
6061#if !(MIN_VERSION_base(4,11,0))
6162import Data.Semigroup (Semigroup(..))
6263#endif
@@ -70,6 +71,7 @@ import Streamly.Internal.Data.Time.Units (NanoSecond64(..), toRelTime64)
7071import qualified Data.List as List
7172import qualified Data.Map.Strict as Map
7273import qualified Streamly.Internal.Data.Array as Array
74+import qualified Streamly.Internal.Data.Array.Foreign.Mut.Type as MA
7375import qualified Streamly.Internal.Data.Fold as Fold
7476import qualified Streamly.Internal.Data.Parser as Parser
7577import qualified Streamly.Internal.Data.Stream.IsStream.Lift as Stream
@@ -443,17 +445,29 @@ joinOuter :: MonadIO m =>
443445 -> SerialT m (Maybe a, Maybe b)
444446joinOuter eq s1 s =
445447 Stream.concatM $ do
446− arr <- Array.fromStream $ fmap (,False) s
447− return $ go arr <> leftOver arr
448+ inputArr <- Array.fromStream s
449+ let len = length inputArr
450+ foundArr <-
451+ Stream.fold
452+ (MA.writeN len)
453+ (Stream.fromList (Prelude.replicate len False))
454+ return $ go inputArr foundArr <> leftOver inputArr foundArr
448455
449456 where
450457
451− leftOver =
452− fmap (\(x, _) -> (Nothing, Just x))
453− . Stream.filter (not . snd)
454− . Array.toStream
455−
456− go arr = Stream.evalStateT (return False) $ do
458+ leftOver inputArr foundArr =
459+ let stream1 = IsStream.fromSerial $ Array.toStream inputArr
460+ stream2 = Stream.unfold MA.read foundArr
461+ in Stream.filter
462+ isJust
463+ ( Stream.zipWith (\x y ->
464+ if y
465+ then Nothing
466+ else Just (Nothing, Just x)
467+ ) stream1 stream2
468+ ) & Stream.catMaybes
469+
470+ go inputArr foundArr = Stream.evalStateT (return False) $ do
457471 a <- Stream.liftInner s1
458472 -- XXX should we use StreamD monad here?
459473 -- XXX Is there a better way to perform some action at the end of a loop
@@ -464,16 +478,16 @@ joinOuter eq s1 s =
464478 if r
465479 then Stream.nil
466480 else Stream.fromPure Nothing
467− (_i, b) <-
468− let stream = IsStream.fromSerial $ Array.toStream arr
481+ (i, b) <-
482+ let stream = IsStream.fromSerial $ Array.toStream inputArr
469483 in Stream.indexed $ fmap Just (Stream.liftInner stream) <> final
484+
470485 case b of
471− Just (b1, _used) ->
486+ Just b1 ->
472487 if a `eq` b1
473488 then do
474489 lift $ put True
475− -- XXX Need to use a mutable array
476− -- when (not used) $ Array.writeIndex i True
490+ MA.putIndex i True foundArr
477491 return (Just a, Just b1)
478492 else Stream.nil
479493 Nothing -> return (Just a, Nothing)
test/Streamly/Test/Prelude/Top.hs+2−5
@@ -85,8 +85,6 @@ joinOuterList ls0 ls1 =
8585 v4 = filter (\(_, a2, _) -> isNothing a2) v3
8686 in v2 ++ v4
8787
88−-- XXX A bug need to be fixed in joinOuter function
89−{-
9088joinOuter :: Property
9189joinOuter =
9290 forAll (listOf (chooseInt (min_value, max_value))) $ \ls0 ->
@@ -103,7 +101,7 @@ joinOuter =
103101 (map (\a -> (a, a)) ls1)
104102 v3 = map (\(_, v10, v20) -> (v10, v20)) v2
105103 assert (sort v1 == sort v3)
106−-}
104+
107105
108106joinOuterMap :: Property
109107joinOuterMap =
@@ -209,8 +207,7 @@ main = hspec $ do
209207 -- Joins
210208 prop "joinInner" Main.joinInner
211209 prop "joinInnerMap" Main.joinInnerMap
212− -- XXX currently API is broken https://github.com/composewell/streamly/issues/1032
213− --prop "joinOuter" Main.joinOuter
210+ prop "joinOuter" Main.joinOuter
214211 prop "joinOuterMap" Main.joinOuterMap
215212 prop "joinLeft" Main.joinLeft
216213 prop "joinLeftMap" Main.joinLeftMap