Skip to content

Commit ea69a59

Browse files
committed
llbsolver: Fix performance of recomputeDigests
Before this, in the case where nothing was mutated the visited memo would never be updated, thus causing exponential complexity. Now the memo is updated even when nothing is mutated, just setting old and new to be the same digest. Signed-off-by: Erik Sipsma <[email protected]>
1 parent 3b2b824 commit ea69a59

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

client/client_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ func TestIntegration(t *testing.T) {
194194
testMountStubsDirectory,
195195
testMountStubsTimestamp,
196196
testSourcePolicy,
197+
testLLBMountPerformance,
197198
)
198199
}
199200

@@ -8991,3 +8992,31 @@ func testSourcePolicy(t *testing.T, sb integration.Sandbox) {
89918992
require.ErrorContains(t, err, sourcepolicy.ErrSourceDenied.Error())
89928993
})
89938994
}
8995+
8996+
func testLLBMountPerformance(t *testing.T, sb integration.Sandbox) {
8997+
c, err := New(sb.Context(), sb.Address())
8998+
require.NoError(t, err)
8999+
defer c.Close()
9000+
9001+
mntInput := llb.Image("busybox:latest")
9002+
st := llb.Image("busybox:latest")
9003+
var mnts []llb.State
9004+
for i := 0; i < 20; i++ {
9005+
execSt := st.Run(
9006+
llb.Args([]string{"true"}),
9007+
)
9008+
mnts = append(mnts, mntInput)
9009+
for j := range mnts {
9010+
mnts[j] = execSt.AddMount(fmt.Sprintf("/tmp/bin%d", j), mnts[j], llb.SourcePath("/bin"))
9011+
}
9012+
st = execSt.Root()
9013+
}
9014+
9015+
def, err := st.Marshal(sb.Context())
9016+
require.NoError(t, err)
9017+
9018+
timeoutCtx, cancel := context.WithTimeout(sb.Context(), time.Minute)
9019+
defer cancel()
9020+
_, err = c.Solve(timeoutCtx, def, SolveOpt{}, nil)
9021+
require.NoError(t, err)
9022+
}

solver/llbsolver/vertex.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ func recomputeDigests(ctx context.Context, all map[digest.Digest]*pb.Op, visited
210210
}
211211

212212
if !mutated {
213+
visited[dgst] = dgst
213214
return dgst, nil
214215
}
215216

@@ -274,7 +275,7 @@ func loadLLB(ctx context.Context, def *pb.Definition, polEngine SourcePolicyEval
274275

275276
for {
276277
newDgst, ok := mutatedDigests[lastDgst]
277-
if !ok {
278+
if !ok || newDgst == lastDgst {
278279
break
279280
}
280281
lastDgst = newDgst

0 commit comments

Comments
 (0)