on master help sign in
Export some pre-release array APIs

* getIndex * casting ops * writeLastN * readRev

commit03cf686ca7e3fe1093b064c9763de8b684cce0f4 authorHarendra Kumar <harendra@composewell.com> dateMon 26 Apr 2021, 01:56 (5 years ago) parent18b6ef8
7 files changed+50−39
benchmark/Streamly/Benchmark/Data/Array.hs+3−3 benchmark/Streamly/Benchmark/Data/Array/Stream/Foreign.hs+1−1 src/Streamly/Data/Array/Foreign.hs+7−2 src/Streamly/Internal/Data/Array/Foreign.hs+29−23 src/Streamly/Internal/FileSystem/Event/Linux.hs+1−1 test/Streamly/Test/Common/Array.hs+8−8 test/Streamly/Test/FileSystem/Event.hs+1−1
benchmark/Streamly/Benchmark/Data/Array.hs+3−3
@@ -120,8 +120,8 @@ o_1_space_elimination value =
120120 , benchIOSink value "foldl'" Ops.pureFoldl'
121121 , benchIOSink value "read" Ops.unfoldReadDrain
122122 , benchIOSink value "toStreamRev" Ops.toStreamRevDrain
123− , benchFold "lastN.1" (S.fold (IA.lastN 1)) (P.sourceUnfoldrM value)
124− , benchFold "lastN.10" (S.fold (IA.lastN 10)) (P.sourceUnfoldrM value)
123+ , benchFold "writeLastN.1" (S.fold (IA.writeLastN 1)) (P.sourceUnfoldrM value)
124+ , benchFold "writeLastN.10" (S.fold (IA.writeLastN 10)) (P.sourceUnfoldrM value)
125125#if !defined(DATA_ARRAY_PRIM) && !defined(DATA_ARRAY_PRIM_PINNED)
126126#ifdef DEVBUILD
127127 , benchPureSink value "foldable/foldl'" Ops.foldableFoldl'
@@ -136,7 +136,7 @@ o_n_heap_serial value =
136136 [ bgroup "elimination"
137137 [
138138 -- Converting the stream to an array
139− benchFold "lastN.Max" (S.fold (IA.lastN (value + 1)))
139+ benchFold "writeLastN.Max" (S.fold (IA.writeLastN (value + 1)))
140140 (P.sourceUnfoldrM value)
141141 , benchFold "writeN" (S.fold (A.writeN value))
142142 (P.sourceUnfoldrM value)
benchmark/Streamly/Benchmark/Data/Array/Stream/Foreign.hs+1−1
@@ -55,7 +55,7 @@ toChunksLast inh = do
5555 larr <- Stream.last s
5656 return $ case larr of
5757 Nothing -> Nothing
58− Just arr -> Array.readIndex arr (Array.length arr - 1)
58+ Just arr -> Array.getIndex arr (Array.length arr - 1)
5959
6060#ifdef INSPECTION
6161inspect $ hasNoTypeClasses 'toChunksLast
src/Streamly/Data/Array/Foreign.hs+7−2
@@ -54,7 +54,7 @@ module Streamly.Data.Array.Foreign
5454 -- Monadic APIs
5555 , A.writeN -- drop new
5656 , A.write -- full buffer
57− -- , writeLastN -- drop old (ring buffer)
57+ , writeLastN -- drop old (ring buffer)
5858
5959 -- ** Elimination
6060 -- 'GHC.Exts.toList' from "GHC.Exts" can be used to convert an array to a
@@ -62,11 +62,16 @@ module Streamly.Data.Array.Foreign
6262
6363 , A.toList
6464 , A.read
65+ , A.readRev
66+
67+ -- ** Casting
68+ , cast
69+ , asBytes
6570
6671 -- ** Random Access
6772 , A.length
6873 -- , (!!)
69− -- , A.readIndex
74+ , A.getIndex
7075 )
7176where
7277
src/Streamly/Internal/Data/Array/Foreign.hs+29−23
@@ -60,7 +60,7 @@ module Streamly.Internal.Data.Array.Foreign
6060 , A.writeN -- drop new
6161 , A.writeNAligned
6262 , A.write -- full buffer
63− -- , writeLastN -- drop old (ring buffer)
63+ , writeLastN
6464
6565 -- * Elimination
6666
@@ -78,7 +78,7 @@ module Streamly.Internal.Data.Array.Foreign
7878 , null
7979 , last
8080 -- , (!!)
81− , readIndex
81+ , getIndex
8282 , A.unsafeIndex
8383 -- , readIndices
8484 -- , readRanges
@@ -130,15 +130,12 @@ module Streamly.Internal.Data.Array.Foreign
130130 , cast
131131 , unsafeCast
132132 , asPtr
133− , asByteArray
133+ , asBytes
134134 , asCString
135135
136136 -- * Folding Arrays
137137 , streamFold
138138 , fold
139−
140− -- * Folds with Array as the container
141− , lastN
142139 )
143140where
144141
@@ -273,34 +270,43 @@ unsafeRead = Unfold step inject
273270null :: Storable a => Array a -> Bool
274271null arr = length arr == 0
275272
276−-- | > last arr = readIndex arr (length arr - 1)
273+-- | > last arr = getIndex arr (length arr - 1)
277274--
278275-- /Pre-release/
279276{-# INLINE last #-}
280277last :: Storable a => Array a -> Maybe a
281−last arr = readIndex arr (length arr - 1)
278+last arr = getIndex arr (length arr - 1)
282279
283280-------------------------------------------------------------------------------
284281-- Folds with Array as the container
285282-------------------------------------------------------------------------------
286283
287−-- | Take last 'n' elements from the stream and discard the rest.
288−{-# INLINE lastN #-}
289−lastN :: (Storable a, MonadIO m) => Int -> Fold m a (Array a)
290−lastN n
284+-- | @writeLastN n@ folds a maximum of @n@ elements from the end of the input
285+-- stream to an 'Array'.
286+--
287+-- @since 0.8.0
288+{-# INLINE writeLastN #-}
289+writeLastN :: (Storable a, MonadIO m) => Int -> Fold m a (Array a)
290+writeLastN n
291291 | n <= 0 = fmap (const mempty) FL.drain
292292 | otherwise = A.unsafeFreeze <$> Fold step initial done
293− where
293+
294+ where
295+
294296 step (Tuple3' rb rh i) a = do
295297 rh1 <- liftIO $ RB.unsafeInsert rb rh a
296298 return $ FL.Partial $ Tuple3' rb rh1 (i + 1)
299+
297300 initial =
298301 let f (a, b) = FL.Partial $ Tuple3' a b (0 :: Int)
299302 in fmap f $ liftIO $ RB.new n
303+
300304 done (Tuple3' rb rh i) = do
301305 arr <- liftIO $ MA.newArray n
302306 foldFunc i rh snoc' arr rb
307+
303308 snoc' b a = liftIO $ MA.unsafeSnoc b a
309+
304310 foldFunc i
305311 | i < n = RB.unsafeFoldRingM
306312 | otherwise = RB.unsafeFoldRingFullM
@@ -425,10 +431,10 @@ foldbWith level f = undefined
425431
426432-- | /O(1)/ Lookup the element at the given index, starting from 0.
427433--
428−-- /Pre-release/
429−{-# INLINE readIndex #-}
430−readIndex :: Storable a => Array a -> Int -> Maybe a
431−readIndex arr i =
434+-- @since 0.8.0
435+{-# INLINE getIndex #-}
436+getIndex :: Storable a => Array a -> Int -> Maybe a
437+getIndex arr i =
432438 if i < 0 || i > length arr - 1
433439 then Nothing
434440 else A.unsafeInlineIO $
@@ -543,18 +549,18 @@ unsafeCast ::
543549 Array a -> Array b
544550unsafeCast (Array start end) = Array (castForeignPtr start) (castPtr end)
545551
546−-- | Cast an array into a Word8 array
552+-- | Cast an @Array a@ into an @Array Word8@.
547553--
548−-- /Pre-release/
554+-- @since 0.8.0
549555--
550−asByteArray :: Array a -> Array Word8
551−asByteArray = unsafeCast
556+asBytes :: Array a -> Array Word8
557+asBytes = unsafeCast
552558
553559-- | Cast an array having elements of type @a@ into an array having elements of
554560-- type @b@. The length of the array should be a multiple of the size of the
555561-- target element otherwise 'Nothing' is returned.
556562--
557−-- /Pre-release/
563+-- @since 0.8.0
558564--
559565cast :: forall a b. (Storable b) => Array a -> Maybe (Array b)
560566cast arr =
@@ -584,7 +590,7 @@ asPtr Array{..} act = do
584590--
585591asCString :: Array a -> (CString -> IO b) -> IO b
586592asCString arr act = do
587− let Array{..} = asByteArray arr <> A.fromList [0]
593+ let Array{..} = asBytes arr <> A.fromList [0]
588594 withForeignPtr aStart $ \ptr -> act (castPtr ptr)
589595
590596-------------------------------------------------------------------------------
src/Streamly/Internal/FileSystem/Event/Linux.hs+1−1
@@ -621,7 +621,7 @@ ensureTrailingSlash :: Array Word8 -> Array Word8
621621ensureTrailingSlash path =
622622 if A.length path /= 0
623623 then
624− let mx = A.readIndex path (A.length path - 1)
624+ let mx = A.getIndex path (A.length path - 1)
625625 in case mx of
626626 Nothing -> error "ensureTrailingSlash: Bug: Invalid index"
627627 Just x ->
test/Streamly/Test/Common/Array.hs+8−8
@@ -206,14 +206,14 @@ testLastN =
206206 monadicIO $ do
207207 xs <- run
208208 $ fmap A.toList
209− $ S.fold (A.lastN n)
209+ $ S.fold (A.writeLastN n)
210210 $ S.fromList list
211211 assert (xs == lastN n list)
212212
213213testLastN_LN :: Int -> Int -> IO Bool
214214testLastN_LN len n = do
215215 let list = [1..len]
216− l1 <- fmap A.toList $ S.fold (A.lastN n) $ S.fromList list
216+ l1 <- fmap A.toList $ S.fold (A.writeLastN n) $ S.fromList list
217217 let l2 = lastN n list
218218 return $ l1 == l2
219219
@@ -275,10 +275,10 @@ main =
275275 it "middle" (unsafeWriteIndex [1..10] 5 0 `shouldReturn` True)
276276 it "last" (unsafeWriteIndex [1..10] 9 0 `shouldReturn` True)
277277 describe "Fold" $ do
278− prop "lastN : 0 <= n <= len" $ testLastN
279− describe "lastN boundary conditions" $ do
280− it "lastN -1" (testLastN_LN 10 (-1) `shouldReturn` True)
281− it "lastN 0" (testLastN_LN 10 0 `shouldReturn` True)
282− it "lastN length" (testLastN_LN 10 10 `shouldReturn` True)
283− it "lastN (length + 1)" (testLastN_LN 10 11 `shouldReturn` True)
278+ prop "writeLastN : 0 <= n <= len" $ testLastN
279+ describe "writeLastN boundary conditions" $ do
280+ it "writeLastN -1" (testLastN_LN 10 (-1) `shouldReturn` True)
281+ it "writeLastN 0" (testLastN_LN 10 0 `shouldReturn` True)
282+ it "writeLastN length" (testLastN_LN 10 10 `shouldReturn` True)
283+ it "writeLastN (length + 1)" (testLastN_LN 10 11 `shouldReturn` True)
284284#endif
test/Streamly/Test/FileSystem/Event.hs+1−1
@@ -93,7 +93,7 @@ removeTrailingSlash path =
9393 if Array.length path == 0
9494 then path
9595 else
96− let mx = Array.readIndex path (Array.length path - 1)
96+ let mx = Array.getIndex path (Array.length path - 1)
9797 in case mx of
9898 Nothing -> error "removeTrailingSlash: Bug: Invalid index"
9999 Just x ->