@@ -75,7 +75,7 @@ defaultPoolConfig
7575 -> (a -> IO () )
7676 -- ^ The action that destroys an existing resource.
7777 -> Double
78- -- ^ The amount of seconds for which an unused resource is kept around. The
78+ -- ^ The number of seconds for which an unused resource is kept around. The
7979 -- smallest acceptable value is @0.5@.
8080 --
8181 -- /Note:/ the elapsed time before destroying a resource may be a little
@@ -84,9 +84,8 @@ defaultPoolConfig
8484 -- ^ The maximum number of resources to keep open __across all stripes__. The
8585 -- smallest acceptable value is @1@ per stripe.
8686 --
87- -- /Note:/ for each stripe the number of resources is divided by the number of
88- -- stripes and rounded up, hence the pool might end up creating up to @N - 1@
89- -- resources more in total than specified, where @N@ is the number of stripes.
87+ -- /Note:/ if the number of stripes does not divide the number of resources,
88+ -- some of the stripes will have 1 more resource available than the others.
9089 -> PoolConfig a
9190defaultPoolConfig create free cacheTTL maxResources =
9291 PoolConfig
@@ -99,10 +98,10 @@ defaultPoolConfig create free cacheTTL maxResources =
9998
10099-- | Set the number of stripes (sub-pools) in the pool.
101100--
102- -- If not explicitly set, the default amount of stripes is 1, which should be
101+ -- If not explicitly set, the default number of stripes is 1, which should be
103102-- good for typical use (when in doubt, profile your application first).
104103--
105- -- If set to 'Nothing', the pool will create the amount of stripes equal to the
104+ -- If set to 'Nothing', the pool will create the number of stripes equal to the
106105-- number of capabilities.
107106--
108107-- /Note:/ usage of multiple stripes reduces contention, but can also result in
@@ -129,12 +128,13 @@ newPool pc = do
129128 error " numStripes must be at least 1"
130129 when (poolMaxResources pc < numStripes) $ do
131130 error " poolMaxResources must not be smaller than numStripes"
132- pools <- fmap (smallArrayFromListN numStripes) . forM [1 .. numStripes] $ \ n -> do
131+ let mkArray = fmap (smallArrayFromListN numStripes)
132+ pools <- mkArray . forM (stripeResources numStripes) $ \ (n, resources) -> do
133133 ref <- newIORef ()
134134 stripe <-
135135 newTVarIO
136136 Stripe
137- { available = poolMaxResources pc `quotCeil` numStripes
137+ { available = resources
138138 , cache = []
139139 , queue = Empty
140140 , queueR = Empty
@@ -161,10 +161,15 @@ newPool pc = do
161161 , reaperRef = ref
162162 }
163163 where
164- quotCeil :: Int -> Int -> Int
165- quotCeil x y =
166- -- Basically ceiling (x / y) without going through Double.
167- let (z, r) = x `quotRem` y in if r == 0 then z else z + 1
164+ stripeResources :: Int -> [(Int , Int )]
165+ stripeResources numStripes =
166+ let (base, rest) = quotRem (poolMaxResources pc) numStripes
167+ in zip [1 .. numStripes] $ addRest (replicate numStripes base) rest
168+ where
169+ addRest [] = error " unreachable"
170+ addRest acc@ (r : rs) = \ case
171+ 0 -> acc
172+ rest -> r + 1 : addRest rs (rest - 1 )
168173
169174 -- Collect stale resources from the pool once per second.
170175 collector pools = forever $ do
0 commit comments