Skip to content

Commit 5d94a62

Browse files
authored
Geofiles: Implement mmap in filesystem to reduce ram usage (#5480)
For #4422
1 parent ad468e4 commit 5d94a62

2 files changed

Lines changed: 80 additions & 0 deletions

File tree

common/platform/filesystem/file.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
//go:build !windows && !wasm
2+
13
package filesystem
24

35
import (
46
"io"
57
"os"
68
"path/filepath"
9+
"syscall"
710

811
"github.com/xtls/xray-core/common/buf"
912
"github.com/xtls/xray-core/common/platform"
@@ -16,6 +19,29 @@ var NewFileReader FileReaderFunc = func(path string) (io.ReadCloser, error) {
1619
}
1720

1821
func ReadFile(path string) ([]byte, error) {
22+
file, err := os.Open(path)
23+
if err != nil {
24+
return nil, err
25+
}
26+
defer file.Close()
27+
28+
stat, err := file.Stat()
29+
if err != nil {
30+
return nil, err
31+
}
32+
33+
size := stat.Size()
34+
if size == 0 {
35+
return []byte{}, nil
36+
}
37+
38+
// use mmap to save RAM
39+
bs, err := syscall.Mmap(int(file.Fd()), 0, int(size), syscall.PROT_READ, syscall.MAP_SHARED)
40+
if err == nil {
41+
return bs, nil
42+
}
43+
44+
// fallback
1945
reader, err := NewFileReader(path)
2046
if err != nil {
2147
return nil, err
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
//go:build windows || wasm
2+
3+
package filesystem
4+
5+
import (
6+
"io"
7+
"os"
8+
"path/filepath"
9+
10+
"github.com/xtls/xray-core/common/buf"
11+
"github.com/xtls/xray-core/common/platform"
12+
)
13+
14+
type FileReaderFunc func(path string) (io.ReadCloser, error)
15+
16+
var NewFileReader FileReaderFunc = func(path string) (io.ReadCloser, error) {
17+
return os.Open(path)
18+
}
19+
20+
func ReadFile(path string) ([]byte, error) {
21+
reader, err := NewFileReader(path)
22+
if err != nil {
23+
return nil, err
24+
}
25+
defer reader.Close()
26+
27+
return buf.ReadAllToBytes(reader)
28+
}
29+
30+
func ReadAsset(file string) ([]byte, error) {
31+
return ReadFile(platform.GetAssetLocation(file))
32+
}
33+
34+
func ReadCert(file string) ([]byte, error) {
35+
if filepath.IsAbs(file) {
36+
return ReadFile(file)
37+
}
38+
return ReadFile(platform.GetCertLocation(file))
39+
}
40+
41+
func CopyFile(dst string, src string) error {
42+
bytes, err := ReadFile(src)
43+
if err != nil {
44+
return err
45+
}
46+
f, err := os.OpenFile(dst, os.O_CREATE|os.O_WRONLY, 0o644)
47+
if err != nil {
48+
return err
49+
}
50+
defer f.Close()
51+
52+
_, err = f.Write(bytes)
53+
return err
54+
}

0 commit comments

Comments
 (0)