1+ {-# LANGUAGE BangPatterns #-}
12{-# LANGUAGE MonadComprehensions #-}
23{-# LANGUAGE OverloadedStrings #-}
34{-# LANGUAGE ScopedTypeVariables #-}
@@ -15,6 +16,7 @@ import qualified Data.Aeson as J
1516import Data.Bifunctor (first , second )
1617import Data.ByteString.Char8 (ByteString )
1718import qualified Data.ByteString.Char8 as B
19+ import Data.ByteString.Internal (toForeignPtr , unsafeCreate , unsafeWithForeignPtr )
1820import qualified Data.ByteString.Lazy.Char8 as LB
1921import Data.IORef
2022import Data.Int (Int64 )
@@ -29,6 +31,8 @@ import qualified Data.Text as T
2931import Data.Text.Encoding (decodeUtf8With , encodeUtf8 )
3032import Data.Time (NominalDiffTime )
3133import Data.Tuple (swap )
34+ import Data.Word (Word8 )
35+ import Foreign.Storable (peekByteOff , pokeByteOff )
3236import GHC.Conc (labelThread , myThreadId , threadDelay )
3337import UnliftIO hiding (atomicModifyIORef' )
3438import qualified UnliftIO.Exception as UE
@@ -156,6 +160,27 @@ mapAccumLM_NonEmpty
156160mapAccumLM_NonEmpty f s (x :| xs) =
157161 [(s2, x' :| xs') | (s1, x') <- f s x, (s2, xs') <- mapAccumLM_List f s1 xs]
158162
163+ -- | Optimized from bytestring package for GHC 8.10.7 compatibility
164+ packZipWith :: (Word8 -> Word8 -> Word8 ) -> ByteString -> ByteString -> ByteString
165+ packZipWith f s1 s2 =
166+ unsafeCreate len $ \ r ->
167+ unsafeWithForeignPtr fp1 $ \ p1 ->
168+ unsafeWithForeignPtr fp2 $ \ p2 -> zipWith_ p1 p2 r
169+ where
170+ zipWith_ p1 p2 r = go 0
171+ where
172+ go :: Int -> IO ()
173+ go ! n
174+ | n >= len = pure ()
175+ | otherwise = do
176+ x <- peekByteOff p1 (off1 + n)
177+ y <- peekByteOff p2 (off2 + n)
178+ pokeByteOff r n (f x y)
179+ go (n + 1 )
180+ (fp1, off1, l1) = toForeignPtr s1
181+ (fp2, off2, l2) = toForeignPtr s2
182+ len = min l1 l2
183+
159184tryWriteTBQueue :: TBQueue a -> a -> STM Bool
160185tryWriteTBQueue q a = do
161186 full <- isFullTBQueue q
0 commit comments