Skip to content

Commit 5caa9a5

Browse files
committed
refactor(fs): Convert fs dev mapper to singleton
1 parent 0009e58 commit 5caa9a5

2 files changed

Lines changed: 39 additions & 28 deletions

File tree

pkg/fs/dev.go

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -22,28 +22,39 @@
2222
package fs
2323

2424
import (
25-
"github.com/rabbitstack/fibratus/pkg/sys"
2625
"os"
2726
"strings"
27+
"sync"
28+
29+
"github.com/rabbitstack/fibratus/pkg/sys"
2830
)
2931

3032
const deviceOffset = 8
3133
const vmsmbDevice = `\Device\vmsmb`
3234

33-
// DevMapper is the minimal interface for the device converters.
34-
type DevMapper interface {
35-
// Convert receives the fully qualified file path and replaces the DOS device name with a drive letter.
36-
Convert(filename string) string
35+
var (
36+
devMapper *DevMapper
37+
onceDevMapper sync.Once
38+
)
39+
40+
// GetDevMapper builds and returns the singleton dev mapper instance.
41+
func GetDevMapper() *DevMapper {
42+
onceDevMapper.Do(func() {
43+
devMapper = newDevMapper()
44+
})
45+
return devMapper
3746
}
3847

39-
type mapper struct {
48+
// DevMapper converts the fully qualified file path and
49+
// replaces the DOS device name with a drive letter.
50+
type DevMapper struct {
4051
cache map[string]string
4152
sysroot string
4253
}
4354

44-
// NewDevMapper creates a new instance of the DOS device replacer.
45-
func NewDevMapper() DevMapper {
46-
m := &mapper{
55+
// newDevMapper creates a new instance of the DOS device replacer.
56+
func newDevMapper() *DevMapper {
57+
m := &DevMapper{
4758
cache: make(map[string]string),
4859
}
4960

@@ -65,39 +76,39 @@ func NewDevMapper() DevMapper {
6576
return m
6677
}
6778

68-
func (m *mapper) Convert(filename string) string {
69-
if filename == "" || len(filename) < deviceOffset {
70-
return filename
79+
func (m *DevMapper) Convert(path string) string {
80+
if path == "" || len(path) < deviceOffset {
81+
return path
7182
}
7283

7384
// find the backslash index
74-
n := strings.Index(filename[deviceOffset:], "\\")
85+
n := strings.Index(path[deviceOffset:], "\\")
7586
if n < 0 {
76-
if f, ok := m.cache[filename]; ok {
87+
if f, ok := m.cache[path]; ok {
7788
return f
7889
}
79-
return filename
90+
return path
8091
}
8192

82-
dev := filename[:n+deviceOffset]
93+
dev := path[:n+deviceOffset]
8394
if drive, ok := m.cache[dev]; ok {
8495
// the mapping for the DOS device exists
85-
return strings.Replace(filename, dev, drive, 1)
96+
return strings.Replace(path, dev, drive, 1)
8697
}
8798

8899
switch {
89100
case dev == vmsmbDevice:
90101
// convert Windows Sandbox path to native path
91-
if n := strings.Index(filename, "os"); n > 0 {
92-
return "C:" + filename[n+2:]
102+
if n := strings.Index(path, "os"); n > 0 {
103+
return "C:" + path[n+2:]
93104
}
94-
case strings.HasPrefix(filename, "\\SystemRoot"):
105+
case strings.HasPrefix(path, "\\SystemRoot"):
95106
// normalize paths starting with SystemRoot
96-
return strings.Replace(filename, "\\SystemRoot", m.sysroot, 1)
97-
case strings.HasPrefix(filename, "\\SYSTEMROOT"):
107+
return strings.Replace(path, "\\SystemRoot", m.sysroot, 1)
108+
case strings.HasPrefix(path, "\\SYSTEMROOT"):
98109
// normalize paths starting with SYSTEMROOT
99-
return strings.Replace(filename, "\\SYSTEMROOT", m.sysroot, 1)
110+
return strings.Replace(path, "\\SYSTEMROOT", m.sysroot, 1)
100111
}
101112

102-
return filename
113+
return path
103114
}

pkg/fs/dev_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ var drives = []string{
5858
"Z"}
5959

6060
func TestConvertDosDevice(t *testing.T) {
61-
m := NewDevMapper()
61+
m := GetDevMapper()
6262
files := make([]string, 0, len(drives))
6363

6464
for _, drive := range drives {
@@ -74,9 +74,9 @@ func TestConvertDosDevice(t *testing.T) {
7474
}
7575
assert.Contains(t, files, filename)
7676

77-
m.(*mapper).cache["\\Device\\HarddiskVolume1"] = "C:"
78-
m.(*mapper).cache["\\Device\\HarddiskVolume5"] = "\\Device\\HarddiskVolume5"
79-
m.(*mapper).sysroot = "C:\\Windows"
77+
m.cache["\\Device\\HarddiskVolume1"] = "C:"
78+
m.cache["\\Device\\HarddiskVolume5"] = "\\Device\\HarddiskVolume5"
79+
m.sysroot = "C:\\Windows"
8080

8181
var tests = []struct {
8282
inputFilename string

0 commit comments

Comments
 (0)