From 00d1c81a6cc18f329f74fdae93487bc9db6284b5 Mon Sep 17 00:00:00 2001 From: Alex Yatskov Date: Fri, 19 Jun 2015 17:51:10 +0900 Subject: [PATCH] Renaming things --- database.go | 6 ++--- dir.go | 56 +++++++++++++++++++-------------------- file.go | 36 ++++++++++++------------- meta.go | 20 +++++++------- node.go | 24 ++++++++--------- util.go | 44 +++++++++++++++++++++++++++---- version.go | 75 ++++++++++++----------------------------------------- 7 files changed, 127 insertions(+), 134 deletions(-) diff --git a/database.go b/database.go index dc98a35..18b3f49 100644 --- a/database.go +++ b/database.go @@ -37,7 +37,7 @@ import ( type database struct { base string - vers versionList + vers verList } func newDatabase(dir string) (*database, error) { @@ -85,13 +85,13 @@ func (db *database) save() error { return nil } -func (db *database) buildVersions(base string) (versionList, error) { +func (db *database) buildVersions(base string) (verList, error) { nodes, err := ioutil.ReadDir(base) if err != nil { return nil, err } - var vers versionList + var vers verList for _, node := range nodes { if !node.IsDir() { continue diff --git a/dir.go b/dir.go index 4b59cf6..a146d6c 100644 --- a/dir.go +++ b/dir.go @@ -33,30 +33,30 @@ import ( ) // -// versionedDir +// verDir // -type versionedDir struct { - dirs map[string]*versionedDir - files map[string]*versionedFile - node *versionedNode +type verDir struct { + dirs map[string]*verDir + files map[string]*verFile + node *verNode inode uint64 - parent *versionedDir + parent *verDir } -func newVersionedDir(node *versionedNode, parent *versionedDir) *versionedDir { - dirs := make(map[string]*versionedDir) - files := make(map[string]*versionedFile) +func newVerDir(node *verNode, parent *verDir) *verDir { + dirs := make(map[string]*verDir) + files := make(map[string]*verFile) - return &versionedDir{dirs, files, node, allocInode(), parent} + return &verDir{dirs, files, node, allocInode(), parent} } -func (vd *versionedDir) version() error { +func (vd *verDir) version() error { if vd.node.flags&NodeFlagVer == NodeFlagVer { return nil } - node := newVersionedNode(vd.node.path, vd.node.ver.db.lastVersion(), vd.node, NodeFlagDir|NodeFlagVer) + node := newVerNode(vd.node.path, vd.node.ver.db.lastVersion(), vd.node, NodeFlagDir|NodeFlagVer) if err := os.MkdirAll(node.rebasedPath(), 0755); err != nil { return err @@ -68,7 +68,7 @@ func (vd *versionedDir) version() error { return nil } -func (vd *versionedDir) createDir(name string) (*versionedDir, error) { +func (vd *verDir) createDir(name string) (*verDir, error) { if err := vd.version(); err != nil { return nil, err } @@ -78,15 +78,15 @@ func (vd *versionedDir) createDir(name string) (*versionedDir, error) { return nil, err } - node := newVersionedNode(childPath, vd.node.ver, nil, NodeFlagDir|NodeFlagVer) - dir := newVersionedDir(node, vd) + node := newVerNode(childPath, vd.node.ver, nil, NodeFlagDir|NodeFlagVer) + dir := newVerDir(node, vd) vd.dirs[name] = dir node.ver.meta.createNode(node.path) return dir, nil } -func (vd *versionedDir) createFile(name string, flags int) (*versionedFile, error) { +func (vd *verDir) createFile(name string, flags int) (*verFile, error) { if err := vd.version(); err != nil { return nil, err } @@ -97,8 +97,8 @@ func (vd *versionedDir) createFile(name string, flags int) (*versionedFile, erro return nil, err } - node := newVersionedNode(childPath, vd.node.ver, nil, NodeFlagVer) - file := newVersionedFile(node, vd) + node := newVerNode(childPath, vd.node.ver, nil, NodeFlagVer) + file := newVerFile(node, vd) file.handle = handle vd.files[name] = file @@ -107,7 +107,7 @@ func (vd *versionedDir) createFile(name string, flags int) (*versionedFile, erro } // Node -func (vd *versionedDir) Attr(ctx context.Context, attr *fuse.Attr) error { +func (vd *verDir) Attr(ctx context.Context, attr *fuse.Attr) error { if err := vd.node.attr(attr); err != nil { return err } @@ -117,26 +117,26 @@ func (vd *versionedDir) Attr(ctx context.Context, attr *fuse.Attr) error { } // NodeGetattrer -func (vd *versionedDir) Getattr(ctx context.Context, req *fuse.GetattrRequest, resp *fuse.GetattrResponse) error { +func (vd *verDir) Getattr(ctx context.Context, req *fuse.GetattrRequest, resp *fuse.GetattrResponse) error { return vd.Attr(ctx, &resp.Attr) } // NodeSetattrer -func (vd *versionedDir) Setattr(ctx context.Context, req *fuse.SetattrRequest, resp *fuse.SetattrResponse) error { +func (vd *verDir) Setattr(ctx context.Context, req *fuse.SetattrRequest, resp *fuse.SetattrResponse) error { vd.version() return vd.node.setAttr(req, resp) } // NodeCreater -func (vd *versionedDir) Create(ctx context.Context, req *fuse.CreateRequest, resp *fuse.CreateResponse) (node fs.Node, handle fs.Handle, err error) { +func (vd *verDir) Create(ctx context.Context, req *fuse.CreateRequest, resp *fuse.CreateResponse) (node fs.Node, handle fs.Handle, err error) { if req.Mode.IsDir() { - var dir *versionedDir + var dir *verDir if dir, err = vd.createDir(req.Name); err == nil { node = dir handle = dir } } else if req.Mode.IsRegular() { - var file *versionedFile + var file *verFile if file, err = vd.createFile(req.Name, int(req.Flags)); err == nil { node = file handle = file @@ -149,12 +149,12 @@ func (vd *versionedDir) Create(ctx context.Context, req *fuse.CreateRequest, res } // NodeMkdirer -func (vd *versionedDir) Mkdir(ctx context.Context, req *fuse.MkdirRequest) (fs.Node, error) { +func (vd *verDir) Mkdir(ctx context.Context, req *fuse.MkdirRequest) (fs.Node, error) { return vd.createDir(req.Name) } // NodeRemover -func (vd *versionedDir) Remove(ctx context.Context, req *fuse.RemoveRequest) error { +func (vd *verDir) Remove(ctx context.Context, req *fuse.RemoveRequest) error { if req.Dir { node := vd.dirs[req.Name].node ver := node.ver @@ -189,7 +189,7 @@ func (vd *versionedDir) Remove(ctx context.Context, req *fuse.RemoveRequest) err } // NodeRequestLookuper -func (vd *versionedDir) Lookup(ctx context.Context, name string) (fs.Node, error) { +func (vd *verDir) Lookup(ctx context.Context, name string) (fs.Node, error) { if dir, ok := vd.dirs[name]; ok { return dir, nil } @@ -202,7 +202,7 @@ func (vd *versionedDir) Lookup(ctx context.Context, name string) (fs.Node, error } // HandleReadDirAller -func (vd *versionedDir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) { +func (vd *verDir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) { entries := []fuse.Dirent{{Inode: vd.inode, Name: ".", Type: fuse.DT_Dir}} if vd.parent != nil { entry := fuse.Dirent{Inode: vd.parent.inode, Name: "..", Type: fuse.DT_Dir} diff --git a/file.go b/file.go index 94890f4..a051a3f 100644 --- a/file.go +++ b/file.go @@ -32,28 +32,28 @@ import ( ) // -// versionedFile +// verFile // -type versionedFile struct { - node *versionedNode +type verFile struct { + node *verNode inode uint64 - parent *versionedDir + parent *verDir handle *os.File } -func newVersionedFile(node *versionedNode, parent *versionedDir) *versionedFile { - return &versionedFile{node, allocInode(), parent, nil} +func newVerFile(node *verNode, parent *verDir) *verFile { + return &verFile{node, allocInode(), parent, nil} } -func (vf *versionedFile) version() error { +func (vf *verFile) version() error { if vf.node.flags&NodeFlagVer == NodeFlagVer { return nil } - node := newVersionedNode(vf.node.path, vf.node.ver.db.lastVersion(), vf.node, NodeFlagVer) + node := newVerNode(vf.node.path, vf.node.ver.db.lastVersion(), vf.node, NodeFlagVer) - if _, err := fileCopy(vf.node.rebasedPath(), node.rebasedPath()); err != nil { + if _, err := copyFile(vf.node.rebasedPath(), node.rebasedPath()); err != nil { return err } @@ -64,24 +64,24 @@ func (vf *versionedFile) version() error { } // Node -func (vf *versionedFile) Attr(ctx context.Context, attr *fuse.Attr) error { +func (vf *verFile) Attr(ctx context.Context, attr *fuse.Attr) error { vf.node.attr(attr) attr.Inode = vf.inode return nil } // NodeGetattrer -func (vf *versionedFile) Getattr(ctx context.Context, req *fuse.GetattrRequest, resp *fuse.GetattrResponse) error { +func (vf *verFile) Getattr(ctx context.Context, req *fuse.GetattrRequest, resp *fuse.GetattrResponse) error { return vf.Attr(ctx, &resp.Attr) } // NodeSetattrer -func (vf *versionedFile) Setattr(ctx context.Context, req *fuse.SetattrRequest, resp *fuse.SetattrResponse) error { +func (vf *verFile) Setattr(ctx context.Context, req *fuse.SetattrRequest, resp *fuse.SetattrResponse) error { return vf.node.setAttr(req, resp) } // NodeOpener -func (vf *versionedFile) Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.OpenResponse) (fs.Handle, error) { +func (vf *verFile) Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.OpenResponse) (fs.Handle, error) { if vf.handle != nil { return nil, errors.New("attempted to open already opened file") } @@ -102,7 +102,7 @@ func (vf *versionedFile) Open(ctx context.Context, req *fuse.OpenRequest, resp * } // HandleReleaser -func (vf *versionedFile) Release(ctx context.Context, req *fuse.ReleaseRequest) error { +func (vf *verFile) Release(ctx context.Context, req *fuse.ReleaseRequest) error { if vf.handle == nil { return errors.New("attempted to release unopened file") } @@ -114,7 +114,7 @@ func (vf *versionedFile) Release(ctx context.Context, req *fuse.ReleaseRequest) } // NodeFsyncer -func (vf *versionedFile) Fsync(ctx context.Context, req *fuse.FsyncRequest) error { +func (vf *verFile) Fsync(ctx context.Context, req *fuse.FsyncRequest) error { if vf.handle == nil { return errors.New("attempted to sync unopened file") } @@ -123,7 +123,7 @@ func (vf *versionedFile) Fsync(ctx context.Context, req *fuse.FsyncRequest) erro } // HandleReader -func (vf *versionedFile) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error { +func (vf *verFile) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error { if vf.handle == nil { return errors.New("attempted to read from unopened file") } @@ -137,7 +137,7 @@ func (vf *versionedFile) Read(ctx context.Context, req *fuse.ReadRequest, resp * } // HandleReadAller -func (vf *versionedFile) ReadAll(ctx context.Context) ([]byte, error) { +func (vf *verFile) ReadAll(ctx context.Context) ([]byte, error) { if vf.handle == nil { return nil, errors.New("attempted to read from unopened file") } @@ -156,7 +156,7 @@ func (vf *versionedFile) ReadAll(ctx context.Context) ([]byte, error) { } // HandleWriter -func (vf *versionedFile) Write(ctx context.Context, req *fuse.WriteRequest, resp *fuse.WriteResponse) error { +func (vf *verFile) Write(ctx context.Context, req *fuse.WriteRequest, resp *fuse.WriteResponse) error { if vf.handle == nil { return errors.New("attempted to write to unopened file") } diff --git a/meta.go b/meta.go index 25720ee..5913194 100644 --- a/meta.go +++ b/meta.go @@ -30,17 +30,17 @@ import ( ) // -// versionMetadata +// verMeta // -type versionMetadata struct { +type verMeta struct { Deleted []string `json:"deleted"` path string dirty bool } -func newVersionMetadata(path string) (*versionMetadata, error) { - meta := &versionMetadata{path: path} +func newVerMeta(path string) (*verMeta, error) { + meta := &verMeta{path: path} if err := meta.load(); err != nil { return nil, err } @@ -48,7 +48,7 @@ func newVersionMetadata(path string) (*versionMetadata, error) { return meta, nil } -func (m *versionMetadata) filter(nodes versionedNodeMap) { +func (m *verMeta) filter(nodes verNodeMap) { for _, delPath := range m.Deleted { for name, node := range nodes { if strings.HasPrefix(node.path, delPath) { @@ -58,20 +58,20 @@ func (m *versionMetadata) filter(nodes versionedNodeMap) { } } -func (m *versionMetadata) removeNode(path string) { +func (m *verMeta) removeNode(path string) { m.Deleted = append(m.Deleted, path) m.dirty = true } -func (m *versionMetadata) createNode(path string) { +func (m *verMeta) createNode(path string) { m.dirty = true } -func (m *versionMetadata) modifyNode(path string) { +func (m *verMeta) modifyNode(path string) { m.dirty = true } -func (m *versionMetadata) load() error { +func (m *verMeta) load() error { m.dirty = false if _, err := os.Stat(m.path); os.IsNotExist(err) { @@ -90,7 +90,7 @@ func (m *versionMetadata) load() error { return nil } -func (m *versionMetadata) save() error { +func (m *verMeta) save() error { if !m.dirty { return nil } diff --git a/node.go b/node.go index e1eaf64..afd06c7 100644 --- a/node.go +++ b/node.go @@ -31,7 +31,7 @@ import ( ) // -// versionedNode +// verNode // const ( @@ -39,18 +39,18 @@ const ( NodeFlagVer ) -type versionedNode struct { +type verNode struct { path string ver *version - parent *versionedNode + parent *verNode flags int } -func newVersionedNode(path string, ver *version, parent *versionedNode, flags int) *versionedNode { - return &versionedNode{path, ver, parent, flags} +func newVerNode(path string, ver *version, parent *verNode, flags int) *verNode { + return &verNode{path, ver, parent, flags} } -func (n *versionedNode) setAttr(req *fuse.SetattrRequest, resp *fuse.SetattrResponse) error { +func (n *verNode) setAttr(req *fuse.SetattrRequest, resp *fuse.SetattrResponse) error { if err := n.attr(&resp.Attr); err != nil { return err } @@ -92,24 +92,24 @@ func (n *versionedNode) setAttr(req *fuse.SetattrRequest, resp *fuse.SetattrResp return nil } -func (n *versionedNode) rebasedPath() string { +func (n *verNode) rebasedPath() string { return n.ver.rebasePath(n.path) } -func (n *versionedNode) owner(stat syscall.Stat_t) (gid, uid uint32) { +func (n *verNode) owner(stat syscall.Stat_t) (gid, uid uint32) { gid = stat.Gid uid = stat.Uid return } -func (n *versionedNode) times(stat syscall.Stat_t) (atime, mtime, ctime time.Time) { +func (n *verNode) times(stat syscall.Stat_t) (atime, mtime, ctime time.Time) { atime = time.Unix(int64(stat.Atim.Sec), int64(stat.Atim.Nsec)) mtime = time.Unix(int64(stat.Mtim.Sec), int64(stat.Mtim.Nsec)) ctime = time.Unix(int64(stat.Ctim.Sec), int64(stat.Ctim.Nsec)) return } -func (n *versionedNode) attr(attr *fuse.Attr) error { +func (n *verNode) attr(attr *fuse.Attr) error { info, err := os.Stat(n.rebasedPath()) if err != nil { return err @@ -129,7 +129,7 @@ func (n *versionedNode) attr(attr *fuse.Attr) error { } // -// versionedNodeMap +// verNodeMap // -type versionedNodeMap map[string]*versionedNode +type verNodeMap map[string]*verNode diff --git a/util.go b/util.go index 99f112c..1924432 100644 --- a/util.go +++ b/util.go @@ -23,22 +23,24 @@ package main import ( + "errors" + "fmt" "io" "os" + "path" + "regexp" + "strconv" "sync/atomic" + "time" ) -// -// utilities -// - var inodeCnt uint64 func allocInode() uint64 { return atomic.AddUint64(&inodeCnt, 1) } -func fileCopy(src, dst string) (int64, error) { +func copyFile(src, dst string) (int64, error) { srcFile, err := os.Open(src) if err != nil { return 0, err @@ -53,3 +55,35 @@ func fileCopy(src, dst string) (int64, error) { return io.Copy(srcFile, dstFile) } + +func buildNewVersion(base string) error { + name := buildVerName(time.Now()) + if err := os.MkdirAll(path.Join(base, name, "root"), 0755); err != nil { + return err + } + + return nil +} + +func buildVerName(timestamp time.Time) string { + return fmt.Sprintf("ver_%.16x", timestamp.Unix()) +} + +func parseVerName(name string) (time.Time, error) { + re, err := regexp.Compile(`ver_([0-9a-f]+)$`) + if err != nil { + return time.Unix(0, 0), err + } + + matches := re.FindStringSubmatch(name) + if len(matches) < 2 { + return time.Unix(0, 0), errors.New("invalid version identifier") + } + + timestamp, err := strconv.ParseInt(matches[1], 16, 64) + if err != nil { + return time.Unix(0, 0), err + } + + return time.Unix(timestamp, 0), nil +} diff --git a/version.go b/version.go index 67a48e4..f04196c 100644 --- a/version.go +++ b/version.go @@ -23,14 +23,9 @@ package main import ( - "errors" - "fmt" "io/ioutil" "os" - "path" "path/filepath" - "regexp" - "strconv" "time" "bazil.org/fuse/fs" @@ -44,13 +39,13 @@ type version struct { base string parent *version timestamp time.Time - meta *versionMetadata - root *versionedDir + meta *verMeta + root *verDir db *database } func newVersion(base string, timestamp time.Time, db *database) (*version, error) { - meta, err := newVersionMetadata(filepath.Join(base, "meta.json")) + meta, err := newVerMeta(filepath.Join(base, "meta.json")) if err != nil { return nil, err } @@ -58,8 +53,8 @@ func newVersion(base string, timestamp time.Time, db *database) (*version, error return &version{base, nil, timestamp, meta, nil, db}, nil } -func (v *version) scanDir(path string) (versionedNodeMap, error) { - var baseNodes versionedNodeMap +func (v *version) scanDir(path string) (verNodeMap, error) { + var baseNodes verNodeMap if v.parent != nil { var err error @@ -71,7 +66,7 @@ func (v *version) scanDir(path string) (versionedNodeMap, error) { v.meta.filter(baseNodes) } - ownNodes := make(versionedNodeMap) + ownNodes := make(verNodeMap) { infos, err := ioutil.ReadDir(v.rebasePath(path)) if !os.IsNotExist(err) { @@ -88,7 +83,7 @@ func (v *version) scanDir(path string) (versionedNodeMap, error) { childName := info.Name() childPath := filepath.Join(path, childName) - ownNodes[childName] = newVersionedNode(childPath, v, nil, childFlags) + ownNodes[childName] = newVerNode(childPath, v, nil, childFlags) } } @@ -107,7 +102,7 @@ func (v *version) scanDir(path string) (versionedNodeMap, error) { return baseNodes, nil } -func (v *version) buildDir(dir *versionedDir) error { +func (v *version) buildDir(dir *verDir) error { nodes, err := v.scanDir(dir.node.path) if err != nil { return err @@ -115,14 +110,14 @@ func (v *version) buildDir(dir *versionedDir) error { for name, node := range nodes { if node.flags&NodeFlagDir == NodeFlagDir { - subDir := newVersionedDir(node, dir) + subDir := newVerDir(node, dir) if err := v.buildDir(subDir); err != nil { return err } dir.dirs[name] = subDir } else { - dir.files[name] = newVersionedFile(node, dir) + dir.files[name] = newVerFile(node, dir) } } @@ -130,8 +125,8 @@ func (v *version) buildDir(dir *versionedDir) error { } func (v *version) resolve() error { - node := newVersionedNode("/", v, nil, NodeFlagDir) - root := newVersionedDir(node, nil) + node := newVerNode("/", v, nil, NodeFlagDir) + root := newVerDir(node, nil) if err := v.buildDir(root); err != nil { return err @@ -163,55 +158,19 @@ func (v *version) Root() (fs.Node, error) { } // -// versionList +// verList // -type versionList []*version +type verList []*version -func (v versionList) Len() int { +func (v verList) Len() int { return len(v) } -func (v versionList) Swap(i, j int) { +func (v verList) Swap(i, j int) { v[i], v[j] = v[j], v[i] } -func (v versionList) Less(i, j int) bool { +func (v verList) Less(i, j int) bool { return v[i].timestamp.Unix() < v[j].timestamp.Unix() } - -// -// version helpers -// - -func buildNewVersion(base string) error { - name := buildVerName(time.Now()) - if err := os.MkdirAll(path.Join(base, name, "root"), 0755); err != nil { - return err - } - - return nil -} - -func buildVerName(timestamp time.Time) string { - return fmt.Sprintf("ver_%.16x", timestamp.Unix()) -} - -func parseVerName(name string) (time.Time, error) { - re, err := regexp.Compile(`ver_([0-9a-f]+)$`) - if err != nil { - return time.Unix(0, 0), err - } - - matches := re.FindStringSubmatch(name) - if len(matches) < 2 { - return time.Unix(0, 0), errors.New("invalid version identifier") - } - - timestamp, err := strconv.ParseInt(matches[1], 16, 64) - if err != nil { - return time.Unix(0, 0), err - } - - return time.Unix(timestamp, 0), nil -}