sk-matrix-project/app/wails/pkg/sdk/system/file/manager.go

169 lines
3.0 KiB
Go
Raw Normal View History

2023-07-12 00:35:32 +08:00
package file
import (
"io/fs"
"os"
"path/filepath"
"skapp/pkg/logger"
"sync"
)
type Manager struct {
FileManager *sync.Map
lock *sync.RWMutex
}
func NewManager() *Manager {
return &Manager{
FileManager: &sync.Map{},
lock: &sync.RWMutex{},
}
}
func (m *Manager) Len() (count int64) {
defer func() {
m.lock.RUnlock()
}()
m.lock.RLock()
m.Each(func(file *os.File) bool {
count++
return true
})
return
}
func (m *Manager) Each(cb func(*os.File) bool) {
defer func() {
m.lock.RUnlock()
}()
m.lock.RLock()
m.FileManager.Range(func(key, value any) bool {
flagManager := value.(*sync.Map)
flagManager.Range(func(key, value any) bool {
fileModeManager := value.(*sync.Map)
fileModeManager.Range(func(key, value any) bool {
f := (value).(*os.File)
return cb(f)
})
return true
})
return true
})
}
func (m *Manager) Remove(path string, flag int, perm fs.FileMode) {
if m.Get(path, flag, perm) == nil {
return
}
defer func() {
m.lock.Unlock()
}()
m.lock.Lock()
absPath, err := filepath.Abs(path)
if err != nil {
return
}
logger.Log.Infof("Remove %+v %+v %+v\n", absPath, flag, perm)
var value interface{}
value, _ = m.FileManager.Load(absPath)
flagManager := value.(*sync.Map)
value, _ = flagManager.Load(flag)
fileModeManager := value.(*sync.Map)
value, _ = fileModeManager.LoadAndDelete(perm.String())
f := value.(*os.File)
_ = f.Close()
}
func (m *Manager) Get(path string, flag int, perm fs.FileMode) *os.File {
defer func() {
m.lock.RUnlock()
}()
m.lock.RLock()
absPath, err := filepath.Abs(path)
if err != nil {
return nil
}
logger.Log.Infof("Get %+v %+v %+v\n", absPath, flag, perm)
value, ok := m.FileManager.Load(absPath)
if !ok {
return nil
}
switch flagManager := value.(type) {
case *sync.Map:
value, ok := flagManager.Load(flag)
if !ok {
return nil
}
switch fileModeManager := value.(type) {
case *sync.Map:
f, ok := fileModeManager.Load(perm.String())
if !ok {
return nil
}
return f.(*os.File)
}
}
return nil
}
func (m *Manager) Close() {
m.Each(func(f *os.File) bool {
_ = f.Close()
return true
})
}
func (m *Manager) Set(file *os.File, path string, flag int, perm fs.FileMode) {
defer func() {
m.lock.Unlock()
}()
m.lock.Lock()
absPath, err := filepath.Abs(path)
if err != nil {
return
}
logger.Log.Infof("Set %+v %+v %+v\n", absPath, flag, perm)
value, ok := m.FileManager.Load(path)
if !ok {
flagManager := sync.Map{}
fileModeManager := sync.Map{}
fileModeManager.Store(perm.String(), file)
flagManager.Store(flag, &fileModeManager)
m.FileManager.Store(absPath, &flagManager)
return
}
switch flagManager := value.(type) {
case *sync.Map:
value, ok := flagManager.Load(flag)
if !ok {
fileModeManager := sync.Map{}
fileModeManager.Store(perm.String(), file)
flagManager.Store(flag, &fileModeManager)
}
switch fileModeManager := value.(type) {
case *sync.Map:
_, ok := fileModeManager.Load(perm.String())
if !ok {
fileModeManager.Store(perm.String(), file)
}
}
}
}