169 lines
3.0 KiB
Go
169 lines
3.0 KiB
Go
|
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)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|