1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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)
}
|