From a2e80073bebdd346562bbe1c2ce6905c694e86bf Mon Sep 17 00:00:00 2001 From: ashmrtn <3891298+ashmrtn@users.noreply.github.com> Date: Mon, 4 Dec 2023 11:33:52 -0800 Subject: [PATCH] Rewrite remaining directory iteration during hierarchy merging (#4467) Switch the remaining call of iterating through directory entries to explicitly use the iterator instead of a helper function that takes a callback Mostly just just to switch everything over to the new iterator and to reduce indentation of things overall --- #### Does this PR need a docs update or release note? - [ ] :white_check_mark: Yes, it's included - [ ] :clock1: Yes, but in a later PR - [x] :no_entry: No #### Type of change - [ ] :sunflower: Feature - [ ] :bug: Bugfix - [ ] :world_map: Documentation - [x] :robot: Supportability/Tests - [ ] :computer: CI/Deployment - [x] :broom: Tech Debt/Cleanup #### Issue(s) * closes #4457 #### Test Plan - [ ] :muscle: Manual - [x] :zap: Unit test - [x] :green_heart: E2E --- src/internal/kopia/upload.go | 53 +++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 19 deletions(-) diff --git a/src/internal/kopia/upload.go b/src/internal/kopia/upload.go index de4f027cc..deced5bd4 100644 --- a/src/internal/kopia/upload.go +++ b/src/internal/kopia/upload.go @@ -1122,26 +1122,41 @@ func traverseBaseDir( var hasItems bool if changed { - err = fs.IterateEntries( - ctx, - dir, - func(innerCtx context.Context, entry fs.Entry) error { - dEntry, ok := entry.(fs.Directory) - if !ok { - hasItems = true - return nil - } + iter, err := dir.Iterate(ctx) + if err != nil { + return clues.WrapWC(ctx, err, "getting directory iterator") + } + + var entry fs.Entry + + // Need to keep err for the check after the loop as well so we also need to + // declare entry. + for entry, err = iter.Next(ctx); entry != nil && err == nil; entry, err = iter.Next(ctx) { + dEntry, ok := entry.(fs.Directory) + if !ok { + hasItems = true + continue + } + + err = traverseBaseDir( + ctx, + depth+1, + updatedPaths, + oldDirPath, + currentPath, + dEntry, + roots, + stats) + if err != nil { + // Break here instead of just returning so we can close the iterator. + // The error will be returned below. + err = clues.Stack(err) + break + } + } + + iter.Close() - return traverseBaseDir( - innerCtx, - depth+1, - updatedPaths, - oldDirPath, - currentPath, - dEntry, - roots, - stats) - }) if err != nil { return clues.WrapWC(ctx, err, "traversing base directory") }