on master help sign in
Implement fromListRevN and fromListRev for arrays
commit9861120b4ad13dcfb22b68d7483c01eff9eefd7e authorHarendra Kumar <harendra@composewell.com> dateSun 19 Jun 2022, 00:29 (4 years ago) parent4e252a8
2 files changed+62−12
core/src/Streamly/Internal/Data/Array/Foreign/Mut/Type.hs+56−1 core/src/Streamly/Internal/Data/Array/Foreign/Type.hs+6−11
core/src/Streamly/Internal/Data/Array/Foreign/Mut/Type.hs+56−1
@@ -48,13 +48,15 @@ module Streamly.Internal.Data.Array.Foreign.Mut.Type
4848 , writeWith
4949 , write
5050
51− -- , writeRevN
51+ , writeRevN
5252 -- , writeRev
5353
5454 -- ** From containers
5555 , fromForeignPtrUnsafe
5656 , fromListN
5757 , fromList
58+ , fromListRevN
59+ , fromListRev
5860 , fromStreamDN
5961 , fromStreamD
6062
@@ -265,6 +267,7 @@ import qualified Streamly.Internal.Data.Stream.StreamK.Type as K
265267#ifdef USE_FOREIGN_PTR
266268import qualified Streamly.Internal.Foreign.Malloc as Malloc
267269#endif
270+import qualified Prelude
268271
269272import Prelude hiding
270273 (length, foldr, read, unlines, splitAt, reverse, truncate)
@@ -1901,6 +1904,43 @@ writeNWith alloc n = FL.take n (writeNWithUnsafe alloc n)
19011904writeN :: forall m a. (MonadIO m, Storable a) => Int -> Fold m a (Array a)
19021905writeN = writeNWith newArray
19031906
1907+-- | Like writeNWithUnsafe but writes the array in reverse order.
1908+--
1909+-- /Internal/
1910+{-# INLINE_NORMAL writeRevNWithUnsafe #-}
1911+writeRevNWithUnsafe :: forall m a. (MonadIO m, Storable a)
1912+ => (Int -> m (Array a)) -> Int -> Fold m a (Array a)
1913+writeRevNWithUnsafe alloc n = Fold step initial (return . fromArrayUnsafe)
1914+
1915+ where
1916+
1917+ toArrayUnsafeRev (Array contents _ _ bound) =
1918+ ArrayUnsafe contents bound bound
1919+
1920+ initial = FL.Partial . toArrayUnsafeRev <$> alloc (max n 0)
1921+
1922+ step (ArrayUnsafe contents start end) x = do
1923+ let ptr = PTR_PREV(start,a)
1924+ liftIO $ poke ptr x >> touch contents
1925+ return
1926+ $ FL.Partial
1927+ $ ArrayUnsafe contents ptr end
1928+
1929+-- | Like writeNWith but writes the array in reverse order.
1930+--
1931+-- /Internal/
1932+{-# INLINE_NORMAL writeRevNWith #-}
1933+writeRevNWith :: forall m a. (MonadIO m, Storable a)
1934+ => (Int -> m (Array a)) -> Int -> Fold m a (Array a)
1935+writeRevNWith alloc n = FL.take n (writeRevNWithUnsafe alloc n)
1936+
1937+-- | Like writeN but writes the array in reverse order.
1938+--
1939+-- /Pre-release/
1940+{-# INLINE_NORMAL writeRevN #-}
1941+writeRevN :: forall m a. (MonadIO m, Storable a) => Int -> Fold m a (Array a)
1942+writeRevN = writeRevNWith newArray
1943+
19041944-- | @writeNAligned align n@ folds a maximum of @n@ elements from the input
19051945-- stream to an 'Array' aligned to the given size.
19061946--
@@ -2052,6 +2092,13 @@ fromStreamDN limit str = do
20522092fromListN :: (MonadIO m, Storable a) => Int -> [a] -> m (Array a)
20532093fromListN n xs = fromStreamDN n $ D.fromList xs
20542094
2095+-- | Like fromListN but writes the array in reverse order.
2096+--
2097+-- /Pre-release/
2098+{-# INLINE fromListRevN #-}
2099+fromListRevN :: (MonadIO m, Storable a) => Int -> [a] -> m (Array a)
2100+fromListRevN n xs = D.fold (writeRevN n) $ D.fromList xs
2101+
20552102-------------------------------------------------------------------------------
20562103-- convert stream to a single array
20572104-------------------------------------------------------------------------------
@@ -2094,6 +2141,14 @@ fromStreamD m = arrayStreamKFromStreamD m >>= fromArrayStreamK
20942141fromList :: (MonadIO m, Storable a) => [a] -> m (Array a)
20952142fromList xs = fromStreamD $ D.fromList xs
20962143
2144+-- XXX We are materializing the whole list first for getting the length. Check
2145+-- if the 'fromList' like chunked implementation would fare better.
2146+
2147+-- | Like 'fromList' but writes the contents of the list in reverse order.
2148+{-# INLINE fromListRev #-}
2149+fromListRev :: (MonadIO m, Storable a) => [a] -> m (Array a)
2150+fromListRev xs = fromListRevN (Prelude.length xs) xs
2151+
20972152-------------------------------------------------------------------------------
20982153-- Combining
20992154-------------------------------------------------------------------------------
core/src/Streamly/Internal/Data/Array/Foreign/Type.hs+6−11
@@ -349,19 +349,14 @@ fromCString# addr# = do
349349fromListN :: Storable a => Int -> [a] -> Array a
350350fromListN n xs = unsafePerformIO $ unsafeFreeze <$> MA.fromListN n xs
351351
352−-- XXX We can possibly have a direction flag in the array to reverse it without
353−-- actually doing anything. With that we can just do "reverse . fromList". But
354−-- it may complicate all the APIs as all reads of the array will have to handle
355−-- the flag.
356−--
357352-- | Create an 'Array' from the first N elements of a list in reverse order.
358353-- The array is allocated to size N, if the list terminates before N elements
359354-- then the array may hold less than N elements.
360355--
361−-- /Unimplemented/
356+-- /Pre-release/
362357{-# INLINABLE fromListRevN #-}
363−fromListRevN :: {- Storable a => -} Int -> [a] -> Array a
364−fromListRevN _n _xs = undefined
358+fromListRevN :: Storable a => Int -> [a] -> Array a
359+fromListRevN n xs = unsafePerformIO $ unsafeFreeze <$> MA.fromListRevN n xs
365360
366361-- | Create an 'Array' from a list. The list must be of finite size.
367362--
@@ -375,10 +370,10 @@ fromList xs = unsafePerformIO $ unsafeFreeze <$> MA.fromList xs
375370-- | Create an 'Array' from a list in reverse order. The list must be of finite
376371-- size.
377372--
378−-- /Unimplemented/
373+-- /Pre-release/
379374{-# INLINABLE fromListRev #-}
380−fromListRev :: {- Storable a => -} [a] -> Array a
381−fromListRev _xs = undefined
375+fromListRev :: Storable a => [a] -> Array a
376+fromListRev xs = unsafePerformIO $ unsafeFreeze <$> MA.fromListRev xs
382377
383378{-# INLINE_NORMAL fromStreamDN #-}
384379fromStreamDN :: forall m a. (MonadIO m, Storable a)