on master help sign in
Implement fromListRevN and fromListRev for arrays
9861120Harendra Kumar
core/src/Streamly/Internal/Data/Array/Foreign/Mut/Type.hs+56−1
@@ -48,13 +48,15 @@ module Streamly.Internal.Data.Array.Foreign.Mut.Type
48 , writeWith
48 , writeWith
49 , write
49 , write
50
50
51− -- , writeRevN
51+ , writeRevN
52 -- , writeRev
52 -- , writeRev
53
53
54 -- ** From containers
54 -- ** From containers
55 , fromForeignPtrUnsafe
55 , fromForeignPtrUnsafe
56 , fromListN
56 , fromListN
57 , fromList
57 , fromList
58+ , fromListRevN
59+ , fromListRev
58 , fromStreamDN
60 , fromStreamDN
59 , fromStreamD
61 , fromStreamD
60
62
@@ -265,6 +267,7 @@ import qualified Streamly.Internal.Data.Stream.StreamK.Type as K
265#ifdef USE_FOREIGN_PTR
267#ifdef USE_FOREIGN_PTR
266import qualified Streamly.Internal.Foreign.Malloc as Malloc
268import qualified Streamly.Internal.Foreign.Malloc as Malloc
267#endif
269#endif
270+import qualified Prelude
268
271
269import Prelude hiding
272import Prelude hiding
270 (length, foldr, read, unlines, splitAt, reverse, truncate)
273 (length, foldr, read, unlines, splitAt, reverse, truncate)
@@ -1901,6 +1904,43 @@ writeNWith alloc n = FL.take n (writeNWithUnsafe alloc n)
1901writeN :: forall m a. (MonadIO m, Storable a) => Int -> Fold m a (Array a)
1904writeN :: forall m a. (MonadIO m, Storable a) => Int -> Fold m a (Array a)
1902writeN = writeNWith newArray
1905writeN = writeNWith newArray
1903
1906
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+
1904-- | @writeNAligned align n@ folds a maximum of @n@ elements from the input
1944-- | @writeNAligned align n@ folds a maximum of @n@ elements from the input
1905-- stream to an 'Array' aligned to the given size.
1945-- stream to an 'Array' aligned to the given size.
1906--
1946--
@@ -2052,6 +2092,13 @@ fromStreamDN limit str = do
2052fromListN :: (MonadIO m, Storable a) => Int -> [a] -> m (Array a)
2092fromListN :: (MonadIO m, Storable a) => Int -> [a] -> m (Array a)
2053fromListN n xs = fromStreamDN n $ D.fromList xs
2093fromListN n xs = fromStreamDN n $ D.fromList xs
2054
2094
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+
2055-------------------------------------------------------------------------------
2102-------------------------------------------------------------------------------
2056-- convert stream to a single array
2103-- convert stream to a single array
2057-------------------------------------------------------------------------------
2104-------------------------------------------------------------------------------
@@ -2094,6 +2141,14 @@ fromStreamD m = arrayStreamKFromStreamD m >>= fromArrayStreamK
2094fromList :: (MonadIO m, Storable a) => [a] -> m (Array a)
2141fromList :: (MonadIO m, Storable a) => [a] -> m (Array a)
2095fromList xs = fromStreamD $ D.fromList xs
2142fromList xs = fromStreamD $ D.fromList xs
2096
2143
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+
2097-------------------------------------------------------------------------------
2152-------------------------------------------------------------------------------
2098-- Combining
2153-- Combining
2099-------------------------------------------------------------------------------
2154-------------------------------------------------------------------------------
core/src/Streamly/Internal/Data/Array/Foreign/Type.hs+6−11
@@ -349,19 +349,14 @@ fromCString# addr# = do
349fromListN :: Storable a => Int -> [a] -> Array a
349fromListN :: Storable a => Int -> [a] -> Array a
350fromListN n xs = unsafePerformIO $ unsafeFreeze <$> MA.fromListN n xs
350fromListN n xs = unsafePerformIO $ unsafeFreeze <$> MA.fromListN n xs
351
351
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−--
357-- | Create an 'Array' from the first N elements of a list in reverse order.
352-- | Create an 'Array' from the first N elements of a list in reverse order.
358-- The array is allocated to size N, if the list terminates before N elements
353-- The array is allocated to size N, if the list terminates before N elements
359-- then the array may hold less than N elements.
354-- then the array may hold less than N elements.
360--
355--
361−-- /Unimplemented/
356+-- /Pre-release/
362{-# INLINABLE fromListRevN #-}
357{-# INLINABLE fromListRevN #-}
363−fromListRevN :: {- Storable a => -} Int -> [a] -> Array a
358+fromListRevN :: Storable a => Int -> [a] -> Array a
364−fromListRevN _n _xs = undefined
359+fromListRevN n xs = unsafePerformIO $ unsafeFreeze <$> MA.fromListRevN n xs
365
360
366-- | Create an 'Array' from a list. The list must be of finite size.
361-- | Create an 'Array' from a list. The list must be of finite size.
367--
362--
@@ -375,10 +370,10 @@ fromList xs = unsafePerformIO $ unsafeFreeze <$> MA.fromList xs
375-- | Create an 'Array' from a list in reverse order. The list must be of finite
370-- | Create an 'Array' from a list in reverse order. The list must be of finite
376-- size.
371-- size.
377--
372--
378−-- /Unimplemented/
373+-- /Pre-release/
379{-# INLINABLE fromListRev #-}
374{-# INLINABLE fromListRev #-}
380−fromListRev :: {- Storable a => -} [a] -> Array a
375+fromListRev :: Storable a => [a] -> Array a
381−fromListRev _xs = undefined
376+fromListRev xs = unsafePerformIO $ unsafeFreeze <$> MA.fromListRev xs
382
377
383{-# INLINE_NORMAL fromStreamDN #-}
378{-# INLINE_NORMAL fromStreamDN #-}
384fromStreamDN :: forall m a. (MonadIO m, Storable a)
379fromStreamDN :: forall m a. (MonadIO m, Storable a)