@@ -10,6 +10,7 @@ tests :: [TestTree]
10
10
tests = [
11
11
runTest $ basicTest " basic space leak test"
12
12
, runTest $ flagsTest " package with many flags"
13
+ , runTest $ issue2899 " issue #2899"
13
14
]
14
15
15
16
-- | This test solves for n packages that each have two versions. Backjumping
@@ -56,3 +57,38 @@ flagsTest name =
56
57
57
58
orderedFlags :: [ExampleVar ]
58
59
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