1
1
mirror of https://github.com/github/semantic.git synced 2024-12-01 00:33:59 +03:00

Rewrite with elemIndex

Should be a bit faster b/c elemIndex uses memchr(3) under the covers.
This commit is contained in:
Timothy Clem 2017-11-17 08:02:14 -08:00
parent 891a32f7d1
commit ddb8c4f3b1

View File

@ -110,20 +110,20 @@ sourceLineRangesWithin range = uncurry (zipWith Range)
. sourceBytes
. slice range
-- | Return all indices of newlines ('\n', '\r', '\r\n') in the 'ByteString'.
-- | Return all indices of newlines ('\n', '\r', and '\r\n') in the 'ByteString'.
newlineIndices :: B.ByteString -> [Int]
newlineIndices = loop 0
where
loop i bytes = case B.uncons bytes of
Nothing -> []
Just (b, bs) | isLF b -> i : loop (succ i) bs
| isCR b -> case B.uncons bs of
Nothing -> loop (succ i) bs
Just (b', bs') | isLF b' -> succ i : loop (succ (succ i)) bs'
| otherwise -> i : loop (succ i) bs
| otherwise -> loop (succ i) bs
isLF = (== toEnum (ord '\n'))
isCR = (== toEnum (ord '\r'))
newlineIndices = go 0
where go n bs | B.null bs = []
| otherwise = case (searchCR bs, searchLF bs) of
(Nothing, Nothing) -> []
(Just i, Nothing) -> recur n i bs
(Nothing, Just i) -> recur n i bs
(Just crI, Just lfI)
| succ crI == lfI -> recur n lfI bs
| otherwise -> recur n (min crI lfI) bs
recur n i bs = let j = n + i in j : go (succ j) (B.drop (succ i) bs)
searchLF = B.elemIndex (toEnum (ord '\n'))
searchCR = B.elemIndex (toEnum (ord '\r'))
{-# INLINE newlineIndices #-}