@@ -72,6 +72,7 @@ tests = [
7272 , runTest $ mkTest db9 " setupDeps7" [" F" , " G" ] (SolverSuccess [(" A" , 1 ), (" B" , 1 ), (" B" ,2 ), (" C" , 1 ), (" D" , 1 ), (" E" , 1 ), (" E" , 2 ), (" F" , 1 ), (" G" , 1 )])
7373 , runTest $ mkTest db10 " setupDeps8" [" C" ] (SolverSuccess [(" C" , 1 )])
7474 , runTest $ indep $ mkTest dbSetupDeps " setupDeps9" [" A" , " B" ] (SolverSuccess [(" A" , 1 ), (" B" , 1 ), (" C" , 1 ), (" D" , 1 ), (" D" , 2 )])
75+ , runTest $ issue2899 " issue 2899 space leak"
7576 ]
7677 , testGroup " Base shim" [
7778 runTest $ mkTest db11 " baseShim1" [" A" ] (SolverSuccess [(" A" , 1 )])
@@ -168,6 +169,9 @@ tests = [
168169indep :: SolverTest -> SolverTest
169170indep test = test { testIndepGoals = IndependentGoals True }
170171
172+ disableBj :: SolverTest -> SolverTest
173+ disableBj test = test { testEnableBackjumping = EnableBackjumping False }
174+
171175goalOrder :: [ExampleVar ] -> SolverTest -> SolverTest
172176goalOrder order test = test { testGoalOrder = Just order }
173177
@@ -182,6 +186,7 @@ data SolverTest = SolverTest {
182186 , testTargets :: [String ]
183187 , testResult :: SolverResult
184188 , testIndepGoals :: IndependentGoals
189+ , testEnableBackjumping :: EnableBackjumping
185190 , testGoalOrder :: Maybe [ExampleVar ]
186191 , testSoftConstraints :: [ExPreference ]
187192 , testDb :: ExampleDb
@@ -257,6 +262,7 @@ mkTestExtLangPC exts langs pkgConfigDb db label targets result = SolverTest {
257262 , testTargets = targets
258263 , testResult = result
259264 , testIndepGoals = IndependentGoals False
265+ , testEnableBackjumping = EnableBackjumping True
260266 , testGoalOrder = Nothing
261267 , testSoftConstraints = []
262268 , testDb = db
@@ -271,7 +277,7 @@ runTest SolverTest{..} = askOption $ \(OptionShowSolverLog showSolverLog) ->
271277 let lg = exResolve testDb testSupportedExts
272278 testSupportedLangs testPkgConfigDb testTargets
273279 Modular Nothing testIndepGoals (ReorderGoals False )
274- ( EnableBackjumping True ) testGoalOrder testSoftConstraints
280+ testEnableBackjumping testGoalOrder testSoftConstraints
275281 logMsg msg = if showSolverLog
276282 then putStrLn msg
277283 else return ()
@@ -503,6 +509,39 @@ dbSetupDeps = [
503509 , Right $ exAv " D" 2 []
504510 ]
505511
512+ -- | Test for a space leak caused by sharing of search trees under packages with
513+ -- link choices (issue #2899).
514+ --
515+ -- The goal order is fixed so that the solver chooses setup-dep and then
516+ -- target-setup.setup-dep at the top of the search tree. target-setup.setup-dep
517+ -- has two choices: link to setup-dep, and don't link to setup-dep. setup-dep
518+ -- has a long chain of dependencies (pkg-1 through pkg-n). However, pkg-n
519+ -- depends on pkg-n+1, which doesn't exist, so there is no solution. Since each
520+ -- dependency has two versions, the solver must try 2^n combinations when
521+ -- backjumping is disabled. These combinations create large search trees under
522+ -- each of the two choices for target-setup.setup-dep. Although the choice to
523+ -- not link is disallowed by the Single Instance Restriction, the solver doesn't
524+ -- know that until it has explored (and evaluated) the whole tree under the
525+ -- choice to link. If the two trees are shared, memory usage spikes.
526+ issue2899 :: String -> SolverTest
527+ issue2899 name =
528+ disableBj $ goalOrder goals $ mkTest pkgs name [" target" ] anySolverFailure
529+ where
530+ n :: Int
531+ n = 14
532+
533+ pkgs = map Right $
534+ [ exAv " target" 1 [ExAny " setup-dep" ] `withSetupDeps` [ExAny " setup-dep" ]
535+ , exAv " setup-dep" 1 [ExAny " pkg-1" ]]
536+ ++ [ exAv (pkgName i) v [ExAny $ pkgName (i + 1 )]
537+ | i <- [1 .. n], v <- [1 , 2 ]]
538+
539+ pkgName :: Int -> String
540+ pkgName x = " pkg-" ++ show x
541+
542+ goals :: [ExampleVar ]
543+ goals = [P None " setup-dep" , P (Setup " target" ) " setup-dep" ]
544+
506545-- | Tests for dealing with base shims
507546db11 :: ExampleDb
508547db11 =
0 commit comments