on master help sign in
Add mutable array "strip" operation
faabb9aRanjeet Kumar Ranjan
benchmark/Streamly/Benchmark/Data/Array/Foreign/Mut.hs+18
@@ -61,6 +61,22 @@ o_n_space_serial_marray value array =
61 $ MArray.partitionBy (> (value `div` 2))
61 $ MArray.partitionBy (> (value `div` 2))
62 ]
62 ]
63
63
64+o_1_space_serial_marray :: Int -> MArray.Array Int -> [Benchmark]
65+o_1_space_serial_marray value array =
66+ [ benchIO "strip (< 0)" (const array)
67+ $ MArray.strip (< 0)
68+ , benchIO "strip (> 0)" (const array)
69+ $ MArray.strip (> 0)
70+ , benchIO "strip (< value/2)" (const array)
71+ $ MArray.strip (< (value `div` 2))
72+ , benchIO "strip (> value/2)" (const array)
73+ $ MArray.strip (> (value `div` 2))
74+ , benchIO "strip (odd)" (const array)
75+ $ MArray.strip odd
76+ , benchIO "strip (even)" (const array)
77+ $ MArray.strip even
78+ ]
79+
64-------------------------------------------------------------------------------
80-------------------------------------------------------------------------------
65-- Driver
81-- Driver
66-------------------------------------------------------------------------------
82-------------------------------------------------------------------------------
@@ -79,4 +95,6 @@ main = do
79 allBenchmarks array value =
95 allBenchmarks array value =
80 [ bgroup (o_1_space_prefix moduleName) $
96 [ bgroup (o_1_space_prefix moduleName) $
81 o_n_space_serial_marray value array
97 o_n_space_serial_marray value array
98+ , bgroup (o_1_space_prefix moduleName) $
99+ o_1_space_serial_marray value array
82 ]
100 ]
core/src/Streamly/Internal/Data/Array/Foreign/Mut/Type.hs+39
@@ -193,6 +193,7 @@ module Streamly.Internal.Data.Array.Foreign.Mut.Type
193 , memcpy
193 , memcpy
194 , memcmp
194 , memcmp
195 , c_memchr
195 , c_memchr
196+ , strip
196 )
197 )
197where
198where
198
199
@@ -2295,3 +2296,41 @@ instance NFData1 Array where
2295 {-# INLINE liftRnf #-}
2296 {-# INLINE liftRnf #-}
2296 liftRnf _ Array{} = ()
2297 liftRnf _ Array{} = ()
2297#endif
2298#endif
2299+
2300+-- | Strip elements which match with predicate from both ends.
2301+--
2302+-- /Pre-release/
2303+strip :: forall a m. (Storable a, MonadIO m) =>
2304+ (a -> Bool) -> Array a -> m (Array a)
2305+strip eq arr@Array{..} = do
2306+ let p = arrStart
2307+ q = aEnd
2308+ len = length arr
2309+ st <- liftIO $ getStart p len
2310+ end <- liftIO $ do
2311+ touch arrContents
2312+ if st == q
2313+ then return q
2314+ else getLast $ PTR_PREV(q, a)
2315+ go st end
2316+
2317+ where
2318+
2319+ getStart p i = do
2320+ touch arrContents
2321+ r <- peek p
2322+ if eq r && i > 0
2323+ then getStart (PTR_NEXT(p, a)) (i - 1)
2324+ else return p
2325+
2326+ getLast p = do
2327+ touch arrContents
2328+ r <- peek p
2329+ if eq r
2330+ then getLast $ PTR_PREV(p, a)
2331+ else return $ PTR_NEXT(p, a)
2332+
2333+ {-# INLINE go #-}
2334+ go p q = liftIO $ do
2335+ touch arrContents
2336+ return arr {arrStart = p, aEnd = q, aBound = q}
test/Streamly/Test/Data/Array/Foreign.hs+50
@@ -10,6 +10,7 @@ module Streamly.Test.Data.Array.Foreign (main) where
10
10
11#include "Streamly/Test/Data/Array/CommonImports.hs"
11#include "Streamly/Test/Data/Array/CommonImports.hs"
12
12
13+import Data.Char (isLower)
13import Data.Word(Word8)
14import Data.Word(Word8)
14
15
15import qualified Streamly.Internal.Data.Fold as Fold
16import qualified Streamly.Internal.Data.Fold as Fold
@@ -72,6 +73,48 @@ testLastN_LN len n = do
72 let l2 = lastN n list
73 let l2 = lastN n list
73 return $ l1 == l2
74 return $ l1 == l2
74
75
76+testStrip :: IO Bool
77+testStrip = do
78+ dt <- MA.fromList "abcDEFgeh"
79+ dt' <- MA.strip isLower dt
80+ x <- MA.toList dt'
81+ return $ x == "DEF"
82+
83+testStripLeft :: IO Bool
84+testStripLeft = do
85+ dt <- MA.fromList "abcDEF"
86+ dt' <- MA.strip isLower dt
87+ x <- MA.toList dt'
88+ return $ x == "DEF"
89+
90+testStripRight :: IO Bool
91+testStripRight = do
92+ dt <- MA.fromList "DEFgeh"
93+ dt' <- MA.strip isLower dt
94+ x <- MA.toList dt'
95+ return $ x == "DEF"
96+
97+testStripZero :: IO Bool
98+testStripZero = do
99+ dt <- MA.fromList "DEF"
100+ dt' <- MA.strip isLower dt
101+ x <- MA.toList dt'
102+ return $ x == "DEF"
103+
104+testStripEmpty :: IO Bool
105+testStripEmpty = do
106+ dt <- MA.fromList "abc"
107+ dt' <- MA.strip isLower dt
108+ x <- MA.toList dt'
109+ return $ x == ""
110+
111+testStripNull :: IO Bool
112+testStripNull = do
113+ dt <- MA.fromList ""
114+ dt' <- MA.strip isLower dt
115+ x <- MA.toList dt'
116+ return $ x == ""
117+
75-- Instead of hard coding 10000 here we can have maxStreamLength for operations
118-- Instead of hard coding 10000 here we can have maxStreamLength for operations
76-- that use stream of arrays.
119-- that use stream of arrays.
77concatArrayW8 :: Property
120concatArrayW8 :: Property
@@ -118,3 +161,10 @@ main =
118 it "writeLastN 0" (testLastN_LN 10 0 `shouldReturn` True)
161 it "writeLastN 0" (testLastN_LN 10 0 `shouldReturn` True)
119 it "writeLastN length" (testLastN_LN 10 10 `shouldReturn` True)
162 it "writeLastN length" (testLastN_LN 10 10 `shouldReturn` True)
120 it "writeLastN (length + 1)" (testLastN_LN 10 11 `shouldReturn` True)
163 it "writeLastN (length + 1)" (testLastN_LN 10 11 `shouldReturn` True)
164+ describe "Strip" $ do
165+ it "strip" (testStrip `shouldReturn` True)
166+ it "stripLeft" (testStripLeft `shouldReturn` True)
167+ it "stripRight" (testStripRight `shouldReturn` True)
168+ it "stripZero" (testStripZero `shouldReturn` True)
169+ it "stripEmpty" (testStripEmpty `shouldReturn` True)
170+ it "stripNull" (testStripNull `shouldReturn` True)