go.mod: github.com/opencontainers/runc v1.1.0
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
This commit is contained in:
		
							
								
								
									
										6
									
								
								vendor/github.com/opencontainers/selinux/pkg/pwalk/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								vendor/github.com/opencontainers/selinux/pkg/pwalk/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -8,6 +8,12 @@ By default, it utilizes 2\*runtime.NumCPU() goroutines for callbacks.
 | 
			
		||||
This can be changed by using WalkN function which has the additional
 | 
			
		||||
parameter, specifying the number of goroutines (concurrency).
 | 
			
		||||
 | 
			
		||||
### pwalk vs pwalkdir
 | 
			
		||||
 | 
			
		||||
This package is deprecated in favor of
 | 
			
		||||
[pwalkdir](https://pkg.go.dev/github.com/opencontainers/selinux/pkg/pwalkdir),
 | 
			
		||||
which is faster, but requires at least Go 1.16.
 | 
			
		||||
 | 
			
		||||
### Caveats
 | 
			
		||||
 | 
			
		||||
Please note the following limitations of this code:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										21
									
								
								vendor/github.com/opencontainers/selinux/pkg/pwalk/pwalk.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										21
									
								
								vendor/github.com/opencontainers/selinux/pkg/pwalk/pwalk.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,12 +1,11 @@
 | 
			
		||||
package pwalk
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"github.com/pkg/errors"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type WalkFunc = filepath.WalkFunc
 | 
			
		||||
@@ -20,7 +19,7 @@ type WalkFunc = filepath.WalkFunc
 | 
			
		||||
//
 | 
			
		||||
// Note that this implementation only supports primitive error handling:
 | 
			
		||||
//
 | 
			
		||||
// - no errors are ever passed to WalkFn;
 | 
			
		||||
// - no errors are ever passed to walkFn;
 | 
			
		||||
//
 | 
			
		||||
// - once a walkFn returns any error, all further processing stops
 | 
			
		||||
// and the error is returned to the caller of Walk;
 | 
			
		||||
@@ -42,7 +41,7 @@ func Walk(root string, walkFn WalkFunc) error {
 | 
			
		||||
func WalkN(root string, walkFn WalkFunc, num int) error {
 | 
			
		||||
	// make sure limit is sensible
 | 
			
		||||
	if num < 1 {
 | 
			
		||||
		return errors.Errorf("walk(%q): num must be > 0", root)
 | 
			
		||||
		return fmt.Errorf("walk(%q): num must be > 0", root)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	files := make(chan *walkArgs, 2*num)
 | 
			
		||||
@@ -52,6 +51,9 @@ func WalkN(root string, walkFn WalkFunc, num int) error {
 | 
			
		||||
	var (
 | 
			
		||||
		err error
 | 
			
		||||
		wg  sync.WaitGroup
 | 
			
		||||
 | 
			
		||||
		rootLen   = len(root)
 | 
			
		||||
		rootEntry *walkArgs
 | 
			
		||||
	)
 | 
			
		||||
	wg.Add(1)
 | 
			
		||||
	go func() {
 | 
			
		||||
@@ -60,6 +62,11 @@ func WalkN(root string, walkFn WalkFunc, num int) error {
 | 
			
		||||
				close(files)
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
			if len(p) == rootLen {
 | 
			
		||||
				// Root entry is processed separately below.
 | 
			
		||||
				rootEntry = &walkArgs{path: p, info: &info}
 | 
			
		||||
				return nil
 | 
			
		||||
			}
 | 
			
		||||
			// add a file to the queue unless a callback sent an error
 | 
			
		||||
			select {
 | 
			
		||||
			case e := <-errCh:
 | 
			
		||||
@@ -93,10 +100,14 @@ func WalkN(root string, walkFn WalkFunc, num int) error {
 | 
			
		||||
 | 
			
		||||
	wg.Wait()
 | 
			
		||||
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		err = walkFn(rootEntry.path, *rootEntry.info, nil)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// walkArgs holds the arguments that were passed to the Walk or WalkLimit
 | 
			
		||||
// walkArgs holds the arguments that were passed to the Walk or WalkN
 | 
			
		||||
// functions.
 | 
			
		||||
type walkArgs struct {
 | 
			
		||||
	path string
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										54
									
								
								vendor/github.com/opencontainers/selinux/pkg/pwalkdir/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								vendor/github.com/opencontainers/selinux/pkg/pwalkdir/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
			
		||||
## pwalkdir: parallel implementation of filepath.WalkDir
 | 
			
		||||
 | 
			
		||||
This is a wrapper for [filepath.WalkDir](https://pkg.go.dev/path/filepath#WalkDir)
 | 
			
		||||
which may speed it up by calling multiple callback functions (WalkDirFunc)
 | 
			
		||||
in parallel, utilizing goroutines.
 | 
			
		||||
 | 
			
		||||
By default, it utilizes 2\*runtime.NumCPU() goroutines for callbacks.
 | 
			
		||||
This can be changed by using WalkN function which has the additional
 | 
			
		||||
parameter, specifying the number of goroutines (concurrency).
 | 
			
		||||
 | 
			
		||||
### pwalk vs pwalkdir
 | 
			
		||||
 | 
			
		||||
This package is very similar to
 | 
			
		||||
[pwalk](https://pkg.go.dev/github.com/opencontainers/selinux/pkg/pwalkdir),
 | 
			
		||||
but utilizes `filepath.WalkDir` (added to Go 1.16), which does not call stat(2)
 | 
			
		||||
on every entry and is therefore faster (up to 3x, depending on usage scenario).
 | 
			
		||||
 | 
			
		||||
Users who are OK with requiring Go 1.16+ should switch to this
 | 
			
		||||
implementation.
 | 
			
		||||
 | 
			
		||||
### Caveats
 | 
			
		||||
 | 
			
		||||
Please note the following limitations of this code:
 | 
			
		||||
 | 
			
		||||
* Unlike filepath.WalkDir, the order of calls is non-deterministic;
 | 
			
		||||
 | 
			
		||||
* Only primitive error handling is supported:
 | 
			
		||||
 | 
			
		||||
  * fs.SkipDir is not supported;
 | 
			
		||||
 | 
			
		||||
  * no errors are ever passed to WalkDirFunc;
 | 
			
		||||
 | 
			
		||||
  * once any error is returned from any walkDirFunc instance, no more calls
 | 
			
		||||
    to WalkDirFunc are made, and the error is returned to the caller of WalkDir;
 | 
			
		||||
 | 
			
		||||
  * if more than one WalkDirFunc instance will return an error, only one
 | 
			
		||||
    of such errors will be propagated to and returned by WalkDir, others
 | 
			
		||||
    will be silently discarded.
 | 
			
		||||
 | 
			
		||||
### Documentation
 | 
			
		||||
 | 
			
		||||
For the official documentation, see
 | 
			
		||||
https://pkg.go.dev/github.com/opencontainers/selinux/pkg/pwalkdir
 | 
			
		||||
 | 
			
		||||
### Benchmarks
 | 
			
		||||
 | 
			
		||||
For a WalkDirFunc that consists solely of the return statement, this
 | 
			
		||||
implementation is about 15% slower than the standard library's
 | 
			
		||||
filepath.WalkDir.
 | 
			
		||||
 | 
			
		||||
Otherwise (if a WalkDirFunc is actually doing something) this is usually
 | 
			
		||||
faster, except when the WalkDirN(..., 1) is used. Run `go test -bench .`
 | 
			
		||||
to see how different operations can benefit from it, as well as how the
 | 
			
		||||
level of paralellism affects the speed.
 | 
			
		||||
							
								
								
									
										116
									
								
								vendor/github.com/opencontainers/selinux/pkg/pwalkdir/pwalkdir.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								vendor/github.com/opencontainers/selinux/pkg/pwalkdir/pwalkdir.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,116 @@
 | 
			
		||||
//go:build go1.16
 | 
			
		||||
// +build go1.16
 | 
			
		||||
 | 
			
		||||
package pwalkdir
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io/fs"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"sync"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Walk is a wrapper for filepath.WalkDir which can call multiple walkFn
 | 
			
		||||
// in parallel, allowing to handle each item concurrently. A maximum of
 | 
			
		||||
// twice the runtime.NumCPU() walkFn will be called at any one time.
 | 
			
		||||
// If you want to change the maximum, use WalkN instead.
 | 
			
		||||
//
 | 
			
		||||
// The order of calls is non-deterministic.
 | 
			
		||||
//
 | 
			
		||||
// Note that this implementation only supports primitive error handling:
 | 
			
		||||
//
 | 
			
		||||
// - no errors are ever passed to walkFn;
 | 
			
		||||
//
 | 
			
		||||
// - once a walkFn returns any error, all further processing stops
 | 
			
		||||
// and the error is returned to the caller of Walk;
 | 
			
		||||
//
 | 
			
		||||
// - filepath.SkipDir is not supported;
 | 
			
		||||
//
 | 
			
		||||
// - if more than one walkFn instance will return an error, only one
 | 
			
		||||
// of such errors will be propagated and returned by Walk, others
 | 
			
		||||
// will be silently discarded.
 | 
			
		||||
func Walk(root string, walkFn fs.WalkDirFunc) error {
 | 
			
		||||
	return WalkN(root, walkFn, runtime.NumCPU()*2)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WalkN is a wrapper for filepath.WalkDir which can call multiple walkFn
 | 
			
		||||
// in parallel, allowing to handle each item concurrently. A maximum of
 | 
			
		||||
// num walkFn will be called at any one time.
 | 
			
		||||
//
 | 
			
		||||
// Please see Walk documentation for caveats of using this function.
 | 
			
		||||
func WalkN(root string, walkFn fs.WalkDirFunc, num int) error {
 | 
			
		||||
	// make sure limit is sensible
 | 
			
		||||
	if num < 1 {
 | 
			
		||||
		return fmt.Errorf("walk(%q): num must be > 0", root)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	files := make(chan *walkArgs, 2*num)
 | 
			
		||||
	errCh := make(chan error, 1) // Get the first error, ignore others.
 | 
			
		||||
 | 
			
		||||
	// Start walking a tree asap.
 | 
			
		||||
	var (
 | 
			
		||||
		err error
 | 
			
		||||
		wg  sync.WaitGroup
 | 
			
		||||
 | 
			
		||||
		rootLen   = len(root)
 | 
			
		||||
		rootEntry *walkArgs
 | 
			
		||||
	)
 | 
			
		||||
	wg.Add(1)
 | 
			
		||||
	go func() {
 | 
			
		||||
		err = filepath.WalkDir(root, func(p string, entry fs.DirEntry, err error) error {
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				close(files)
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
			if len(p) == rootLen {
 | 
			
		||||
				// Root entry is processed separately below.
 | 
			
		||||
				rootEntry = &walkArgs{path: p, entry: entry}
 | 
			
		||||
				return nil
 | 
			
		||||
			}
 | 
			
		||||
			// Add a file to the queue unless a callback sent an error.
 | 
			
		||||
			select {
 | 
			
		||||
			case e := <-errCh:
 | 
			
		||||
				close(files)
 | 
			
		||||
				return e
 | 
			
		||||
			default:
 | 
			
		||||
				files <- &walkArgs{path: p, entry: entry}
 | 
			
		||||
				return nil
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
		if err == nil {
 | 
			
		||||
			close(files)
 | 
			
		||||
		}
 | 
			
		||||
		wg.Done()
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	wg.Add(num)
 | 
			
		||||
	for i := 0; i < num; i++ {
 | 
			
		||||
		go func() {
 | 
			
		||||
			for file := range files {
 | 
			
		||||
				if e := walkFn(file.path, file.entry, nil); e != nil {
 | 
			
		||||
					select {
 | 
			
		||||
					case errCh <- e: // sent ok
 | 
			
		||||
					default: // buffer full
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			wg.Done()
 | 
			
		||||
		}()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	wg.Wait()
 | 
			
		||||
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		err = walkFn(rootEntry.path, rootEntry.entry, nil)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// walkArgs holds the arguments that were passed to the Walk or WalkN
 | 
			
		||||
// functions.
 | 
			
		||||
type walkArgs struct {
 | 
			
		||||
	path  string
 | 
			
		||||
	entry fs.DirEntry
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user