Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple issue resolution #2917

Merged
merged 2 commits into from
Jan 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions benchmark/Streamly/Benchmark/Unicode/Stream.hs
Original file line number Diff line number Diff line change
Expand Up @@ -264,10 +264,10 @@ _copyStreamUtf8' inh outh =
copyStreamUtf16 :: Handle -> Handle -> IO ()
copyStreamUtf16 inh outh =
Stream.fold (Handle.writeChunks outh)
$ fmap Array.castUnsafe $ Array.chunksOf (arrayPayloadSize (16 * 1024))
$ fmap Array.unsafeCast $ Array.chunksOf (arrayPayloadSize (16 * 1024))
$ Unicode.encodeUtf16le'
$ Unicode.decodeUtf16le
$ Array.concat $ fmap Array.castUnsafe $ Unicode.mkEvenW8Chunks
$ Array.concat $ fmap Array.unsafeCast $ Unicode.mkEvenW8Chunks
$ Handle.readChunks inh

#ifdef INSPECTION
Expand Down
1 change: 1 addition & 0 deletions core/src/DocTestDataUnfold.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
>>> :m
>>> import Streamly.Data.Unfold (Unfold)
>>> import qualified Streamly.Data.Fold as Fold
>>> import qualified Streamly.Data.Scanl as Scanl
>>> import qualified Streamly.Data.Stream as Stream
>>> import qualified Streamly.Data.Unfold as Unfold
Expand Down
23 changes: 14 additions & 9 deletions core/src/Streamly/Internal/Data/Array.hs
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ module Streamly.Internal.Data.Array
-- * Casting
, cast
, asBytes
, castUnsafe
, unsafeCast
, asCStringUnsafe

-- * Subarrays
, getSliceUnsafe
, unsafeGetSlice
-- , getSlice
, sliceIndexerFromLen
, slicerFromLen
Expand Down Expand Up @@ -89,6 +89,8 @@ module Streamly.Internal.Data.Array
, deserialize

