on master help sign in
Bug fix in StreamD.splitOnSeq karp-rabin match
e49a37dadithyaov
src/Streamly/Internal/Data/Stream/StreamD.hs+16−22
@@ -1801,6 +1801,7 @@ data SplitOnSeqState rb rh ck w fs s b x =
1801
1801
1802 | SplitOnSeqKRInit Int s rb !rh
1802 | SplitOnSeqKRInit Int s rb !rh
1803 | SplitOnSeqKRLoop fs s rb !rh !ck
1803 | SplitOnSeqKRLoop fs s rb !rh !ck
1804+ | SplitOnSeqKRCheck fs s rb !rh
1804 | SplitOnSeqKRDone Int !fs rb !rh
1805 | SplitOnSeqKRDone Int !fs rb !rh
1805
1806
1806{-# INLINE_NORMAL splitOnSeq #-}
1807{-# INLINE_NORMAL splitOnSeq #-}
@@ -1983,27 +1984,15 @@ splitOnSeq patArr (Fold fstep initial done) (Stream step state) =
1983 then do
1984 then do
1984 let fold = RB.unsafeFoldRing (RB.ringBound rb)
1985 let fold = RB.unsafeFoldRing (RB.ringBound rb)
1985 let !ringHash = fold addCksum 0 rb
1986 let !ringHash = fold addCksum 0 rb
1987+ fs <- initial
1986 if ringHash == patHash
1988 if ringHash == patHash
1987− then do
1989+ then skip $ SplitOnSeqKRCheck fs s rb rh1
1988− r <- initial >>= done
1989− let next = SplitOnSeqKRInit 0 s rb rh1
1990− -- XXX We need a direct yield here otherwise GHC is not
1991− -- able to fuse the code. This GHC issue needs to be
1992− -- investigated. We should know why.
1993− return $ Yield r next
1994− else do
1995− fs <- initial
1996− skip $ SplitOnSeqKRLoop fs s rb rh1 ringHash
1990+ else skip $ SplitOnSeqKRLoop fs s rb rh1 ringHash
1997 else skip $ SplitOnSeqKRInit (idx + 1) s rb rh1
1991 else skip $ SplitOnSeqKRInit (idx + 1) s rb rh1
1998 Skip s -> skip $ SplitOnSeqKRInit idx s rb rh
1992 Skip s -> skip $ SplitOnSeqKRInit idx s rb rh
1999 Stop -> do
1993 Stop -> do
2000 fs <- initial
1994 fs <- initial
2001− let rh1 = RB.moveBy (0 - idx) rb (rh :: Ptr a)
1995+ skip $ SplitOnSeqKRDone idx fs rb (RB.startOf rb)
2002− if idx /= 0
2003− then skip $ SplitOnSeqKRDone idx fs rb rh1
2004− else do
2005− r <- done fs
2006− skip $ SplitOnSeqYield r SplitOnSeqDone
2007
1996
2008 -- XXX The recursive "go" is more efficient than the state based recursion
1997 -- XXX The recursive "go" is more efficient than the state based recursion
2009 -- code commented out below. Perhaps its more efficient because of
1998 -- code commented out below. Perhaps its more efficient because of
@@ -2021,13 +2010,10 @@ splitOnSeq patArr (Fold fstep initial done) (Stream step state) =
2021 old <- liftIO $ peek rh
2010 old <- liftIO $ peek rh
2022 let cksum1 = deltaCksum cksum old x
2011 let cksum1 = deltaCksum cksum old x
2023 fs1 <- fstep fs old
2012 fs1 <- fstep fs old
2013+ rh1 <- liftIO (RB.unsafeInsert rb rh x)
2024 if (cksum1 == patHash)
2014 if (cksum1 == patHash)
2025− then do
2015+ then skip $ SplitOnSeqKRCheck fs1 s rb rh1
2026− r <- done fs1
2027− skip $ SplitOnSeqYield r $ SplitOnSeqKRInit 0 s rb rh
2028− else do
2029− rh1 <- liftIO (RB.unsafeInsert rb rh x)
2030− go SPEC fs1 s rh1 cksum1
2016+ else go SPEC fs1 s rh1 cksum1
2031 Skip s -> go SPEC fs s rh cksum
2017 Skip s -> go SPEC fs s rh cksum
2032 Stop -> skip $ SplitOnSeqKRDone patLen fs rb rh
2018 Stop -> skip $ SplitOnSeqKRDone patLen fs rb rh
2033
2019
@@ -2056,6 +2042,14 @@ splitOnSeq patArr (Fold fstep initial done) (Stream step state) =
2056 Skip s -> skip $ SplitOnSeqKRLoop fs s rb rh cksum
2042 Skip s -> skip $ SplitOnSeqKRLoop fs s rb rh cksum
2057 Stop -> skip $ SplitOnSeqKRDone patLen fs rb rh
2043 Stop -> skip $ SplitOnSeqKRDone patLen fs rb rh
2058 -}
2044 -}
2045+
2046+ stepOuter _ (SplitOnSeqKRCheck fs st rb rh) = do
2047+ if RB.unsafeEqArray rb rh patArr
2048+ then do
2049+ r <- done fs
2050+ let next = SplitOnSeqKRInit 0 st rb (RB.startOf rb)
2051+ skip $ SplitOnSeqYield r next
2052+ else skip $ SplitOnSeqKRLoop fs st rb rh patHash
2059 stepOuter _ (SplitOnSeqKRDone 0 fs _ _) = do
2053 stepOuter _ (SplitOnSeqKRDone 0 fs _ _) = do
2060 r <- done fs
2054 r <- done fs
2061 skip $ SplitOnSeqYield r SplitOnSeqDone
2055 skip $ SplitOnSeqYield r SplitOnSeqDone