diff --git a/mem/dir.go b/mem/dir.go index 02f632e..0767dc9 100644 --- a/mem/dir.go +++ b/mem/dir.go @@ -20,19 +20,3 @@ type Dir interface { Add(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{} - } - -} diff --git a/mem/file.go b/mem/file.go index 4a652cb..692077a 100644 --- a/mem/file.go +++ b/mem/file.go @@ -26,45 +26,24 @@ import ( import "time" -const FilePathSeparator = string(filepath.Separator) - type File struct { // atomic requires 64-bit alignment for struct field access at int64 readDirCount int64 + FileName string + MemDir Dir + Dir bool + Mode os.FileMode + Modtime time.Time + sync.Mutex - name string - data []byte - memDir Dir - dir bool - closed bool - mode os.FileMode - modtime time.Time + closed bool + data []byte } -func CreateFile(name string) *File { - return &File{name: name, mode: os.ModeTemporary, modtime: time.Now()} -} - -func CreateDir(name string) *File { - return &File{name: FilePathSeparator, 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 Create(name string) *File { + return &File{FileName: name, Mode: os.ModeTemporary, Modtime: time.Now()} } func (f *File) Open() error { @@ -84,7 +63,7 @@ func (f *File) Close() error { } func (f *File) Name() string { - return f.name + return f.FileName } func (f *File) Stat() (os.FileInfo, error) { @@ -99,7 +78,7 @@ func (f *File) Readdir(count int) (res []os.FileInfo, err error) { var outLength int64 f.Lock() - files := f.memDir.Files()[f.readDirCount:] + files := f.MemDir.Files()[f.readDirCount:] if count > 0 { if len(files) < count { outLength = int64(len(files)) @@ -219,27 +198,27 @@ func (f *File) WriteString(s string) (ret int, err error) { } func (f *File) Info() *FileInfo { - return &FileInfo{file: f} + return &FileInfo{File: f} } type FileInfo struct { - file *File + File *File } // Implements os.FileInfo func (s *FileInfo) Name() string { - _, name := filepath.Split(s.file.Name()) + _, name := filepath.Split(s.File.Name()) return name } -func (s *FileInfo) Mode() os.FileMode { return s.file.mode } -func (s *FileInfo) ModTime() time.Time { return s.file.modtime } -func (s *FileInfo) IsDir() bool { return s.file.dir } +func (s *FileInfo) Mode() os.FileMode { return s.File.Mode } +func (s *FileInfo) ModTime() time.Time { return s.File.Modtime } +func (s *FileInfo) IsDir() bool { return s.File.Dir } func (s *FileInfo) Sys() interface{} { return nil } func (s *FileInfo) Size() int64 { if s.IsDir() { return int64(42) } - return int64(len(s.file.data)) + return int64(len(s.File.data)) } var ( diff --git a/memmap.go b/memmap.go index 0263953..88c390f 100644 --- a/memmap.go +++ b/memmap.go @@ -48,7 +48,7 @@ func (m *MemMapFs) getData() map[string]File { // Root should always exist, right? // TODO: what about windows? - m.data[FilePathSeparator] = mem.CreateDir(FilePathSeparator) + m.data[FilePathSeparator] = &mem.File{FileName: FilePathSeparator, MemDir: &mem.DirMap{}, Dir: true} } return m.data } @@ -66,7 +66,7 @@ func (MemMapFs) Name() string { return "MemMapFS" } func (m *MemMapFs) Create(name string) (File, error) { name = normalizePath(name) m.lock() - file := mem.CreateFile(name) + file := mem.Create(name) m.getData()[name] = file m.registerWithParent(file) m.unlock() @@ -86,8 +86,7 @@ func (m *MemMapFs) unRegisterWithParent(fileName string) { log.Fatal("parent of ", f.Name(), " is nil") } pmem := parent.(*mem.File) - fmem := f.(*mem.File) - mem.RemoveFromMemDir(pmem, fmem) + pmem.MemDir.Remove(*f.(*mem.File)) } func (m *MemMapFs) findParent(f File) File { @@ -119,14 +118,17 @@ func (m *MemMapFs) registerWithParent(f File) { } } pmem := parent.(*mem.File) - fmem := f.(*mem.File) // 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. // This currently only happens for the file ".". // This is a quick hack to make the library usable with relative paths. - mem.InitializeDir(pmem) - mem.AddToMemDir(pmem, fmem) + if pmem.MemDir == nil { + pmem.Dir = true + pmem.MemDir = &mem.DirMap{} + } + + pmem.MemDir.Add(*f.(*mem.File)) } func (m *MemMapFs) lockfreeMkdir(name string, perm os.FileMode) error { @@ -142,7 +144,7 @@ func (m *MemMapFs) lockfreeMkdir(name string, perm os.FileMode) error { return err } } else { - item := mem.CreateDir(name) + item := &mem.File{FileName: name, MemDir: &mem.DirMap{}, Dir: true} m.getData()[name] = item m.registerWithParent(item) } @@ -166,7 +168,7 @@ func (m *MemMapFs) Mkdir(name string, perm os.FileMode) error { } } else { m.lock() - item := mem.CreateDir(name) + item := &mem.File{FileName: name, MemDir: &mem.DirMap{}, Dir: true} m.getData()[name] = item m.registerWithParent(item) m.unlock() @@ -303,7 +305,7 @@ func (m *MemMapFs) Rename(oldname, newname string) error { m.unRegisterWithParent(oldname) file := m.getData()[oldname].(*mem.File) delete(m.getData(), oldname) - mem.ChangeFileName(file, newname) + file.FileName = newname m.getData()[newname] = file m.registerWithParent(file) m.unlock() @@ -322,8 +324,7 @@ func (m *MemMapFs) Stat(name string) (os.FileInfo, error) { if err != nil { return nil, err } - fi := mem.GetFileInfo(f.(*mem.File)) - return fi, nil + return &mem.FileInfo{File: f.(*mem.File)}, nil } func (m *MemMapFs) Chmod(name string, mode os.FileMode) error { @@ -336,7 +337,7 @@ func (m *MemMapFs) Chmod(name string, mode os.FileMode) error { ff, ok := f.(*mem.File) if ok { m.lock() - mem.SetMode(ff, mode) + ff.Mode = mode m.unlock() } else { return errors.New("Unable to Chmod Memory File") @@ -354,7 +355,7 @@ func (m *MemMapFs) Chtimes(name string, atime time.Time, mtime time.Time) error ff, ok := f.(*mem.File) if ok { m.lock() - mem.SetModTime(ff, mtime) + ff.Modtime = mtime m.unlock() } else { return errors.New("Unable to Chtime Memory File")