-- * Deprecated
, castUnsafe
, getSliceUnsafe
, pinnedSerialize
, genSlicesFromLen
, getSlicesFromLen
Expand Down Expand Up @@ -294,19 +296,21 @@ find = Unfold.fold Fold.null . Stream.unfold (indexFinder p)
-- /Unsafe/
--
-- /Pre-release/
{-# INLINE getSliceUnsafe #-}
getSliceUnsafe ::
{-# INLINE unsafeGetSlice #-}
unsafeGetSlice, getSliceUnsafe ::
forall a. Unbox a
=> Int -- ^ starting index
-> Int -- ^ length of the slice
-> Array a
-> Array a
getSliceUnsafe index len (Array contents start e) =
unsafeGetSlice index len (Array contents start e) =
let size = SIZE_OF(a)
start1 = start + (index * size)
end1 = start1 + (len * size)
in assert (end1 <= e) (Array contents start1 end1)

RENAME(getSliceUnsafe,unsafeGetSlice)

-- | Split the array into a stream of slices using a predicate. The element
-- matching the predicate is dropped.
--
Expand Down Expand Up @@ -466,19 +470,20 @@ streamTransform f arr =
--
-- /Pre-release/
--
castUnsafe ::
unsafeCast, castUnsafe ::
#ifdef DEVBUILD
Unbox b =>
#endif
Array a -> Array b
castUnsafe (Array contents start end) =
unsafeCast (Array contents start end) =
Array contents start end
RENAME(castUnsafe,unsafeCast)

-- | Cast an @Array a@ into an @Array Word8@.
--
--
asBytes :: Array a -> Array Word8
asBytes = castUnsafe
asBytes = unsafeCast

-- | Cast an array having elements of type @a@ into an array having elements of
-- type @b@. The length of the array should be a multiple of the size of the
Expand All @@ -491,7 +496,7 @@ cast arr =
r = len `mod` SIZE_OF(b)
in if r /= 0
then Nothing
else Just $ castUnsafe arr
else Just $ unsafeCast arr

-- | Convert an array of any type into a null terminated CString Ptr. If the
-- array is unpinned it is first converted to a pinned array which requires a
Expand Down
34 changes: 22 additions & 12 deletions core/src/Streamly/Internal/Data/Array/Generic.hs
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,22 @@ module Streamly.Internal.Data.Array.Generic
, fold

-- * Random Access
, getIndexUnsafe
, unsafeGetIndex
, getIndex
, getSliceUnsafe
, unsafeGetSlice
, strip

-- * Deprecated
, getIndexUnsafe
, getSliceUnsafe
, writeN
, write
, fromByteStr#
)
where

#include "inline.hs"
#include "deprecation.h"

import Control.Monad (replicateM)
import Control.Monad.IO.Class (MonadIO)
Expand Down Expand Up @@ -206,17 +209,17 @@ toList arr = loop 0

len = length arr
loop i | i == len = []
loop i = getIndexUnsafe i arr : loop (i + 1)
loop i = unsafeGetIndex i arr : loop (i + 1)

{-# INLINE_NORMAL read #-}
read :: Monad m => Array a -> Stream m a
read arr =
D.map (`getIndexUnsafe` arr) $ D.enumerateFromToIntegral 0 (length arr - 1)
D.map (`unsafeGetIndex` arr) $ D.enumerateFromToIntegral 0 (length arr - 1)

{-# INLINE_NORMAL readRev #-}
readRev :: Monad m => Array a -> Stream m a
readRev arr =
D.map (`getIndexUnsafe` arr)
D.map (`unsafeGetIndex` arr)
$ D.enumerateFromThenToIntegral (arrLen - 1) (arrLen - 2) 0
where
arrLen = length arr
Expand Down Expand Up @@ -249,9 +252,9 @@ streamFold f arr = f (read arr)
-- not check the bounds.
--
-- @since 0.8.0
{-# INLINE getIndexUnsafe #-}
getIndexUnsafe :: Int -> Array a -> a
getIndexUnsafe i arr =
{-# INLINE unsafeGetIndex #-}
unsafeGetIndex, getIndexUnsafe :: Int -> Array a -> a
unsafeGetIndex i arr =
unsafePerformIO $ MArray.unsafeGetIndex i (unsafeThaw arr)

-- | Lookup the element at the given index. Index starts from 0.
Expand All @@ -260,7 +263,7 @@ getIndexUnsafe i arr =
getIndex :: Int -> Array a -> Maybe a
getIndex i arr =
if i >= 0 && i < length arr
then Just $ getIndexUnsafe i arr
then Just $ unsafeGetIndex i arr
else Nothing

-- >>> import qualified Streamly.Data.Stream as Stream
Expand All @@ -284,9 +287,9 @@ createOfLast n = FL.rmapM f (RB.createOf n)
arr <- RB.copyToMutArray 0 n rb
return $ unsafeFreeze arr

{-# INLINE getSliceUnsafe #-}
getSliceUnsafe :: Int -> Int -> Array a -> Array a
getSliceUnsafe offset len =
{-# INLINE unsafeGetSlice #-}
unsafeGetSlice, getSliceUnsafe :: Int -> Int -> Array a -> Array a
unsafeGetSlice offset len =
unsafeFreeze . MArray.unsafeGetSlice offset len . unsafeThaw

-- XXX This is not efficient as it copies the array. We should support array
Expand Down Expand Up @@ -346,3 +349,10 @@ instance Read a => Read (Array a) where
if fromListWord == "fromList "
then fromList <$> readPrec
else ReadPrec.pfail

-------------------------------------------------------------------------------
-- Backward Compatibility
-------------------------------------------------------------------------------

RENAME(getSliceUnsafe,unsafeGetSlice)
RENAME(getIndexUnsafe,unsafeGetIndex)
39 changes: 25 additions & 14 deletions core/src/Streamly/Internal/Data/Array/Type.hs
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ module Streamly.Internal.Data.Array.Type
-- ** Reading

-- *** Indexing
, unsafeIndexIO -- XXX unsafeGetIndexIO
, getIndexUnsafe -- XXX unsafeGetIndex
, unsafeGetIndexIO
, unsafeGetIndex

-- *** To Streams
, read
Expand All @@ -91,7 +91,7 @@ module Streamly.Internal.Data.Array.Type

-- *** Unfolds
, producer -- experimental
, readerUnsafe
, unsafeReader
, reader
, readerRev

Expand Down Expand Up @@ -170,6 +170,9 @@ module Streamly.Internal.Data.Array.Type
, pinnedFromListN
, pinnedFromList
, pinnedChunksOf
, unsafeIndexIO
, getIndexUnsafe
, readerUnsafe
)
where

Expand Down Expand Up @@ -698,19 +701,19 @@ breakOn sep arr = do
-- | Return element at the specified index without checking the bounds.
--
-- Unsafe because it does not check the bounds of the array.
{-# INLINE_NORMAL unsafeIndexIO #-}
unsafeIndexIO :: forall a. Unbox a => Int -> Array a -> IO a
unsafeIndexIO i arr = MA.unsafeGetIndex i (unsafeThaw arr)
{-# INLINE_NORMAL unsafeGetIndexIO #-}
unsafeGetIndexIO, unsafeIndexIO :: forall a. Unbox a => Int -> Array a -> IO a
unsafeGetIndexIO i arr = MA.unsafeGetIndex i (unsafeThaw arr)

-- | Return element at the specified index without checking the bounds.
{-# INLINE_NORMAL getIndexUnsafe #-}
getIndexUnsafe :: forall a. Unbox a => Int -> Array a -> a
getIndexUnsafe i arr = let !r = unsafeInlineIO $ unsafeIndexIO i arr in r
{-# INLINE_NORMAL unsafeGetIndex #-}
unsafeGetIndex, getIndexUnsafe :: forall a. Unbox a => Int -> Array a -> a
unsafeGetIndex i arr = let !r = unsafeInlineIO $ unsafeGetIndexIO i arr in r

{-# DEPRECATED unsafeIndex "Please use 'getIndexUnsafe' instead" #-}
{-# DEPRECATED unsafeIndex "Please use 'unsafeGetIndex' instead" #-}
{-# INLINE_NORMAL unsafeIndex #-}
unsafeIndex :: forall a. Unbox a => Int -> Array a -> a
unsafeIndex = getIndexUnsafe
unsafeIndex = unsafeGetIndex

-- | /O(1)/ Get the byte length of the array.
--
Expand Down Expand Up @@ -748,9 +751,9 @@ reader = Producer.simplify producer
--
-- /Pre-release/
--
{-# INLINE_NORMAL readerUnsafe #-}
readerUnsafe :: forall m a. (Monad m, Unbox a) => Unfold m (Array a) a
readerUnsafe = Unfold step inject
{-# INLINE_NORMAL unsafeReader #-}
unsafeReader, readerUnsafe :: forall m a. (Monad m, Unbox a) => Unfold m (Array a) a
unsafeReader = Unfold step inject
where

inject (Array contents start end) =
Expand Down Expand Up @@ -1288,3 +1291,11 @@ nil = empty
instance Unbox a => Monoid (Array a) where
mempty = nil
mappend = (<>)

-------------------------------------------------------------------------------
-- Backward Compatibility
-------------------------------------------------------------------------------

RENAME(unsafeIndexIO,unsafeGetIndexIO)
RENAME(getIndexUnsafe,unsafeGetIndex)
RENAME(readerUnsafe,unsafeReader)
4 changes: 2 additions & 2 deletions core/src/Streamly/Internal/Data/Binary/Parser.hs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ import Streamly.Internal.Data.Maybe.Strict (Maybe'(..))
import Streamly.Internal.Data.Tuple.Strict (Tuple' (..))
import qualified Streamly.Data.Array as A
import qualified Streamly.Internal.Data.Array as A
(getIndexUnsafe, castUnsafe)
(unsafeGetIndex, unsafeCast)
import qualified Streamly.Internal.Data.Parser as PR
(fromPure, either, satisfy, takeEQ)
import qualified Streamly.Internal.Data.Parser as PRD
Expand Down Expand Up @@ -388,7 +388,7 @@ charLatin1 = fmap (chr . fromIntegral) word8
{-# INLINE word64host #-}
word64host :: MonadIO m => Parser Word8 m Word64
word64host =
fmap (A.getIndexUnsafe 0 . A.castUnsafe) $ PR.takeEQ 8 (A.createOf 8)
fmap (A.unsafeGetIndex 0 . A.unsafeCast) $ PR.takeEQ 8 (A.createOf 8)

-------------------------------------------------------------------------------
-- Type class
Expand Down
4 changes: 2 additions & 2 deletions core/src/Streamly/Internal/Data/Fold/Combinators.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1465,7 +1465,7 @@ takeEndBySeq patArr (Fold fstep finitial fextract ffinal) =
-- Done <$> ffinal acc
return $ Partial $ SplitOnSeqEmpty acc
| patLen == 1 -> do
pat <- liftIO $ Array.unsafeIndexIO 0 patArr
pat <- liftIO $ Array.unsafeGetIndexIO 0 patArr
return $ Partial $ SplitOnSeqSingle acc pat
| SIZE_OF(a) * patLen <= sizeOf (Proxy :: Proxy Word) ->
return $ Partial $ SplitOnSeqWord acc 0 0
Expand Down Expand Up @@ -1631,7 +1631,7 @@ takeEndBySeq_ patArr (Fold fstep finitial fextract ffinal) =
-- Done <$> ffinal acc
return $ Partial $ SplitOnSeqEmpty acc
| patLen == 1 -> do
pat <- liftIO $ Array.unsafeIndexIO 0 patArr
pat <- liftIO $ Array.unsafeGetIndexIO 0 patArr
return $ Partial $ SplitOnSeqSingle acc pat
-- XXX Need to add tests for this case
| SIZE_OF(a) * patLen <= sizeOf (Proxy :: Proxy Word) ->
Expand Down
4 changes: 2 additions & 2 deletions core/src/Streamly/Internal/Data/Scanl/Combinators.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1424,7 +1424,7 @@ takeEndBySeq patArr (Fold fstep finitial fextract ffinal) =
-- Done <$> ffinal acc
return $ Partial $ SplitOnSeqEmpty acc
| patLen == 1 -> do
pat <- liftIO $ Array.unsafeIndexIO 0 patArr
pat <- liftIO $ Array.unsafeGetIndexIO 0 patArr
return $ Partial $ SplitOnSeqSingle acc pat
| SIZE_OF(a) * patLen <= sizeOf (Proxy :: Proxy Word) ->
return $ Partial $ SplitOnSeqWord acc 0 0
Expand Down Expand Up @@ -1564,7 +1564,7 @@ takeEndBySeq_ patArr (Fold fstep finitial fextract ffinal) =
-- Done <$> ffinal acc
return $ Partial $ SplitOnSeqEmpty acc
| patLen == 1 -> do
pat <- liftIO $ Array.unsafeIndexIO 0 patArr
pat <- liftIO $ Array.unsafeGetIndexIO 0 patArr
return $ Partial $ SplitOnSeqSingle acc pat
-- XXX Need to add tests for this case
| SIZE_OF(a) * patLen <= sizeOf (Proxy :: Proxy Word) ->
Expand Down
6 changes: 3 additions & 3 deletions core/src/Streamly/Internal/Data/Stream/Nesting.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2500,7 +2500,7 @@ takeEndBySeqWith withSep patArr (Stream step state) =
case () of
_ | patLen == 0 -> return Stop
| patLen == 1 -> do
pat <- liftIO $ A.unsafeIndexIO 0 patArr
pat <- liftIO $ A.unsafeGetIndexIO 0 patArr
return $ Skip $ TakeEndBySeqSingle state pat
| SIZE_OF(a) * patLen <= sizeOf (Proxy :: Proxy Word) ->
return $ Skip $ TakeEndBySeqWordInit 0 0 state
Expand Down Expand Up @@ -2845,7 +2845,7 @@ splitSepBySeq_ patArr (Fold fstep initial _ final) (Stream step state) =
| patLen == 0 ->
return $ Skip $ SplitOnSeqEmpty acc state
| patLen == 1 -> do
pat <- liftIO $ A.unsafeIndexIO 0 patArr
pat <- liftIO $ A.unsafeGetIndexIO 0 patArr
return $ Skip $ SplitOnSeqSingle acc state pat
| SIZE_OF(a) * patLen <= sizeOf (Proxy :: Proxy Word) ->
return $ Skip $ SplitOnSeqWordInit acc state
Expand Down Expand Up @@ -3229,7 +3229,7 @@ splitOnSuffixSeq withSep patArr (Fold fstep initial _ final) (Stream step state)
| patLen == 0 ->
skip $ SplitOnSuffixSeqEmpty fs state
| patLen == 1 -> do
pat <- liftIO $ A.unsafeIndexIO 0 patArr
pat <- liftIO $ A.unsafeGetIndexIO 0 patArr
skip $ SplitOnSuffixSeqSingleInit fs state pat
| SIZE_OF(a) * patLen <= sizeOf (Proxy :: Proxy Word) ->
skip $ SplitOnSuffixSeqWordInit fs state
Expand Down
4 changes: 2 additions & 2 deletions core/src/Streamly/Internal/Data/StreamK.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1583,8 +1583,8 @@ backTrackGenericChunks = go
then go (n - len) xs (cons x stream)
else if n == len
then (cons x stream, xs)
else let arr1 = GenArr.getSliceUnsafe (len - n) n x
arr2 = GenArr.getSliceUnsafe 0 (len - n) x
else let arr1 = GenArr.unsafeGetSlice (len - n) n x
arr2 = GenArr.unsafeGetSlice 0 (len - n) x
in (cons arr1 stream, arr2:xs)

-- | Similar to 'parseBreak' but works on generic arrays
Expand Down
Loading
Loading