summaryrefslogtreecommitdiff
path: root/vendor/codeberg.org
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/codeberg.org')
-rw-r--r--vendor/codeberg.org/gruf/go-mmap/LICENSE9
-rw-r--r--vendor/codeberg.org/gruf/go-mmap/README.md3
-rw-r--r--vendor/codeberg.org/gruf/go-mmap/fs.go104
-rw-r--r--vendor/codeberg.org/gruf/go-mmap/mmap.go142
-rw-r--r--vendor/codeberg.org/gruf/go-mmap/open.go62
5 files changed, 320 insertions, 0 deletions
diff --git a/vendor/codeberg.org/gruf/go-mmap/LICENSE b/vendor/codeberg.org/gruf/go-mmap/LICENSE
new file mode 100644
index 000000000..d6f08d0ab
--- /dev/null
+++ b/vendor/codeberg.org/gruf/go-mmap/LICENSE
@@ -0,0 +1,9 @@
+MIT License
+
+Copyright (c) gruf
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/codeberg.org/gruf/go-mmap/README.md b/vendor/codeberg.org/gruf/go-mmap/README.md
new file mode 100644
index 000000000..76fc5fccd
--- /dev/null
+++ b/vendor/codeberg.org/gruf/go-mmap/README.md
@@ -0,0 +1,3 @@
+# go-mmap
+
+Optimized large file reads in Go \ No newline at end of file
diff --git a/vendor/codeberg.org/gruf/go-mmap/fs.go b/vendor/codeberg.org/gruf/go-mmap/fs.go
new file mode 100644
index 000000000..8c47d84b0
--- /dev/null
+++ b/vendor/codeberg.org/gruf/go-mmap/fs.go
@@ -0,0 +1,104 @@
+package mmap
+
+import (
+ "io/fs"
+ "path"
+ "syscall"
+ "time"
+)
+
+type fileStat struct {
+ syscall.Stat_t
+ name string
+ mode fs.FileMode
+}
+
+func (s *fileStat) Name() string { return s.name }
+func (s *fileStat) IsDir() bool { return s.mode.IsDir() }
+func (s *fileStat) Mode() fs.FileMode { return s.mode }
+func (s *fileStat) Size() int64 { return s.Stat_t.Size }
+func (s *fileStat) ModTime() time.Time { return time.Unix(s.Stat_t.Mtim.Unix()) }
+func (s *fileStat) Sys() any { return &s.Stat_t }
+
+// open is a simple wrapper around syscall.Open().
+func open(filepath string, mode int, perm uint32) (fd int, err error) {
+ err = retryOnEINTR(func() (err error) {
+ fd, err = syscall.Open(filepath, mode, perm)
+ return
+ })
+ return
+}
+
+// stat is a simple wrapper around syscall.Stat().
+func stat(filepath string) (*fileStat, error) {
+ var stat fileStat
+ err := retryOnEINTR(func() error {
+ return syscall.Stat(filepath, &stat.Stat_t)
+ })
+ if err != nil {
+ return nil, err
+ }
+ stat.name = path.Base(filepath)
+ stat.mode = fs.FileMode(stat.Stat_t.Mode & 0777)
+ switch stat.Stat_t.Mode & syscall.S_IFMT {
+ case syscall.S_IFBLK:
+ stat.mode |= fs.ModeDevice
+ case syscall.S_IFCHR:
+ stat.mode |= fs.ModeDevice | fs.ModeCharDevice
+ case syscall.S_IFDIR:
+ stat.mode |= fs.ModeDir
+ case syscall.S_IFIFO:
+ stat.mode |= fs.ModeNamedPipe
+ case syscall.S_IFLNK:
+ stat.mode |= fs.ModeSymlink
+ case syscall.S_IFREG:
+ // nothing to do
+ case syscall.S_IFSOCK:
+ stat.mode |= fs.ModeSocket
+ }
+ if stat.Stat_t.Mode&syscall.S_ISGID != 0 {
+ stat.mode |= fs.ModeSetgid
+ }
+ if stat.Stat_t.Mode&syscall.S_ISUID != 0 {
+ stat.mode |= fs.ModeSetuid
+ }
+ if stat.Stat_t.Mode&syscall.S_ISVTX != 0 {
+ stat.mode |= fs.ModeSticky
+ }
+ return &stat, nil
+}
+
+// mmap is a simple wrapper around syscall.Mmap().
+func mmap(fd int, offset int64, length int, prot int, flags int) (b []byte, err error) {
+ err = retryOnEINTR(func() error {
+ b, err = syscall.Mmap(fd, offset, length, prot, flags)
+ return err
+ })
+ return
+}
+
+// munmap is a simple wrapper around syscall.Munmap().
+func munmap(b []byte) error {
+ return retryOnEINTR(func() error {
+ return syscall.Munmap(b)
+ })
+}
+
+// close_ is a simple wrapper around syscall.Close().
+func close_(fd int) error {
+ return retryOnEINTR(func() error {
+ return syscall.Close(fd)
+ })
+}
+
+// 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-mmap/mmap.go b/vendor/codeberg.org/gruf/go-mmap/mmap.go
new file mode 100644
index 000000000..797ed3e73
--- /dev/null
+++ b/vendor/codeberg.org/gruf/go-mmap/mmap.go
@@ -0,0 +1,142 @@
+package mmap
+
+import (
+ "errors"
+ "io"
+ "io/fs"
+ "runtime"
+ "syscall"
+)
+
+// MmapFile maps file at path into memory using syscall.mmap(),
+// and returns a protected MmapReader{} for accessing the mapped data.
+// Note that the mapped memory is not concurrency safe (other than
+// concurrent ReadAt() calls). Any other calls made concurrently to
+// Read() or Close() (including ReadAt()) require protection.
+func MmapFile(path string) (*MmappedFile, error) {
+
+ // Stat file information.
+ stat, err := stat(path)
+ if err != nil {
+ return nil, err
+ }
+
+ // Mmap file into memory.
+ return openMmap(path, stat)
+}
+
+func openMmap(path string, stat *fileStat) (*MmappedFile, error) {
+ if stat.Size() <= 0 {
+ // Empty file, no-op read.
+ return &MmappedFile{}, nil
+ }
+
+ // Check file data size is accessible.
+ if stat.Size() != int64(int(stat.Size())) {
+ return nil, errors.New("file is too large")
+ }
+
+ // Open file at path for read-only access.
+ fd, err := open(path, syscall.O_RDONLY, 0)
+ if err != nil {
+ return nil, err
+ }
+
+ // Map this file into memory as slice.
+ mem, err := mmap(fd, 0, int(stat.Size()),
+ syscall.PROT_READ, syscall.MAP_PRIVATE)
+
+ // Done with file.
+ _ = close_(fd)
+
+ if err != nil {
+ return nil, err
+ }
+
+ // Return as wrapped reader type.
+ return newMmapReader(mem, stat), nil
+}
+
+// newMmapReader wraps a mapped memory slice in an
+// MmappedFile{}, also setting a GC finalizer function.
+func newMmapReader(mem []byte, stat *fileStat) *MmappedFile {
+ r := &MmappedFile{b: mem, s: stat}
+ runtime.SetFinalizer(r, (*MmappedFile).Close)
+ return r
+}
+
+type MmappedFile struct {
+ b []byte // mapped memory
+ n int // read index
+ s *fileStat // file info
+}
+
+func (r *MmappedFile) Name() string {
+ return r.s.name
+}
+
+func (r *MmappedFile) Stat() (fs.FileInfo, error) {
+ return r.s, nil
+}
+
+func (r *MmappedFile) Read(b []byte) (n int, err error) {
+ if r.n >= len(r.b) {
+ return 0, io.EOF
+ }
+ n = copy(b, r.b[r.n:])
+ r.n += n
+ return
+}
+
+func (r *MmappedFile) ReadAt(b []byte, off int64) (n int, err error) {
+ if off > int64(len(r.b)) {
+ return 0, io.EOF
+ }
+ n = copy(b, r.b[off:])
+ return n, nil
+}
+
+func (r *MmappedFile) WriteTo(w io.Writer) (int64, error) {
+ if r.n >= len(r.b) {
+ return 0, io.EOF
+ }
+ n, err := w.Write(r.b[r.n:])
+ r.n += n
+ return int64(n), err
+}
+
+func (r *MmappedFile) Seek(off int64, whence int) (int64, error) {
+ var n int
+ switch whence {
+ case io.SeekCurrent:
+ n = r.n + int(off)
+ case io.SeekStart:
+ n = 0 + int(off)
+ case io.SeekEnd:
+ n = len(r.b) + int(off)
+ default:
+ return 0, errors.New("invalid argument")
+ }
+ if n < 0 || n > len(r.b) {
+ return 0, errors.New("invalid argument")
+ }
+ r.n = n
+ return int64(n), nil
+}
+
+func (r *MmappedFile) Len() int {
+ return len(r.b) - r.n
+}
+
+func (r *MmappedFile) Size() int64 {
+ return int64(len(r.b))
+}
+
+func (r *MmappedFile) Close() error {
+ if b := r.b; b != nil {
+ r.b = nil
+ runtime.SetFinalizer(r, nil)
+ return munmap(b)
+ }
+ return nil
+}
diff --git a/vendor/codeberg.org/gruf/go-mmap/open.go b/vendor/codeberg.org/gruf/go-mmap/open.go
new file mode 100644
index 000000000..c12a091d3
--- /dev/null
+++ b/vendor/codeberg.org/gruf/go-mmap/open.go
@@ -0,0 +1,62 @@
+package mmap
+
+import (
+ "io"
+ "io/fs"
+ "os"
+ "runtime"
+ "syscall"
+)
+
+// MmapThreshold defines the threshold file size (in bytes) for which
+// a call to OpenRead() will deem as big enough for a file to be worth
+// opening using an `mmap` syscall. This is a runtime initialized number
+// based on the number of available CPUs as in concurrent conditions Go
+// can make optimizations for blocking `read` syscalls which scales with
+// the number of available goroutines it can have running at once.
+var MmapThreshold = int64(runtime.NumCPU() * syscall.Getpagesize())
+
+// FileReader defines the base interface
+// of a readable file, whether accessed
+// via `read` or `mmap` syscalls.
+type FileReader interface {
+ fs.File
+ io.ReaderAt
+ io.WriterTo
+ io.Seeker
+ Name() string
+}
+
+// Threshold is a receiving type for OpenRead()
+// that allows defining a custom MmapThreshold.
+type Threshold struct{ At int64 }
+
+// OpenRead: see mmap.OpenRead().
+func (t Threshold) OpenRead(path string) (FileReader, error) {
+ stat, err := stat(path)
+ if err != nil {
+ return nil, err
+ }
+ if stat.Size() >= t.At {
+ return openMmap(path, stat)
+ } else {
+ return os.OpenFile(path, syscall.O_RDONLY, 0)
+ }
+}
+
+// OpenRead will open the file as read only (erroring if it does
+// not already exist). If the file at path is beyond 'MmapThreshold'
+// it will be opened for reads using an `mmap` syscall, by calling
+// MmappedRead(path). Else, it will be opened using os.OpenFile().
+//
+// Please note that the reader returned by this function is not
+// guaranteed to be concurrency-safe. Calls returned by os.OpenFile()
+// follow the usual standard library concurrency guarantees, but the
+// reader returned by MmappedRead() provides no concurrent protection.
+//
+// Also note that this may not always be faster! If the file you need
+// to open will be immediately drained to another file, TCP or Unix
+// connection, then the standard library will used optimized syscalls.
+func OpenRead(path string) (FileReader, error) {
+ return Threshold{MmapThreshold}.OpenRead(path)
+}