From cb06d8c935f1915fc010780cb72c1404fbe0b4a5 Mon Sep 17 00:00:00 2001 From: Rachel Culpepper <84159930+rculpepper@users.noreply.github.com> Date: Fri, 22 Sep 2023 14:03:53 +0000 Subject: [PATCH] backport of commit 68dd82c902ecf4487d9c17729527da9befb81a7f --- sdk/logical/storage.go | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/sdk/logical/storage.go b/sdk/logical/storage.go index 16ba60b94875..886ad51be781 100644 --- a/sdk/logical/storage.go +++ b/sdk/logical/storage.go @@ -97,6 +97,40 @@ func ScanView(ctx context.Context, view ClearableView, cb func(path string)) err return nil } +// AbortableScanView is used to scan all the keys in a view iteratively, +// but will abort the scan if cb returns false +func AbortableScanView(ctx context.Context, view ClearableView, cb func(path string) (cont bool)) error { + frontier := []string{""} + for len(frontier) > 0 { + n := len(frontier) + current := frontier[n-1] + frontier = frontier[:n-1] + + // List the contents + contents, err := view.List(ctx, current) + if err != nil { + return errwrap.Wrapf(fmt.Sprintf("list failed at path %q: {{err}}", current), err) + } + + // Handle the contents in the directory + for _, c := range contents { + // Exit if the context has been canceled + if ctx.Err() != nil { + return ctx.Err() + } + fullPath := current + c + if strings.HasSuffix(c, "/") { + frontier = append(frontier, fullPath) + } else { + if !cb(fullPath) { + return nil + } + } + } + } + return nil +} + // CollectKeys is used to collect all the keys in a view func CollectKeys(ctx context.Context, view ClearableView) ([]string, error) { return CollectKeysWithPrefix(ctx, view, "")