diff options
Diffstat (limited to 'vendor/codeberg.org/gruf/go-store/util')
| -rw-r--r-- | vendor/codeberg.org/gruf/go-store/util/fs.go | 105 | ||||
| -rw-r--r-- | vendor/codeberg.org/gruf/go-store/util/io.go | 42 | ||||
| -rw-r--r-- | vendor/codeberg.org/gruf/go-store/util/pool.go | 20 | 
3 files changed, 167 insertions, 0 deletions
| diff --git a/vendor/codeberg.org/gruf/go-store/util/fs.go b/vendor/codeberg.org/gruf/go-store/util/fs.go new file mode 100644 index 000000000..fa6a9d2c4 --- /dev/null +++ b/vendor/codeberg.org/gruf/go-store/util/fs.go @@ -0,0 +1,105 @@ +package util + +import ( +	"io/fs" +	"os" +	"strings" +	"syscall" + +	"codeberg.org/gruf/go-fastpath" +) + +var dotdot = "../" + +// CountDotdots returns the number of "dot-dots" (../) in a cleaned filesystem path +func CountDotdots(path string) int { +	if !strings.HasSuffix(path, dotdot) { +		return 0 +	} +	return strings.Count(path, dotdot) +} + +// WalkDir traverses the dir tree of the supplied path, performing the supplied walkFn on each entry +func WalkDir(pb *fastpath.Builder, path string, walkFn func(string, fs.DirEntry)) error { +	// Read supplied dir path +	dirEntries, err := os.ReadDir(path) +	if err != nil { +		return err +	} + +	// Iter entries +	for _, entry := range dirEntries { +		// Pass to walk fn +		walkFn(path, entry) + +		// Recurse dir entries +		if entry.IsDir() { +			err = WalkDir(pb, pb.Join(path, entry.Name()), walkFn) +			if err != nil { +				return err +			} +		} +	} + +	return nil +} + +// CleanDirs traverses the dir tree of the supplied path, removing any folders with zero children +func CleanDirs(path string) error { +	// Acquire builder +	pb := GetPathBuilder() +	defer PutPathBuilder(pb) + +	// Get dir entries +	entries, err := os.ReadDir(path) +	if err != nil { +		return err +	} + +	// Recurse dirs +	for _, entry := range entries { +		if entry.IsDir() { +			err := cleanDirs(pb, pb.Join(path, entry.Name())) +			if err != nil { +				return err +			} +		} +	} +	return nil +} + +// cleanDirs performs the actual dir cleaning logic for the exported version +func cleanDirs(pb *fastpath.Builder, path string) error { +	// Get dir entries +	entries, err := os.ReadDir(path) +	if err != nil { +		return err +	} + +	// If no entries, delete +	if len(entries) < 1 { +		return os.Remove(path) +	} + +	// Recurse dirs +	for _, entry := range entries { +		if entry.IsDir() { +			err := cleanDirs(pb, pb.Join(path, entry.Name())) +			if err != nil { +				return err +			} +		} +	} +	return nil +} + +// RetryOnEINTR is a low-level filesystem function for retrying syscalls on O_EINTR received +func RetryOnEINTR(do func() error) error { +	for { +		err := do() +		if err == syscall.EINTR { +			continue +		} +		return err +	} +} diff --git a/vendor/codeberg.org/gruf/go-store/util/io.go b/vendor/codeberg.org/gruf/go-store/util/io.go new file mode 100644 index 000000000..d034cf62b --- /dev/null +++ b/vendor/codeberg.org/gruf/go-store/util/io.go @@ -0,0 +1,42 @@ +package util + +import "io" + +// NopReadCloser turns a supplied io.Reader into io.ReadCloser with a nop Close() implementation +func NopReadCloser(r io.Reader) io.ReadCloser { +	return &nopReadCloser{r} +} + +// NopWriteCloser turns a supplied io.Writer into io.WriteCloser with a nop Close() implementation +func NopWriteCloser(w io.Writer) io.WriteCloser { +	return &nopWriteCloser{w} +} + +// ReadCloserWithCallback adds a customizable callback to be called upon Close() of a supplied io.ReadCloser +func ReadCloserWithCallback(rc io.ReadCloser, cb func()) io.ReadCloser { +	return &callbackReadCloser{ +		ReadCloser: rc, +		callback:   cb, +	} +} + +// nopReadCloser turns an io.Reader -> io.ReadCloser with a nop Close() +type nopReadCloser struct{ io.Reader } + +func (r *nopReadCloser) Close() error { return nil } + +// nopWriteCloser turns an io.Writer -> io.WriteCloser with a nop Close() +type nopWriteCloser struct{ io.Writer } + +func (w nopWriteCloser) Close() error { return nil } + +// callbackReadCloser allows adding our own custom callback to an io.ReadCloser +type callbackReadCloser struct { +	io.ReadCloser +	callback func() +} + +func (c *callbackReadCloser) Close() error { +	defer c.callback() +	return c.ReadCloser.Close() +} diff --git a/vendor/codeberg.org/gruf/go-store/util/pool.go b/vendor/codeberg.org/gruf/go-store/util/pool.go new file mode 100644 index 000000000..8400cb5b7 --- /dev/null +++ b/vendor/codeberg.org/gruf/go-store/util/pool.go @@ -0,0 +1,20 @@ +package util + +import ( +	"codeberg.org/gruf/go-fastpath" +	"codeberg.org/gruf/go-pools" +) + +// pathBuilderPool is the global fastpath.Builder pool +var pathBuilderPool = pools.NewPathBuilderPool(512) + +// GetPathBuilder fetches a fastpath.Builder object from the pool +func GetPathBuilder() *fastpath.Builder { +	return pathBuilderPool.Get() +} + +// PutPathBuilder places supplied fastpath.Builder back in the pool +func PutPathBuilder(pb *fastpath.Builder) { +	pb.Reset() +	pathBuilderPool.Put(pb) +} | 
