int-supply (empty) → 1.0.0
raw patch · 5 files changed
+157/−0 lines, 5 filesdep +base
Dependencies added: base
Files
- CHANGELOG.md +3/−0
- LICENSE +11/−0
- README.md +7/−0
- int-supply.cabal +50/−0
- src/IntSupply.hs +86/−0
+ CHANGELOG.md view
@@ -0,0 +1,3 @@+## [1.0.0] - November 27, 2023++- Initial release
+ LICENSE view
@@ -0,0 +1,11 @@+Copyright 2023 Mitchell Rosen, Travis Staton++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,7 @@+# `int-supply`++[](https://github.com/awkward-squad/int-supply/actions)+[](https://hackage.haskell.org/package/int-supply)+[](https://www.stackage.org/lts/package/int-supply)+[](https://www.stackage.org/nightly/package/int-supply)+[](https://packdeps.haskellers.com/reverse/int-supply)
+ int-supply.cabal view
@@ -0,0 +1,50 @@+cabal-version: 2.4++category: Data+author: Mitchell Rosen, Travis Staton+bug-reports: https://github.com/awkward-squad/int-supply/issues+build-type: Simple+copyright: (c) 2023 Mitchell Rosen, Travis Staton+description: This package provides a simple, efficient supply of integers using atomic fetch-and-add.+homepage: https://github.com/awkward-squad/int-supply+license: BSD-3-Clause+license-file: LICENSE+maintainer: Mitchell Rosen <mitchellwrosen@gmail.com>, Travis Staton <hello@travisstaton.com>+name: int-supply+synopsis: A simple, efficient supply of integers using atomic fetch-and-add.+tested-with: GHC == 9.4.8, GHC == 9.6.3, GHC == 9.8.1+version: 1.0.0++extra-doc-files:+ CHANGELOG.md+ README.md++source-repository head+ type: git+ location: git://github.com/awkward-squad/int-supply.git++library+ build-depends:+ base ^>= 4.13 || ^>= 4.14 || ^>= 4.15 || ^>= 4.16 || ^>= 4.17 || ^>= 4.18 || ^>= 4.19+ default-language: Haskell2010+ exposed-modules: IntSupply+ ghc-options:+ -Weverything+ -Wno-all-missed-specialisations+ -Wno-implicit-prelude+ -Wno-missing-import-lists+ -Wno-missing-local-signatures+ -Wno-monomorphism-restriction+ -Wno-safe+ -Wno-unsafe+ if impl(ghc >= 8.10)+ ghc-options:+ -Wno-missing-safe-haskell-mode+ -Wno-prepositive-qualified-module+ if impl(ghc >= 9.2)+ ghc-options:+ -Wno-missing-kind-signatures+ if impl(ghc >= 9.8)+ ghc-options:+ -Wno-missing-role-annotations+ hs-source-dirs: src
+ src/IntSupply.hs view
@@ -0,0 +1,86 @@+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE BlockArguments #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE UnboxedTuples #-}++-- | This module provides a simple, efficient supply of integers using atomic fetch-and-add.+--+-- To use this module, first create an @IntSupply@. This is often done once at the top level of an application, in+-- global scope.+--+-- > import IntSupply (IntSupply)+-- > import IntSupply qualified+-- > import System.IO.Unsafe (unsafePerformIO)+-- >+-- > myIntSupply :: IntSupply+-- > myIntSupply = unsafePerformIO IntSupply.new+-- > {-# NOINLINE myIntSupply #-}+--+-- Next, call @IntSupply.next@ on the supply, which will return 0, then 1, and so on.+--+-- > > IntSupply.next myIntSupply+-- > 0+-- > > IntSupply.next myIntSupply+-- > 1+--+-- If desired, you can reset the count to 0.+--+-- > > IntSupply.reset myIntSupply+-- > > IntSupply.next myIntSupply+-- > 0+--+-- On a 64-bit machine, for many applications, these integers can be treated as effectively unique: even if+-- 1,000,000,000 integers were generated per second, it would still take over 580 years to wrap around.+--+-- On a 32-bit machine, more care must be taken, of course: even if only 1,000 integers were generated per second, it+-- would only take 50 days to wrap around.+module IntSupply+ ( IntSupply,+ new,+ next,+ reset,+ )+where++import Data.Bits (finiteBitSize)+import GHC.Base+ ( IO (IO),+ Int (I#),+ MutableByteArray#,+ RealWorld,+ atomicWriteIntArray#,+ fetchAddIntArray#,+ newByteArray#,+ writeIntArray#,+ )++-- | A thread-safe supply of integers.+data IntSupply+ = IntSupply (MutableByteArray# RealWorld)++-- | Create a supply of integers.+new :: IO IntSupply+new =+ IO \s0 ->+ case newByteArray# size s0 of+ (# s1, supply #) ->+ (# writeIntArray# supply 0# 0# s1, IntSupply supply #)+ where+ !(I# size) =+ finiteBitSize (undefined :: Int) `div` 8+{-# INLINEABLE new #-}++-- | Get the next integer from a supply of integers.+next :: IntSupply -> IO Int+next (IntSupply supply) =+ IO \s0 ->+ case fetchAddIntArray# supply 0# 1# s0 of+ (# s1, n #) -> (# s1, I# n #)+{-# INLINEABLE next #-}++-- | Reset a supply of integers to 0.+reset :: IntSupply -> IO ()+reset (IntSupply arr#) =+ IO \s0 ->+ (# atomicWriteIntArray# arr# 0# 0# s0, () #)+{-# INLINEABLE reset #-}