streamly 0.8.1 → 0.8.1.1
raw patch · 12 files changed
+341/−54 lines, 12 filesdep ~basedep ~filepathdep ~monad-control
Dependency ranges changed: base, filepath, monad-control, mtl, network, unicode-data
Files
- Changelog.md +4/−0
- benchmark/bench-report/bin/bench-runner.sh +14/−8
- bin/mk-hscope.sh +1/−1
- bin/test.sh +4/−2
- configure +9/−9
- configure.ac +1/−1
- dev/MAINTAINING.md +22/−17
- docs/CONTRIBUTORS.md +5/−0
- docs/getting-started.md +1/−1
- src/Streamly/Internal/Data/Array/Foreign/Mut/Type.hs +11/−7
- src/Streamly/Internal/Ring/Foreign.hs +265/−6
- streamly.cabal +4/−2
Changelog.md view
@@ -2,6 +2,10 @@ <!-- See rendered changelog at https://streamly.composewell.com --> +## 0.8.1.1 (Dec 2021)++* Disable building FileSystem.Events where FS Events isn't supported.+ ## 0.8.1 (Nov 2021) See docs/API-changelog.txt for new APIs introduced.
benchmark/bench-report/bin/bench-runner.sh view
@@ -34,7 +34,7 @@ echo " [--with-compiler <compiler exe name>]" echo " [--cabal-build-options <options>]" echo " [--rtsopts <opts>]"- echo " [--commit-compare] [--base <commit>] [--candidate <commit>]"+ #echo " [--commit-compare] [--base <commit>] [--candidate <commit>]" #echo " -- <gauge options or benchmarks>" echo echo "--benchmarks: benchmarks to run, use 'help' for list of benchmarks"@@ -56,10 +56,10 @@ echo "bench.sh --benchmarks Data.Parser -- Data.Parser/o-1-space " echo "restricts Heap/Stack space for O(1) characterstics" echo- echo "When using --commit-compare, by default comparative chart of HEAD^ vs HEAD"- echo "commit is generated, in the 'charts' directory."- echo "Use --base and --candidate to select the commits to compare."- echo+ #echo "When using --commit-compare, by default comparative chart of HEAD^ vs HEAD"+ #echo "commit is generated, in the 'charts' directory."+ #echo "Use --base and --candidate to select the commits to compare."+ #echo #echo "Any arguments after a '--' are passed directly to gauge" exit }@@ -383,16 +383,20 @@ fi echo "Comparing baseline commit [$BASE] with candidate [$CANDIDATE]" echo "Checking out base commit [$BASE] for benchmarking"+ # XXX git checkout will overwrite this script itself and the scripts+ # imported/used by this script. git checkout "$BASE" || die "Checkout of base commit [$BASE] failed" - $BUILD_BENCH || die "build failed"+ # $BUILD_BENCH || die "build failed"+ run_build "$BUILD_BENCH" $BENCHMARK_PACKAGE_NAME bench "$TARGETS" run_bench_targets $BENCHMARK_PACKAGE_NAME b "$bench_list" target_exe_extra_args echo "Checking out candidate commit [$CANDIDATE] for benchmarking" git checkout "$CANDIDATE" || \ die "Checkout of candidate [$CANDIDATE] commit failed" - $BUILD_BENCH || die "build failed"+ # $BUILD_BENCH || die "build failed"+ run_build "$BUILD_BENCH" $BENCHMARK_PACKAGE_NAME bench "$TARGETS" run_bench_targets $BENCHMARK_PACKAGE_NAME b "$bench_list" target_exe_extra_args # XXX reset back to the original commit }@@ -417,6 +421,7 @@ if test "$COMMIT_COMPARE" = "0" then+ run_build "$BUILD_BENCH" $BENCHMARK_PACKAGE_NAME bench "$TARGETS" run_bench_targets $BENCHMARK_PACKAGE_NAME b "$bench_list" target_exe_extra_args else run_benches_comparing "$bench_list"@@ -501,6 +506,8 @@ --sort-by-name) SORT_BY_NAME=1; shift ;; --graphs) GRAPH=1; shift ;; --no-measure) MEASURE=0; shift ;;+ # This is used in build-lib.sh to enable dev_build function which is used+ # in targets.sh to enable or disable some targets. --dev-build) RUNNING_DEVBUILD=1; shift ;; --use-nix) USE_NIX=1; shift ;; --use-gauge) USE_GAUGE=1; shift ;;@@ -613,7 +620,6 @@ BUILD_BENCH="$CABAL_EXECUTABLE v2-build $BUILD_FLAGS $CABAL_BUILD_OPTIONS --enable-benchmarks" if test "$MEASURE" = "1" then- run_build "$BUILD_BENCH" $BENCHMARK_PACKAGE_NAME bench "$TARGETS" run_measurements "$TARGETS" fi
bin/mk-hscope.sh view
@@ -1,7 +1,7 @@ #!/usr/bin/env bash GHC_VERSION=8.10.4-STREAMLY_VERSION=0.8.1+STREAMLY_VERSION=0.8.1.1 case `uname` in Darwin) SYSTEM=x86_64-osx;;
bin/test.sh view
@@ -2,7 +2,7 @@ SCRIPT_DIR=$(dirname $0) -STREAMLY_VERSION=0.8.1+STREAMLY_VERSION=0.8.1.1 BENCH_REPORT_DIR=benchmark/bench-report source $SCRIPT_DIR/targets.sh @@ -239,7 +239,9 @@ fi done - hpc sum --output=$ALLTIX $TIXFILES+ #echo "Combining tix files:"+ #echo $TIXFILES | tr ' ' '\n'+ hpc sum --union --output=$ALLTIX $TIXFILES run_verbose hpc markup $ALLTIX --hpcdir $MIX_DIR run_verbose hpc report $ALLTIX $HPC_REPORT_OPTIONS --hpcdir $MIX_DIR fi
configure view
@@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles.-# Generated by GNU Autoconf 2.71 for streamly 0.8.1.+# Generated by GNU Autoconf 2.71 for streamly 0.8.1.1. # # Report bugs to <streamly@composewell.com>. #@@ -610,8 +610,8 @@ # Identity of this package. PACKAGE_NAME='streamly' PACKAGE_TARNAME='streamly'-PACKAGE_VERSION='0.8.1'-PACKAGE_STRING='streamly 0.8.1'+PACKAGE_VERSION='0.8.1.1'+PACKAGE_STRING='streamly 0.8.1.1' PACKAGE_BUGREPORT='streamly@composewell.com' PACKAGE_URL='https://streamly.composewell.com' @@ -1256,7 +1256,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF-\`configure' configures streamly 0.8.1 to adapt to many kinds of systems.+\`configure' configures streamly 0.8.1.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1318,7 +1318,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in- short | recursive ) echo "Configuration of streamly 0.8.1:";;+ short | recursive ) echo "Configuration of streamly 0.8.1.1:";; esac cat <<\_ACEOF @@ -1404,7 +1404,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF-streamly configure 0.8.1+streamly configure 0.8.1.1 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc.@@ -1674,7 +1674,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by streamly $as_me 0.8.1, which was+It was created by streamly $as_me 0.8.1.1, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw@@ -4028,7 +4028,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log="-This file was extended by streamly $as_me 0.8.1, which was+This file was extended by streamly $as_me 0.8.1.1, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES@@ -4084,7 +4084,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\-streamly config.status 0.8.1+streamly config.status 0.8.1.1 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\"
configure.ac view
@@ -3,7 +3,7 @@ # See https://www.gnu.org/software/autoconf/manual/autoconf.html for help on # the macros used in this file. -AC_INIT([streamly], [0.8.1], [streamly@composewell.com], [streamly], [https://streamly.composewell.com])+AC_INIT([streamly], [0.8.1.1], [streamly@composewell.com], [streamly], [https://streamly.composewell.com]) # To suppress "WARNING: unrecognized options: --with-compiler" AC_ARG_WITH([compiler], [GHC])
dev/MAINTAINING.md view
@@ -193,11 +193,11 @@ of the issue. If no change is required the issue must have one of the following labels: -* invalid-* question-* discussion-* duplicate-* wontfix+* disposition:invalid+* disposition:question+* disposition:discussion+* disposition:duplicate+* disposition:wontfix If a change is required we need to do level-2 triage of the issue, see the sections below.@@ -207,12 +207,13 @@ When a change is required we need to put one of the __change type__ labels as part of level-2 triaging: -* performance: User visible impact on performance.-* usability: It is not convenient to use the library.-* documentation: documentation is not correct or sufficient.-* bug: A functionality issue, not working as expected.-* enhancement: A new feature or enhancement of the product.-* maintenance: A refactor or any other change with no user visible impact.+* type:performance: User visible impact on performance.+* type:testing: Improves testing or related to testing.+* type:usability: It is not convenient to use the library.+* type:documentation: documentation is not correct or sufficient.+* type:bug: A functionality issue, not working as expected.+* type:enhancement: includes a new feature or enhancement+* type:maintenance: A refactor or any other change with no user visible impact. ### Aspect @@ -229,13 +230,13 @@ * severity:high -### Change impact+### API impact For a user visible issue whether it has a release/changelog impact: -* enhancement: includes a new feature or enhancement-* breaking: has a breaking impact on existing deployments-* deprecating: deprecates an existing functionality+* api:new: includes a new feature or enhancement+* api:breaking: has a breaking impact on existing deployments+* api:deprecating: deprecates an existing functionality __RULE__: Any commit that may affect the end user in some way MUST have either a changelog entry OR MUST have an issue marked with one of the@@ -253,9 +254,13 @@ If the issue is assigned to someone then it is considered scheduled. Otherwise it is unscheduled. Unassigned issues may have the following labels: -* deferred: blocked on any other fix or a decision to be made, or deliberately- deferred for some reason.+* sched:deferred: deliberately deferred for some reason.+* sched:blocked: blocked on any other fix or a decision to be mad++### For Contributors+ * help-wanted: anyone can take the issue and contribute+* good-first-issue: good for new contributors ## Correlating Changes, Issues and Releases
docs/CONTRIBUTORS.md view
@@ -4,6 +4,11 @@ Use `git shortlog -sn tag1...tag2` on the git repository to get a list of contributors between two repository tags. +## 0.8.1.1++* Harendra Kumar+* Julian Ospald+ ## 0.8.1 * Harendra Kumar
docs/getting-started.md view
@@ -204,7 +204,7 @@ adding a version number constraint to the `--build-depends` flag: ```-$ cabal repl --build-depends streamly==0.8.1+$ cabal repl --build-depends streamly==0.8.1.1 [1 of 1] Compiling Main ( Main.hs, interpreted ) Ok, modules loaded: Main. *Main>
src/Streamly/Internal/Data/Array/Foreign/Mut/Type.hs view
@@ -703,13 +703,12 @@ ------------------------------------------------------------------------------- -- XXX We can possibly use a smallMutableByteArray to hold the start, end,--- bound pointers. Or we can use the first 16 bytes of the allocation to store--- the end, bound pointers. Using fully mutable handle will ensure that we do--- not have multiple references to the same array of different lengths lying--- around and potentially misused. In that case "snoc" need not return a new--- array (snoc :: Array a -> a -> m ()), it will just modify the old reference.--- The array length will be mutable. This means the length function would also--- be monadic. Mutable arrays would behave more like files that grow in that+-- bound pointers. Using fully mutable handle will ensure that we do not have+-- multiple references to the same array of different lengths lying around and+-- potentially misused. In that case "snoc" need not return a new array (snoc+-- :: Array a -> a -> m ()), it will just modify the old reference. The array+-- length will be mutable. This means the length function would also be+-- monadic. Mutable arrays would behave more like files that grow in that -- case. -- | Snoc using a 'Ptr'. Low level reusable function.@@ -846,6 +845,9 @@ -- Resizing ------------------------------------------------------------------------------- +-- XXX See if resizing can be implemented by reading the old array as a stream+-- and then using writeN to the new array.+-- -- | Reallocate the array to the specified size in bytes. If the size is less -- than the original array the array gets truncated. {-# NOINLINE reallocAligned #-}@@ -925,6 +927,8 @@ -- Reducing the length ------------------------------------------------------------------------------- +-- XXX Either slice the array or stream it and write it out to a new array?+-- -- | Drop the last n elements of the array to reduce the length by n. The -- capacity is reallocated using the user supplied function. --
src/Streamly/Internal/Ring/Foreign.hs view
@@ -6,45 +6,94 @@ -- Stability : experimental -- Portability : GHC --+-- A ring array is a circular mutable array. +-- XXX Write benchmarks+-- XXX Make the implementation similar to mutable array+-- XXX Rename this module to Data.RingArray.Storable+ module Streamly.Internal.Ring.Foreign- ( Ring(..)+ (+ -- * Type+ Ring(..) -- * Construction , new+ , newRing+ , writeN+ , advance , moveBy , startOf - -- * Modification+ -- * Random writes , unsafeInsert+ , slide+ , putIndex+ , modifyIndex + -- * Unfolds+ , read+ , readRev++ -- * Random reads+ , getIndex+ , getIndexUnsafe+ , getIndexRev++ -- * Size+ , length+ , byteLength+ -- , capacity+ , byteCapacity+ , bytesFree++ -- * Casting+ , cast+ , castUnsafe+ , asBytes+ , fromArray+ -- * Folds , unsafeFoldRing , unsafeFoldRingM , unsafeFoldRingFullM , unsafeFoldRingNM + -- * Stream of Arrays+ , ringsOf+ -- * Fast Byte Comparisons , unsafeEqArray , unsafeEqArrayN ) where +#include "inline.hs"+ import Control.Exception (assert)+import Control.Monad.IO.Class (MonadIO(..))+import Data.Word (Word8) import Foreign.ForeignPtr (ForeignPtr, withForeignPtr, touchForeignPtr) import Foreign.ForeignPtr.Unsafe (unsafeForeignPtrToPtr) import Foreign.Ptr (plusPtr, minusPtr, castPtr) import Foreign.Storable (Storable(..)) import GHC.ForeignPtr (mallocPlainForeignPtrAlignedBytes) import GHC.Ptr (Ptr(..))-import Prelude hiding (length, concat)--import Control.Monad.IO.Class (MonadIO(..))-import Streamly.Internal.Data.Array.Foreign.Mut.Type (memcmp)+import Streamly.Internal.Data.Array.Foreign.Mut.Type (Array, memcmp)+import Streamly.Internal.Data.Fold.Type (Fold(..))+import Streamly.Internal.Data.Stream.Serial (SerialT(..))+-- import Streamly.Internal.Data.Stream.IsStream.Transform (scan)+import Streamly.Internal.Data.Unfold.Type (Unfold(..)) import Streamly.Internal.System.IO (unsafeInlineIO) import qualified Streamly.Internal.Data.Array.Foreign.Type as A +import Prelude hiding (length, concat, read)++-- $setup+-- >>> :m+-- >>> import qualified Streamly.Internal.Ring.Foreign as Ring+ -- | A ring buffer is a mutable array of fixed size. Initially the array is -- empty, with ringStart pointing at the start of allocated memory. We call the -- next location to be written in the ring as ringHead. Initially ringHead ==@@ -62,6 +111,10 @@ , ringBound :: {-# UNPACK #-} !(Ptr a) -- first address beyond allocated memory } +-------------------------------------------------------------------------------+-- Construction+-------------------------------------------------------------------------------+ -- | Get the first address of the ring as a pointer. startOf :: Ring a -> Ptr a startOf = unsafeForeignPtrToPtr . ringStart@@ -79,6 +132,17 @@ , ringBound = p `plusPtr` size }, p) +-- XXX Rename this to "new".+--+-- | @newRing count@ allocates an empty array that can hold 'count' items. The+-- memory of the array is uninitialized and the allocation is aligned as per+-- the 'Storable' instance of the type.+--+-- /Unimplemented/+{-# INLINE newRing #-}+newRing :: Int -> m (Ring a)+newRing = undefined+ -- | Advance the ringHead by 1 item, wrap around if we hit the end of the -- array. {-# INLINE advance #-}@@ -106,6 +170,47 @@ off = assert (offInBytes `mod` elemSize == 0) $ offInBytes `div` elemSize advanceFromHead = (off + by `mod` len) * elemSize +-- XXX Move the writeLastN from array module here.+--+-- | @writeN n@ is a rolling fold that keeps the last n elements of the stream+-- in a ring array.+--+-- /Unimplemented/+{-# INLINE writeN #-}+writeN :: -- (Storable a, MonadIO m) =>+ Int -> Fold m a (Ring a)+writeN = undefined++-------------------------------------------------------------------------------+-- Conversions+-------------------------------------------------------------------------------++-- | Cast a mutable array to a ring array.+fromArray :: Array a -> Ring a+fromArray = undefined++-------------------------------------------------------------------------------+-- Conversion to/from array+-------------------------------------------------------------------------------++-- | Modify a given index of a ring array using a modifier function.+--+-- /Unimplemented/+modifyIndex :: -- forall m a b. (MonadIO m, Storable a) =>+ Ring a -> Int -> (a -> (a, b)) -> m b+modifyIndex = undefined++-- | /O(1)/ Write the given element at the given index in the ring array.+-- Performs in-place mutation of the array.+--+-- >>> putIndex arr ix val = Ring.modifyIndex arr ix (const (val, ()))+--+-- /Unimplemented/+{-# INLINE putIndex #-}+putIndex :: -- (MonadIO m, Storable a) =>+ Ring a -> Int -> a -> m ()+putIndex = undefined+ -- | Insert an item at the head of the ring, when the ring is full this -- replaces the oldest item in the ring with the new item. This is unsafe -- beause ringHead supplied is not verified to be within the Ring. Also,@@ -117,6 +222,155 @@ -- touchForeignPtr (ringStart rb) return $ advance rb ringHead +-- | Insert an item at the head of the ring, when the ring is full this+-- replaces the oldest item in the ring with the new item.+--+-- /Unimplemented/+slide :: -- forall m a. (MonadIO m, Storable a) =>+ Ring a -> a -> m (Ring a)+slide = undefined++-------------------------------------------------------------------------------+-- Random reads+-------------------------------------------------------------------------------++-- | Return the element at the specified index without checking the bounds.+--+-- Unsafe because it does not check the bounds of the ring array.+{-# INLINE_NORMAL getIndexUnsafe #-}+getIndexUnsafe :: -- forall m a. (MonadIO m, Storable a) =>+ Ring a -> Int -> m a+getIndexUnsafe = undefined++-- | /O(1)/ Lookup the element at the given index. Index starts from 0.+--+{-# INLINE getIndex #-}+getIndex :: -- (MonadIO m, Storable a) =>+ Ring a -> Int -> m a+getIndex = undefined++-- | /O(1)/ Lookup the element at the given index from the end of the array.+-- Index starts from 0.+--+-- Slightly faster than computing the forward index and using getIndex.+--+{-# INLINE getIndexRev #-}+getIndexRev :: -- (MonadIO m, Storable a) =>+ Ring a -> Int -> m a+getIndexRev = undefined++-------------------------------------------------------------------------------+-- Size+-------------------------------------------------------------------------------++-- | /O(1)/ Get the byte length of the array.+--+-- /Unimplemented/+{-# INLINE byteLength #-}+byteLength :: Ring a -> Int+byteLength = undefined++-- | /O(1)/ Get the length of the array i.e. the number of elements in the+-- array.+--+-- Note that 'byteLength' is less expensive than this operation, as 'length'+-- involves a costly division operation.+--+-- /Unimplemented/+{-# INLINE length #-}+length :: -- forall a. Storable a =>+ Ring a -> Int+length = undefined++-- | Get the total capacity of an array. An array may have space reserved+-- beyond the current used length of the array.+--+-- /Pre-release/+{-# INLINE byteCapacity #-}+byteCapacity :: Ring a -> Int+byteCapacity = undefined++-- | The remaining capacity in the array for appending more elements without+-- reallocation.+--+-- /Pre-release/+{-# INLINE bytesFree #-}+bytesFree :: Ring a -> Int+bytesFree = undefined++-------------------------------------------------------------------------------+-- Unfolds+-------------------------------------------------------------------------------++-- | Unfold a ring array into a stream.+--+-- /Unimplemented/+{-# INLINE_NORMAL read #-}+read :: -- forall m a. (MonadIO m, Storable a) =>+ Unfold m (Ring a) a+read = undefined++-- | Unfold a ring array into a stream in reverse order.+--+-- /Unimplemented/+{-# INLINE_NORMAL readRev #-}+readRev :: -- forall m a. (MonadIO m, Storable a) =>+ Unfold m (Array a) a+readRev = undefined++-------------------------------------------------------------------------------+-- Stream of arrays+-------------------------------------------------------------------------------++-- XXX Move this module to a lower level Ring/Type module and move ringsOf to a+-- higher level ring module where we can import "scan".++-- | @ringsOf n stream@ groups the input stream into a stream of+-- ring arrays of size n. Each ring is a sliding window of size n.+--+-- /Unimplemented/+{-# INLINE_NORMAL ringsOf #-}+ringsOf :: -- forall m a. (MonadIO m, Storable a) =>+ Int -> SerialT m a -> SerialT m (Array a)+ringsOf = undefined -- Stream.scan (writeN n)++-------------------------------------------------------------------------------+-- Casting+-------------------------------------------------------------------------------++-- | Cast an array having elements of type @a@ into an array having elements of+-- type @b@. The array size must be a multiple of the size of type @b@.+--+-- /Unimplemented/+--+castUnsafe :: Ring a -> Ring b+castUnsafe = undefined++-- | Cast an @Array a@ into an @Array Word8@.+--+-- /Unimplemented/+--+asBytes :: Ring a -> Ring Word8+asBytes = castUnsafe++-- | 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+-- target element otherwise 'Nothing' is returned.+--+-- /Pre-release/+--+cast :: forall a b. Storable b => Ring a -> Maybe (Ring b)+cast arr =+ let len = byteLength arr+ r = len `mod` sizeOf (undefined :: b)+ in if r /= 0+ then Nothing+ else Just $ castUnsafe arr++-------------------------------------------------------------------------------+-- Equality+-------------------------------------------------------------------------------+ -- XXX remove all usage of unsafeInlineIO -- -- | Like 'unsafeEqArray' but compares only N bytes instead of entire length of@@ -166,6 +420,11 @@ return (r1 && r2) in res +-------------------------------------------------------------------------------+-- Folding+-------------------------------------------------------------------------------++-- XXX We can unfold it into a stream and fold the stream instead. -- XXX use MonadIO -- -- | Fold the buffer starting from ringStart up to the given 'Ptr' using a pure
streamly.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.2 name: streamly-version: 0.8.1+version: 0.8.1.1 synopsis: Dataflow programming and declarative concurrency description: Browse the documentation at https://streamly.composewell.com.@@ -331,6 +331,9 @@ if os(linux) exposed-modules: Streamly.Internal.FileSystem.Event.Linux + if os(linux) || os(darwin) || os(windows)+ exposed-modules: Streamly.Internal.FileSystem.Event+ hs-source-dirs: src other-modules: Streamly.Data.Array@@ -505,7 +508,6 @@ , Streamly.Internal.FileSystem.File , Streamly.Internal.FileSystem.FDIO , Streamly.Internal.FileSystem.FD- , Streamly.Internal.FileSystem.Event -- streamly-console , Streamly.Internal.Console.Stdio