compact-list (empty) → 0.1.0
raw patch · 7 files changed
+182/−0 lines, 7 filesdep +basedep +compact-listdep +ghc-prim
Dependencies added: base, compact-list, ghc-prim
Files
- Changelog.md +3/−0
- LICENSE +27/−0
- README.md +13/−0
- compact-list.cabal +51/−0
- src/Data/CompactList.hs +75/−0
- stack.yaml +3/−0
- test/Main.hs +10/−0
+ Changelog.md view
@@ -0,0 +1,3 @@+## 0.1.0++* Initial release
+ LICENSE view
@@ -0,0 +1,27 @@+Copyright (c) 2018, Composewell Technologies+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++1. Redistributions of source code must retain the above copyright notice, this+list of conditions and the following disclaimer.++2. Redistributions in binary form must reproduce the above copyright notice,+this list of conditions and the following disclaimer in the documentation+and/or other materials provided with the distribution.++3. Neither the name of the copyright holder nor the names of its contributors+may be used to endorse or promote products derived from this software without+specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,13 @@+# compact-list++[](https://hackage.haskell.org/package/compact-list)+[](https://travis-ci.org/composewell/compact-list)+[](https://ci.appveyor.com/project/harendra-kumar/compact-list)++If you hold on to a large data structure in garbage collected (GC) memory+for relatively longer times it puts undue pressure on GC, unnecessarily+increasing the work done by GC and also increasing the duration of GC+pauses. A `CompactList` allows you to keep a large list in a Compact Region+not touched by GC, thus avoiding any GC overhead. This is essentially like+a convenient in-memory append only file where you can write a list of+Haskell values without having to marshall or serialize them.
+ compact-list.cabal view
@@ -0,0 +1,51 @@+name: compact-list+version: 0.1.0+synopsis: An append only list in a compact region+description:+ If you hold on to a large data structure in garbage collected (GC) memory+ for relatively longer times it puts undue pressure on GC, unnecessarily+ increasing the work done by GC and also increasing the duration of GC+ pauses. A 'CompactList' allows you to keep a large list in a Compact Region+ not touched by GC, thus avoiding any GC overhead. This is essentially like+ a convenient in-memory append only file where you can write a list of+ Haskell values without having to marshall or serialize them.++homepage: https://github.com/composewell/compact-list+bug-reports: https://github.com/composewell/compact-list/issues+license: BSD3+license-file: LICENSE+tested-with: GHC==8.2.2, GHC==8.4.3+author: Harendra Kumar+maintainer: harendra.kumar@gmail.com+copyright: 2018 Harendra Kumar+category: Data+stability: Experimental+build-type: Simple+cabal-version: >= 1.10++extra-source-files:+ Changelog.md+ README.md+ stack.yaml++source-repository head+ type: git+ location: https://github.com/composewell/compact-list++library+ hs-source-dirs: src+ exposed-modules: Data.CompactList+ default-language: Haskell2010+ ghc-options: -Wall+ build-depends: base >= 4.8 && < 5+ , ghc-prim >= 0.2 && < 0.6++test-suite test+ type: exitcode-stdio-1.0+ hs-source-dirs: test+ main-is: Main.hs+ build-depends:+ compact-list+ , base >= 4.8 && < 5+ default-language: Haskell2010+ ghc-options: -Wall -with-rtsopts "-s"
+ src/Data/CompactList.hs view
@@ -0,0 +1,75 @@+-- |+-- Module : Data.CompactList+-- Copyright : (c) 2018 Composewell Technologies+-- (c) 2001-14 GHC Project+--+-- License : BSD3+-- Maintainer : harendra.kumar@gmail.com+-- Stability : experimental+-- Portability : GHC+--+-- If you hold on to a large data structure in garbage collected (GC) memory+-- for relatively longer times it puts undue pressure on GC, unnecessarily+-- increasing the work done by GC and also increasing the duration of GC+-- pauses. A 'CompactList' allows you to keep a large list in a Compact Region+-- not touched by GC, thus avoiding any GC overhead. This is essentially like+-- a convenient in-memory append only file where you can write a list of+-- Haskell values without having to marshall or serialize them.+--+-- A 'CompactList' is like a thread safe 'IORef' to a list in compact region.++{-# LANGUAGE MagicHash #-}+{-# LANGUAGE UnboxedTuples #-}++module Data.CompactList+ ( CompactList+ , newCompactList+ , consCompactList+ , readCompactList+ ) where++import Control.Concurrent.MVar (MVar, newMVar, withMVar)+import GHC.IO (stToIO)+import GHC.Prim+ (Compact#, compactAdd#, compactNew#, int2Word#, RealWorld, State#)+import GHC.ST (ST(ST))+import GHC.STRef (STRef, newSTRef, readSTRef, writeSTRef)+import GHC.Types (Int(I#), IO(IO))++-- | A list with values of type @a@ living in a compact (non-GC) region.+data CompactList a = CompactList Compact# (STRef RealWorld [a]) (MVar ())++mkCompactList+ :: Compact# -> [a] -> State# RealWorld -> (# State# RealWorld, CompactList a #)+mkCompactList compact# as s =+ case unST (newSTRef as) s of { (# s0, ref #) ->+ case unIO (newMVar ()) s0 of { (# s1, lock #) ->+ (# s1, CompactList compact# ref lock #) } }+ where+ unST (ST a) = a+ unIO (IO a) = a++compactSized :: Int -> [a] -> IO (CompactList a)+compactSized (I# size) a = IO $ \s0 ->+ case compactNew# (int2Word# size) s0 of { (# s1, compact# #) ->+ case compactAdd# compact# a s1 of { (# s2, pk #) ->+ mkCompactList compact# pk s2 }}++-- | Make a new compact list from a list.+newCompactList :: [a] -> IO (CompactList a)+newCompactList = compactSized 31268++-- | Retrieve the compact list from the compact region.+readCompactList :: CompactList a -> IO [a]+readCompactList (CompactList _ ref _) = stToIO (readSTRef ref)++-- | Add an element at the head of the compact list. The modification is thread+-- safe.+consCompactList :: CompactList a -> a -> IO ()+consCompactList (CompactList compact# ref lock) x =+ withMVar lock $ \_ -> IO $ \s ->+ case unST (readSTRef ref) s of { (# s1, xs #) ->+ case compactAdd# compact# (x : xs) s1 of { (# s2, ys #) ->+ unST (writeSTRef ref ys) s2 }}+ where+ unST (ST a) = a
+ stack.yaml view
@@ -0,0 +1,3 @@+resolver: lts-12.5+packages:+- '.'
+ test/Main.hs view
@@ -0,0 +1,10 @@+import Data.CompactList+import Control.Monad (replicateM, void)++main :: IO ()+main = do+ ref <- newCompactList []+ void $ replicateM 1000000 $ do+ consCompactList ref ()+ return ()+ readCompactList ref >>= print . length