Skip to content

Commit

Permalink
Rename *Unsafe APIs to unsafe* in Array modules
Browse files Browse the repository at this point in the history
  • Loading branch information
adithyaov committed Jan 2, 2025
1 parent 60f2166 commit e342036
Show file tree
Hide file tree
Showing 16 changed files with 116 additions and 90 deletions.
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
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

0 comments on commit e342036

Please sign in to comment.