Renaming things
This commit is contained in:
parent
b6afe85166
commit
00d1c81a6c
@ -37,7 +37,7 @@ import (
|
|||||||
|
|
||||||
type database struct {
|
type database struct {
|
||||||
base string
|
base string
|
||||||
vers versionList
|
vers verList
|
||||||
}
|
}
|
||||||
|
|
||||||
func newDatabase(dir string) (*database, error) {
|
func newDatabase(dir string) (*database, error) {
|
||||||
@ -85,13 +85,13 @@ func (db *database) save() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *database) buildVersions(base string) (versionList, error) {
|
func (db *database) buildVersions(base string) (verList, error) {
|
||||||
nodes, err := ioutil.ReadDir(base)
|
nodes, err := ioutil.ReadDir(base)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var vers versionList
|
var vers verList
|
||||||
for _, node := range nodes {
|
for _, node := range nodes {
|
||||||
if !node.IsDir() {
|
if !node.IsDir() {
|
||||||
continue
|
continue
|
||||||
|
56
dir.go
56
dir.go
@ -33,30 +33,30 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
//
|
//
|
||||||
// versionedDir
|
// verDir
|
||||||
//
|
//
|
||||||
|
|
||||||
type versionedDir struct {
|
type verDir struct {
|
||||||
dirs map[string]*versionedDir
|
dirs map[string]*verDir
|
||||||
files map[string]*versionedFile
|
files map[string]*verFile
|
||||||
node *versionedNode
|
node *verNode
|
||||||
inode uint64
|
inode uint64
|
||||||
parent *versionedDir
|
parent *verDir
|
||||||
}
|
}
|
||||||
|
|
||||||
func newVersionedDir(node *versionedNode, parent *versionedDir) *versionedDir {
|
func newVerDir(node *verNode, parent *verDir) *verDir {
|
||||||
dirs := make(map[string]*versionedDir)
|
dirs := make(map[string]*verDir)
|
||||||
files := make(map[string]*versionedFile)
|
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 {
|
if vd.node.flags&NodeFlagVer == NodeFlagVer {
|
||||||
return nil
|
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 {
|
if err := os.MkdirAll(node.rebasedPath(), 0755); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -68,7 +68,7 @@ func (vd *versionedDir) version() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vd *versionedDir) createDir(name string) (*versionedDir, error) {
|
func (vd *verDir) createDir(name string) (*verDir, error) {
|
||||||
if err := vd.version(); err != nil {
|
if err := vd.version(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -78,15 +78,15 @@ func (vd *versionedDir) createDir(name string) (*versionedDir, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
node := newVersionedNode(childPath, vd.node.ver, nil, NodeFlagDir|NodeFlagVer)
|
node := newVerNode(childPath, vd.node.ver, nil, NodeFlagDir|NodeFlagVer)
|
||||||
dir := newVersionedDir(node, vd)
|
dir := newVerDir(node, vd)
|
||||||
vd.dirs[name] = dir
|
vd.dirs[name] = dir
|
||||||
|
|
||||||
node.ver.meta.createNode(node.path)
|
node.ver.meta.createNode(node.path)
|
||||||
return dir, nil
|
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 {
|
if err := vd.version(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -97,8 +97,8 @@ func (vd *versionedDir) createFile(name string, flags int) (*versionedFile, erro
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
node := newVersionedNode(childPath, vd.node.ver, nil, NodeFlagVer)
|
node := newVerNode(childPath, vd.node.ver, nil, NodeFlagVer)
|
||||||
file := newVersionedFile(node, vd)
|
file := newVerFile(node, vd)
|
||||||
file.handle = handle
|
file.handle = handle
|
||||||
vd.files[name] = file
|
vd.files[name] = file
|
||||||
|
|
||||||
@ -107,7 +107,7 @@ func (vd *versionedDir) createFile(name string, flags int) (*versionedFile, erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Node
|
// 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 {
|
if err := vd.node.attr(attr); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -117,26 +117,26 @@ func (vd *versionedDir) Attr(ctx context.Context, attr *fuse.Attr) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NodeGetattrer
|
// 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)
|
return vd.Attr(ctx, &resp.Attr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NodeSetattrer
|
// 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()
|
vd.version()
|
||||||
return vd.node.setAttr(req, resp)
|
return vd.node.setAttr(req, resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NodeCreater
|
// 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() {
|
if req.Mode.IsDir() {
|
||||||
var dir *versionedDir
|
var dir *verDir
|
||||||
if dir, err = vd.createDir(req.Name); err == nil {
|
if dir, err = vd.createDir(req.Name); err == nil {
|
||||||
node = dir
|
node = dir
|
||||||
handle = dir
|
handle = dir
|
||||||
}
|
}
|
||||||
} else if req.Mode.IsRegular() {
|
} else if req.Mode.IsRegular() {
|
||||||
var file *versionedFile
|
var file *verFile
|
||||||
if file, err = vd.createFile(req.Name, int(req.Flags)); err == nil {
|
if file, err = vd.createFile(req.Name, int(req.Flags)); err == nil {
|
||||||
node = file
|
node = file
|
||||||
handle = file
|
handle = file
|
||||||
@ -149,12 +149,12 @@ func (vd *versionedDir) Create(ctx context.Context, req *fuse.CreateRequest, res
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NodeMkdirer
|
// 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)
|
return vd.createDir(req.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NodeRemover
|
// 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 {
|
if req.Dir {
|
||||||
node := vd.dirs[req.Name].node
|
node := vd.dirs[req.Name].node
|
||||||
ver := node.ver
|
ver := node.ver
|
||||||
@ -189,7 +189,7 @@ func (vd *versionedDir) Remove(ctx context.Context, req *fuse.RemoveRequest) err
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NodeRequestLookuper
|
// 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 {
|
if dir, ok := vd.dirs[name]; ok {
|
||||||
return dir, nil
|
return dir, nil
|
||||||
}
|
}
|
||||||
@ -202,7 +202,7 @@ func (vd *versionedDir) Lookup(ctx context.Context, name string) (fs.Node, error
|
|||||||
}
|
}
|
||||||
|
|
||||||
// HandleReadDirAller
|
// 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}}
|
entries := []fuse.Dirent{{Inode: vd.inode, Name: ".", Type: fuse.DT_Dir}}
|
||||||
if vd.parent != nil {
|
if vd.parent != nil {
|
||||||
entry := fuse.Dirent{Inode: vd.parent.inode, Name: "..", Type: fuse.DT_Dir}
|
entry := fuse.Dirent{Inode: vd.parent.inode, Name: "..", Type: fuse.DT_Dir}
|
||||||
|
36
file.go
36
file.go
@ -32,28 +32,28 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
//
|
//
|
||||||
// versionedFile
|
// verFile
|
||||||
//
|
//
|
||||||
|
|
||||||
type versionedFile struct {
|
type verFile struct {
|
||||||
node *versionedNode
|
node *verNode
|
||||||
inode uint64
|
inode uint64
|
||||||
parent *versionedDir
|
parent *verDir
|
||||||
handle *os.File
|
handle *os.File
|
||||||
}
|
}
|
||||||
|
|
||||||
func newVersionedFile(node *versionedNode, parent *versionedDir) *versionedFile {
|
func newVerFile(node *verNode, parent *verDir) *verFile {
|
||||||
return &versionedFile{node, allocInode(), parent, nil}
|
return &verFile{node, allocInode(), parent, nil}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vf *versionedFile) version() error {
|
func (vf *verFile) version() error {
|
||||||
if vf.node.flags&NodeFlagVer == NodeFlagVer {
|
if vf.node.flags&NodeFlagVer == NodeFlagVer {
|
||||||
return nil
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,24 +64,24 @@ func (vf *versionedFile) version() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Node
|
// 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)
|
vf.node.attr(attr)
|
||||||
attr.Inode = vf.inode
|
attr.Inode = vf.inode
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NodeGetattrer
|
// 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)
|
return vf.Attr(ctx, &resp.Attr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NodeSetattrer
|
// 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)
|
return vf.node.setAttr(req, resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NodeOpener
|
// 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 {
|
if vf.handle != nil {
|
||||||
return nil, errors.New("attempted to open already opened file")
|
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
|
// 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 {
|
if vf.handle == nil {
|
||||||
return errors.New("attempted to release unopened file")
|
return errors.New("attempted to release unopened file")
|
||||||
}
|
}
|
||||||
@ -114,7 +114,7 @@ func (vf *versionedFile) Release(ctx context.Context, req *fuse.ReleaseRequest)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NodeFsyncer
|
// 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 {
|
if vf.handle == nil {
|
||||||
return errors.New("attempted to sync unopened file")
|
return errors.New("attempted to sync unopened file")
|
||||||
}
|
}
|
||||||
@ -123,7 +123,7 @@ func (vf *versionedFile) Fsync(ctx context.Context, req *fuse.FsyncRequest) erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
// HandleReader
|
// 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 {
|
if vf.handle == nil {
|
||||||
return errors.New("attempted to read from unopened file")
|
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
|
// HandleReadAller
|
||||||
func (vf *versionedFile) ReadAll(ctx context.Context) ([]byte, error) {
|
func (vf *verFile) ReadAll(ctx context.Context) ([]byte, error) {
|
||||||
if vf.handle == nil {
|
if vf.handle == nil {
|
||||||
return nil, errors.New("attempted to read from unopened file")
|
return nil, errors.New("attempted to read from unopened file")
|
||||||
}
|
}
|
||||||
@ -156,7 +156,7 @@ func (vf *versionedFile) ReadAll(ctx context.Context) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// HandleWriter
|
// 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 {
|
if vf.handle == nil {
|
||||||
return errors.New("attempted to write to unopened file")
|
return errors.New("attempted to write to unopened file")
|
||||||
}
|
}
|
||||||
|
20
meta.go
20
meta.go
@ -30,17 +30,17 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
//
|
//
|
||||||
// versionMetadata
|
// verMeta
|
||||||
//
|
//
|
||||||
|
|
||||||
type versionMetadata struct {
|
type verMeta struct {
|
||||||
Deleted []string `json:"deleted"`
|
Deleted []string `json:"deleted"`
|
||||||
path string
|
path string
|
||||||
dirty bool
|
dirty bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func newVersionMetadata(path string) (*versionMetadata, error) {
|
func newVerMeta(path string) (*verMeta, error) {
|
||||||
meta := &versionMetadata{path: path}
|
meta := &verMeta{path: path}
|
||||||
if err := meta.load(); err != nil {
|
if err := meta.load(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -48,7 +48,7 @@ func newVersionMetadata(path string) (*versionMetadata, error) {
|
|||||||
return meta, nil
|
return meta, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *versionMetadata) filter(nodes versionedNodeMap) {
|
func (m *verMeta) filter(nodes verNodeMap) {
|
||||||
for _, delPath := range m.Deleted {
|
for _, delPath := range m.Deleted {
|
||||||
for name, node := range nodes {
|
for name, node := range nodes {
|
||||||
if strings.HasPrefix(node.path, delPath) {
|
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.Deleted = append(m.Deleted, path)
|
||||||
m.dirty = true
|
m.dirty = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *versionMetadata) createNode(path string) {
|
func (m *verMeta) createNode(path string) {
|
||||||
m.dirty = true
|
m.dirty = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *versionMetadata) modifyNode(path string) {
|
func (m *verMeta) modifyNode(path string) {
|
||||||
m.dirty = true
|
m.dirty = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *versionMetadata) load() error {
|
func (m *verMeta) load() error {
|
||||||
m.dirty = false
|
m.dirty = false
|
||||||
|
|
||||||
if _, err := os.Stat(m.path); os.IsNotExist(err) {
|
if _, err := os.Stat(m.path); os.IsNotExist(err) {
|
||||||
@ -90,7 +90,7 @@ func (m *versionMetadata) load() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *versionMetadata) save() error {
|
func (m *verMeta) save() error {
|
||||||
if !m.dirty {
|
if !m.dirty {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
24
node.go
24
node.go
@ -31,7 +31,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
//
|
//
|
||||||
// versionedNode
|
// verNode
|
||||||
//
|
//
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -39,18 +39,18 @@ const (
|
|||||||
NodeFlagVer
|
NodeFlagVer
|
||||||
)
|
)
|
||||||
|
|
||||||
type versionedNode struct {
|
type verNode struct {
|
||||||
path string
|
path string
|
||||||
ver *version
|
ver *version
|
||||||
parent *versionedNode
|
parent *verNode
|
||||||
flags int
|
flags int
|
||||||
}
|
}
|
||||||
|
|
||||||
func newVersionedNode(path string, ver *version, parent *versionedNode, flags int) *versionedNode {
|
func newVerNode(path string, ver *version, parent *verNode, flags int) *verNode {
|
||||||
return &versionedNode{path, ver, parent, flags}
|
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 {
|
if err := n.attr(&resp.Attr); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -92,24 +92,24 @@ func (n *versionedNode) setAttr(req *fuse.SetattrRequest, resp *fuse.SetattrResp
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *versionedNode) rebasedPath() string {
|
func (n *verNode) rebasedPath() string {
|
||||||
return n.ver.rebasePath(n.path)
|
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
|
gid = stat.Gid
|
||||||
uid = stat.Uid
|
uid = stat.Uid
|
||||||
return
|
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))
|
atime = time.Unix(int64(stat.Atim.Sec), int64(stat.Atim.Nsec))
|
||||||
mtime = time.Unix(int64(stat.Mtim.Sec), int64(stat.Mtim.Nsec))
|
mtime = time.Unix(int64(stat.Mtim.Sec), int64(stat.Mtim.Nsec))
|
||||||
ctime = time.Unix(int64(stat.Ctim.Sec), int64(stat.Ctim.Nsec))
|
ctime = time.Unix(int64(stat.Ctim.Sec), int64(stat.Ctim.Nsec))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *versionedNode) attr(attr *fuse.Attr) error {
|
func (n *verNode) attr(attr *fuse.Attr) error {
|
||||||
info, err := os.Stat(n.rebasedPath())
|
info, err := os.Stat(n.rebasedPath())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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
|
||||||
|
44
util.go
44
util.go
@ -23,22 +23,24 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
//
|
|
||||||
// utilities
|
|
||||||
//
|
|
||||||
|
|
||||||
var inodeCnt uint64
|
var inodeCnt uint64
|
||||||
|
|
||||||
func allocInode() uint64 {
|
func allocInode() uint64 {
|
||||||
return atomic.AddUint64(&inodeCnt, 1)
|
return atomic.AddUint64(&inodeCnt, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func fileCopy(src, dst string) (int64, error) {
|
func copyFile(src, dst string) (int64, error) {
|
||||||
srcFile, err := os.Open(src)
|
srcFile, err := os.Open(src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
@ -53,3 +55,35 @@ func fileCopy(src, dst string) (int64, error) {
|
|||||||
|
|
||||||
return io.Copy(srcFile, dstFile)
|
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
|
||||||
|
}
|
||||||
|
75
version.go
75
version.go
@ -23,14 +23,9 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"bazil.org/fuse/fs"
|
"bazil.org/fuse/fs"
|
||||||
@ -44,13 +39,13 @@ type version struct {
|
|||||||
base string
|
base string
|
||||||
parent *version
|
parent *version
|
||||||
timestamp time.Time
|
timestamp time.Time
|
||||||
meta *versionMetadata
|
meta *verMeta
|
||||||
root *versionedDir
|
root *verDir
|
||||||
db *database
|
db *database
|
||||||
}
|
}
|
||||||
|
|
||||||
func newVersion(base string, timestamp time.Time, db *database) (*version, error) {
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
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
|
return &version{base, nil, timestamp, meta, nil, db}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *version) scanDir(path string) (versionedNodeMap, error) {
|
func (v *version) scanDir(path string) (verNodeMap, error) {
|
||||||
var baseNodes versionedNodeMap
|
var baseNodes verNodeMap
|
||||||
if v.parent != nil {
|
if v.parent != nil {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
@ -71,7 +66,7 @@ func (v *version) scanDir(path string) (versionedNodeMap, error) {
|
|||||||
v.meta.filter(baseNodes)
|
v.meta.filter(baseNodes)
|
||||||
}
|
}
|
||||||
|
|
||||||
ownNodes := make(versionedNodeMap)
|
ownNodes := make(verNodeMap)
|
||||||
{
|
{
|
||||||
infos, err := ioutil.ReadDir(v.rebasePath(path))
|
infos, err := ioutil.ReadDir(v.rebasePath(path))
|
||||||
if !os.IsNotExist(err) {
|
if !os.IsNotExist(err) {
|
||||||
@ -88,7 +83,7 @@ func (v *version) scanDir(path string) (versionedNodeMap, error) {
|
|||||||
childName := info.Name()
|
childName := info.Name()
|
||||||
childPath := filepath.Join(path, childName)
|
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
|
return baseNodes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *version) buildDir(dir *versionedDir) error {
|
func (v *version) buildDir(dir *verDir) error {
|
||||||
nodes, err := v.scanDir(dir.node.path)
|
nodes, err := v.scanDir(dir.node.path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -115,14 +110,14 @@ func (v *version) buildDir(dir *versionedDir) error {
|
|||||||
|
|
||||||
for name, node := range nodes {
|
for name, node := range nodes {
|
||||||
if node.flags&NodeFlagDir == NodeFlagDir {
|
if node.flags&NodeFlagDir == NodeFlagDir {
|
||||||
subDir := newVersionedDir(node, dir)
|
subDir := newVerDir(node, dir)
|
||||||
if err := v.buildDir(subDir); err != nil {
|
if err := v.buildDir(subDir); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
dir.dirs[name] = subDir
|
dir.dirs[name] = subDir
|
||||||
} else {
|
} 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 {
|
func (v *version) resolve() error {
|
||||||
node := newVersionedNode("/", v, nil, NodeFlagDir)
|
node := newVerNode("/", v, nil, NodeFlagDir)
|
||||||
root := newVersionedDir(node, nil)
|
root := newVerDir(node, nil)
|
||||||
|
|
||||||
if err := v.buildDir(root); err != nil {
|
if err := v.buildDir(root); err != nil {
|
||||||
return err
|
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)
|
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]
|
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()
|
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
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user