on master help sign in
Record a sort-of-working fast search.

--HG-- extra : convert_revision : 89f38e4b73631d7cad3bb71ad07341a045b93dfd

commit78449a3f5f608372eb77de082b8bc7a4ffc1bc49 authorBryan O'Sullivan <bos@serpentine.com> dateMon 24 Aug 2009, 05:17 (17 years ago) parent709916e
3 files changed+45−2
Data/Text/Search.hs+44 Data/Text/UnsafeShift.hs−2 text.cabal+1
Data/Text/Search.hsnew file+44
@@ -0,0 +1,44 @@
1+{-# LANGUAGE BangPatterns, ScopedTypeVariables #-}
2+
3+module Data.Text.Search where
4+
5+import qualified Data.Text as T ()
6+import qualified Data.Text.Array as A
7+import Data.Word (Word64)
8+import Data.Text.Internal (Text(..))
9+import Data.Bits ((.|.), (.&.))
10+import Data.Text.UnsafeShift (shiftL)
11+
12+indices :: Text -> Text -> [Int]
13+indices _needle@(Text narr noff nlen) _haystack@(Text harr hoff hlen)
14+ | ldiff < 0 = []
15+ | otherwise = outer 0
16+ where
17+ ldiff = hlen - nlen
18+ nlast = nlen - 1
19+ z = nindex nlast
20+ nindex k = A.unsafeIndex narr (noff+k)
21+ hindex k = A.unsafeIndex harr (hoff+k)
22+ (mask :: Word64, skip :: Int) = buildTable 0 0 (nlen-2)
23+ buildTable !i !msk !skp
24+ | i >= nlast = (msk .|. swizzle z, skp)
25+ | otherwise = buildTable (i+1) (msk .|. swizzle c) skp'
26+ where c = nindex i
27+ skp' | c == z = nlen - i - 2
28+ | otherwise = skp
29+ swizzle k = 1 `shiftL` (fromEnum k .&. 0x3f)
30+ outer !i
31+ | i > ldiff = []
32+ | c == z = if candidateMatch 0
33+ then i : outer (i + nlast)
34+ else if nextInPattern
35+ then outer (i + nlen)
36+ else outer (i + skip)
37+ | nextInPattern = outer (i + nlen)
38+ | otherwise = outer (i + 1)
39+ where c = hindex (i+nlast)
40+ candidateMatch j
41+ | j >= nlast = True
42+ | hindex (i+j) /= nindex j = False
43+ | otherwise = candidateMatch (j+1)
44+ nextInPattern = (mask .&. swizzle (hindex (i+nlen))) == 0
Data/Text/UnsafeShift.hs−2
@@ -45,14 +45,12 @@ instance UnsafeShift Word32 where
4545 {-# INLINE shiftR #-}
4646 shiftR (W32# x#) (I# i#) = W32# (x# `uncheckedShiftRL#` i#)
4747
48−{-
4948instance UnsafeShift Word64 where
5049 {-# INLINE shiftL #-}
5150 shiftL (W64# x#) (I# i#) = W64# (x# `uncheckedShiftL64#` i#)
5251
5352 {-# INLINE shiftR #-}
5453 shiftR (W64# x#) (I# i#) = W64# (x# `uncheckedShiftRL64#` i#)
55−-}
5654
5755instance UnsafeShift Int where
5856 {-# INLINE shiftL #-}
text.cabal+1
@@ -22,6 +22,7 @@ library
2222 Data.Text.Foreign
2323 Data.Text.Lazy
2424 Data.Text.Lazy.Encoding
25+ Data.Text.Search
2526 other-modules:
2627 Data.Text.Array
2728 Data.Text.Encoding.Fusion