Update mem to keep things private

This commit is contained in:
Steve Francia 2015-12-10 13:00:25 -05:00
parent 4b2ab283a0
commit 12f79b29b2
3 changed files with 69 additions and 34 deletions

View File

@ -20,3 +20,18 @@ type Dir interface {
Add(File) Add(File)
Remove(File) Remove(File)
} }
func RemoveFromMemDir(dir *File, f *File) {
dir.memDir.Remove(*f)
}
func AddToMemDir(dir *File, f *File) {
dir.memDir.Add(*f)
}
func InitializeDir(d *File) {
if d.memDir == nil {
d.dir = true
d.memDir = &DirMap{}
}
}

View File

@ -26,24 +26,45 @@ import (
import "time" import "time"
const FilePathSeparator = string(filepath.Separator)
type File struct { type File struct {
// atomic requires 64-bit alignment for struct field access // atomic requires 64-bit alignment for struct field access
at int64 at int64
readDirCount int64 readDirCount int64
FileName string
MemDir Dir
Dir bool
Mode os.FileMode
Modtime time.Time
sync.Mutex sync.Mutex
closed bool name string
data []byte data []byte
memDir Dir
dir bool
closed bool
mode os.FileMode
modtime time.Time
} }
func Create(name string) *File { func CreateFile(name string) *File {
return &File{FileName: name, Mode: os.ModeTemporary, Modtime: time.Now()} return &File{name: name, mode: os.ModeTemporary, modtime: time.Now()}
}
func CreateDir(name string) *File {
return &File{name: name, memDir: &DirMap{}, dir: true}
}
func ChangeFileName(f *File, newname string) {
f.name = newname
}
func SetMode(f *File, mode os.FileMode) {
f.mode = mode
}
func SetModTime(f *File, mtime time.Time) {
f.modtime = mtime
}
func GetFileInfo(f *File) *FileInfo {
return &FileInfo{file: f}
} }
func (f *File) Open() error { func (f *File) Open() error {
@ -63,7 +84,7 @@ func (f *File) Close() error {
} }
func (f *File) Name() string { func (f *File) Name() string {
return f.FileName return f.name
} }
func (f *File) Stat() (os.FileInfo, error) { func (f *File) Stat() (os.FileInfo, error) {
@ -78,7 +99,7 @@ func (f *File) Readdir(count int) (res []os.FileInfo, err error) {
var outLength int64 var outLength int64
f.Lock() f.Lock()
files := f.MemDir.Files()[f.readDirCount:] files := f.memDir.Files()[f.readDirCount:]
if count > 0 { if count > 0 {
if len(files) < count { if len(files) < count {
outLength = int64(len(files)) outLength = int64(len(files))
@ -198,27 +219,27 @@ func (f *File) WriteString(s string) (ret int, err error) {
} }
func (f *File) Info() *FileInfo { func (f *File) Info() *FileInfo {
return &FileInfo{File: f} return &FileInfo{file: f}
} }
type FileInfo struct { type FileInfo struct {
File *File file *File
} }
// Implements os.FileInfo // Implements os.FileInfo
func (s *FileInfo) Name() string { func (s *FileInfo) Name() string {
_, name := filepath.Split(s.File.Name()) _, name := filepath.Split(s.file.Name())
return name return name
} }
func (s *FileInfo) Mode() os.FileMode { return s.File.Mode } func (s *FileInfo) Mode() os.FileMode { return s.file.mode }
func (s *FileInfo) ModTime() time.Time { return s.File.Modtime } func (s *FileInfo) ModTime() time.Time { return s.file.modtime }
func (s *FileInfo) IsDir() bool { return s.File.Dir } func (s *FileInfo) IsDir() bool { return s.file.dir }
func (s *FileInfo) Sys() interface{} { return nil } func (s *FileInfo) Sys() interface{} { return nil }
func (s *FileInfo) Size() int64 { func (s *FileInfo) Size() int64 {
if s.IsDir() { if s.IsDir() {
return int64(42) return int64(42)
} }
return int64(len(s.File.data)) return int64(len(s.file.data))
} }
var ( var (

View File

@ -48,7 +48,7 @@ func (m *MemMapFs) getData() map[string]File {
// Root should always exist, right? // Root should always exist, right?
// TODO: what about windows? // TODO: what about windows?
m.data[FilePathSeparator] = &mem.File{FileName: FilePathSeparator, MemDir: &mem.DirMap{}, Dir: true} m.data[FilePathSeparator] = mem.CreateDir(FilePathSeparator)
} }
return m.data return m.data
} }
@ -66,7 +66,7 @@ func (MemMapFs) Name() string { return "MemMapFS" }
func (m *MemMapFs) Create(name string) (File, error) { func (m *MemMapFs) Create(name string) (File, error) {
name = normalizePath(name) name = normalizePath(name)
m.lock() m.lock()
file := mem.Create(name) file := mem.CreateFile(name)
m.getData()[name] = file m.getData()[name] = file
m.registerWithParent(file) m.registerWithParent(file)
m.unlock() m.unlock()
@ -86,7 +86,8 @@ func (m *MemMapFs) unRegisterWithParent(fileName string) {
log.Fatal("parent of ", f.Name(), " is nil") log.Fatal("parent of ", f.Name(), " is nil")
} }
pmem := parent.(*mem.File) pmem := parent.(*mem.File)
pmem.MemDir.Remove(*f.(*mem.File)) fmem := f.(*mem.File)
mem.RemoveFromMemDir(pmem, fmem)
} }
func (m *MemMapFs) findParent(f File) File { func (m *MemMapFs) findParent(f File) File {
@ -118,17 +119,14 @@ func (m *MemMapFs) registerWithParent(f File) {
} }
} }
pmem := parent.(*mem.File) pmem := parent.(*mem.File)
fmem := f.(*mem.File)
// TODO(mbertschler): memDir is only nil when it was not made with Mkdir // TODO(mbertschler): memDir is only nil when it was not made with Mkdir
// or lockfreeMkdir. In this case the parent is also not a real directory. // or lockfreeMkdir. In this case the parent is also not a real directory.
// This currently only happens for the file ".". // This currently only happens for the file ".".
// This is a quick hack to make the library usable with relative paths. // This is a quick hack to make the library usable with relative paths.
if pmem.MemDir == nil { mem.InitializeDir(pmem)
pmem.Dir = true mem.AddToMemDir(pmem, fmem)
pmem.MemDir = &mem.DirMap{}
}
pmem.MemDir.Add(*f.(*mem.File))
} }
func (m *MemMapFs) lockfreeMkdir(name string, perm os.FileMode) error { func (m *MemMapFs) lockfreeMkdir(name string, perm os.FileMode) error {
@ -144,7 +142,7 @@ func (m *MemMapFs) lockfreeMkdir(name string, perm os.FileMode) error {
return err return err
} }
} else { } else {
item := &mem.File{FileName: name, MemDir: &mem.DirMap{}, Dir: true} item := mem.CreateDir(name)
m.getData()[name] = item m.getData()[name] = item
m.registerWithParent(item) m.registerWithParent(item)
} }
@ -168,7 +166,7 @@ func (m *MemMapFs) Mkdir(name string, perm os.FileMode) error {
} }
} else { } else {
m.lock() m.lock()
item := &mem.File{FileName: name, MemDir: &mem.DirMap{}, Dir: true} item := mem.CreateDir(name)
m.getData()[name] = item m.getData()[name] = item
m.registerWithParent(item) m.registerWithParent(item)
m.unlock() m.unlock()
@ -305,7 +303,7 @@ func (m *MemMapFs) Rename(oldname, newname string) error {
m.unRegisterWithParent(oldname) m.unRegisterWithParent(oldname)
file := m.getData()[oldname].(*mem.File) file := m.getData()[oldname].(*mem.File)
delete(m.getData(), oldname) delete(m.getData(), oldname)
file.FileName = newname mem.ChangeFileName(file, newname)
m.getData()[newname] = file m.getData()[newname] = file
m.registerWithParent(file) m.registerWithParent(file)
m.unlock() m.unlock()
@ -324,7 +322,8 @@ func (m *MemMapFs) Stat(name string) (os.FileInfo, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &mem.FileInfo{File: f.(*mem.File)}, nil fi := mem.GetFileInfo(f.(*mem.File))
return fi, nil
} }
func (m *MemMapFs) Chmod(name string, mode os.FileMode) error { func (m *MemMapFs) Chmod(name string, mode os.FileMode) error {
@ -337,7 +336,7 @@ func (m *MemMapFs) Chmod(name string, mode os.FileMode) error {
ff, ok := f.(*mem.File) ff, ok := f.(*mem.File)
if ok { if ok {
m.lock() m.lock()
ff.Mode = mode mem.SetMode(ff, mode)
m.unlock() m.unlock()
} else { } else {
return errors.New("Unable to Chmod Memory File") return errors.New("Unable to Chmod Memory File")
@ -355,7 +354,7 @@ func (m *MemMapFs) Chtimes(name string, atime time.Time, mtime time.Time) error
ff, ok := f.(*mem.File) ff, ok := f.(*mem.File)
if ok { if ok {
m.lock() m.lock()
ff.Modtime = mtime mem.SetModTime(ff, mtime)
m.unlock() m.unlock()
} else { } else {
return errors.New("Unable to Chtime Memory File") return errors.New("Unable to Chtime Memory File")