@@ -10,6 +10,7 @@ tests :: [TestTree]
1010tests = [
1111 runTest $ basicTest " basic space leak test"
1212 , runTest $ flagsTest " package with many flags"
13+ , runTest $ issue2899 " issue #2899"
1314 ]
1415
1516-- | This test solves for n packages that each have two versions. Backjumping
@@ -56,3 +57,38 @@ flagsTest name =
5657
5758 orderedFlags :: [ExampleVar ]
5859 orderedFlags = [F None " pkg" (flagName i) | i <- [1 .. n]]
60+
61+ -- | Test for a space leak caused by sharing of search trees under packages with
62+ -- link choices (issue #2899).
63+ --
64+ -- The goal order is fixed so that the solver chooses setup-dep and then
65+ -- target-setup.setup-dep at the top of the search tree. target-setup.setup-dep
66+ -- has two choices: link to setup-dep, and don't link to setup-dep. setup-dep
67+ -- has a long chain of dependencies (pkg-1 through pkg-n). However, pkg-n
68+ -- depends on pkg-n+1, which doesn't exist, so there is no solution. Since each
69+ -- dependency has two versions, the solver must try 2^n combinations when
70+ -- backjumping is disabled. These combinations create large search trees under
71+ -- each of the two choices for target-setup.setup-dep. Although the choice to
72+ -- not link is disallowed by the Single Instance Restriction, the solver doesn't
73+ -- know that until it has explored (and evaluated) the whole tree under the
74+ -- choice to link. If the two trees are shared, memory usage spikes.
75+ issue2899 :: String -> SolverTest
76+ issue2899 name =
77+ disableBackjumping $
78+ goalOrder goals $ mkTest pkgs name [" target" ] anySolverFailure
79+ where
80+ n :: Int
81+ n = 16
82+
83+ pkgs :: ExampleDb
84+ pkgs = map Right $
85+ [ exAv " target" 1 [ExAny " setup-dep" ] `withSetupDeps` [ExAny " setup-dep" ]
86+ , exAv " setup-dep" 1 [ExAny $ pkgName 1 ]]
87+ ++ [ exAv (pkgName i) v [ExAny $ pkgName (i + 1 )]
88+ | i <- [1 .. n], v <- [1 , 2 ]]
89+
90+ pkgName :: Int -> ExamplePkgName
91+ pkgName x = " pkg-" ++ show x
92+
93+ goals :: [ExampleVar ]
94+ goals = [P None " setup-dep" , P (Setup " target" ) " setup-dep" ]
0 commit comments