Commits

Bryan O'Sullivan committed 4a3620a

Simplify code, and ensure that tests are sane.

Comments (0)

Files changed (3)

Data/Text/Lazy/Search.hs

 import qualified Data.Text.Internal as T
 import qualified Data.Text as T
 import Data.Text.Fusion.Internal (PairS(..))
-import Data.Text.Lazy.Internal (Text(..))
+import Data.Text.Lazy.Internal (Text(..), foldlChunks)
 import Data.Bits ((.|.), (.&.))
 import Data.Text.UnsafeShift (shiftL)
 
     nlen      = wordLength needle
     nlast     = nlen - 1
     nindex    = index n ns
-    z         = foldChunks fin 0 needle
+    z         = foldlChunks fin 0 needle
         where fin _ (T.Text farr foff flen) = A.unsafeIndex farr (foff+flen-1)
     mask :*: skip = buildTable needle
     scanOne c i (T.Text oarr ooff olen) os = go 0
 swizzle :: Word16 -> Word64
 swizzle k = 1 `shiftL` (fromIntegral k .&. 0x3f)
 
-foldChunks :: (a -> T.Text -> a) -> a -> Text -> a
-foldChunks _ z Empty        = z
-foldChunks f z (Chunk c cs) = let z' = f z c
-                              in z' `seq` foldChunks f z' cs
-
 wordLength :: Text -> Int64
-wordLength = foldChunks sumLength 0
+wordLength = foldlChunks sumLength 0
     where sumLength i (T.Text _ _ l) = i + fromIntegral l
 
 buildTable :: Text -> PairS Word64 Int64
                         | otherwise = skip
                   xlast = xlen - 1
     nlen      = wordLength needle
-    z         = foldChunks fin 0 needle
+    z         = foldlChunks fin 0 needle
         where fin _ (T.Text farr foff flen) = A.unsafeIndex farr (foff+flen-1)

tests/Properties.hs

-{-# LANGUAGE BangPatterns, FlexibleInstances, ScopedTypeVariables,
-             TypeSynonymInstances #-}
+{-# LANGUAGE BangPatterns, FlexibleInstances, OverloadedStrings,
+             ScopedTypeVariables, TypeSynonymInstances #-}
 {-# OPTIONS_GHC -fno-enable-rewrite-rules #-}
 
 import Test.QuickCheck hiding (evaluate)
 t_zipWith c s     = L.zipWith c s `eqP` (unpackS . T.zipWith c (packS s))
 tl_zipWith c s    = L.zipWith c s `eqP` (unpackS . TL.zipWith c (packS s))
 
-slow_indices = unsquare (\s -> (map fromIntegral . Slow.indices (T.pack s)) `eq` (Slow.lazyIndices (TL.pack s) . TL.fromChunks . (:[])))
 t_indices = unsquare (\s -> Slow.indices s `eq` indices s)
-tl_indices = unsquare (\s -> Slow.lazyIndices s `eq` S.indices s)
+tl_indices = unsquare (\s -> lazyIndices s `eq` S.indices s)
+    where lazyIndices s t = map fromIntegral $ Slow.indices (conc s) (conc t)
+          conc = T.concat . TL.toChunks
 t_indices_occurs t = unsquare (\ts -> let s = T.intercalate t ts
                                       in Slow.indices t s == indices t s)
 
     testProperty "t_findIndex" t_findIndex,
     testProperty "t_count" t_count,
     testProperty "tl_count" tl_count,
-    testProperty "slow_indices" slow_indices,
     testProperty "t_indices" t_indices,
     testProperty "tl_indices" tl_indices,
     testProperty "t_indices_occurs" t_indices_occurs

tests/SlowFunctions.hs

 module SlowFunctions
     (
       indices
-    , lazyIndices
     , split
     ) where
 
-import Data.Int (Int64)
 import qualified Data.Text as T
-import qualified Data.Text.Lazy as L
 import Data.Text.Internal (Text(..))
 import Data.Text.Unsafe (iter_, unsafeHead, unsafeTail)
 
-indices :: Text                -- ^ Substring to search for (@needle@)
-        -> Text                -- ^ Text to search in (@haystack@)
+indices :: T.Text              -- ^ Substring to search for (@needle@)
+        -> T.Text              -- ^ Text to search in (@haystack@)
         -> [Int]
 indices needle@(Text _narr _noff nlen) haystack@(Text harr hoff hlen)
     | T.null needle = []
            where t = Text harr (hoff+i) (hlen-i)
                  d = iter_ haystack i
 
-lazyIndices :: L.Text -> L.Text -> [Int64]
-lazyIndices needle haystack
-    | L.null needle = []
-    | otherwise = scan 0 haystack
-  where
-    scan !i hay
-        | L.null hay                = []
-        | needle `L.isPrefixOf` hay = i : scan (i+n) (L.drop n hay)
-        | otherwise                 = scan (i+1) (L.tail hay)
-    n = L.length needle
-
-split :: Text                   -- ^ Text to split on
-      -> Text                   -- ^ Input text
-      -> [Text]
+split :: T.Text                 -- ^ Text to split on
+      -> T.Text                 -- ^ Input text
+      -> [T.Text]
 split pat src0
     | T.null pat  = error "split: empty"
     | l == 1      = T.splitBy (== (unsafeHead pat)) src0