diff --git a/database.go b/database.go index 841703f..71e73d3 100644 --- a/database.go +++ b/database.go @@ -24,9 +24,15 @@ package main import ( "bazil.org/fuse/fs" + "errors" + "fmt" "io/ioutil" + "path" "path/filepath" + "regexp" + "strconv" "sync/atomic" + "time" ) type database struct { @@ -57,7 +63,7 @@ func (this *database) load(dir string) error { return err } - this.vers, err = this.versions(dirs) + this.vers, err = this.version(dirs) if err != nil { return err } @@ -73,12 +79,17 @@ func (this *database) save() error { return nil } -func (this *database) versions(dirs []string) ([]*version, error) { +func (this *database) version(dirs []string) ([]*version, error) { var vers []*version var parent *version for _, dir := range dirs { - ver, err := newVersion(dir, this, parent) + time, err := this.parseVerName(path.Base(dir)) + if err != nil { + return nil, err + } + + ver, err := newVersion(dir, time, this, parent) if err != nil { return nil, err } @@ -122,3 +133,26 @@ func (this *database) Root() (fs.Node, error) { func (this *database) AllocInode() uint64 { return atomic.AddUint64(&this.inodeCnt, 1) } + +func (this *database) buildVerName(timestamp time.Time) string { + return fmt.Sprintf("%x", timestamp.Unix()) +} + +func (this *database) parseVerName(name string) (time.Time, error) { + re, err := regexp.Compile(`vfs_([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 9b6576f..d9534a2 100644 --- a/version.go +++ b/version.go @@ -28,8 +28,6 @@ import ( "io/ioutil" "os" "path/filepath" - "regexp" - "strconv" "strings" "time" ) @@ -47,22 +45,7 @@ type InodeAllocator interface { AllocInode() uint64 } -func newVersion(base string, allocator InodeAllocator, parent *version) (*version, error) { - re, err := regexp.Compile(`/vfs_([0-9a-f])$`) - if err != nil { - return nil, err - } - - matches := re.FindStringSubmatch(base) - if len(matches) < 2 { - return nil, fmt.Errorf("invalid version identifier for %s", base) - } - - timeval, err := strconv.ParseInt(matches[1], 16, 64) - if err != nil { - return nil, err - } - +func newVersion(base string, timestamp time.Time, allocator InodeAllocator, parent *version) (*version, error) { meta, err := newVersionMetadata(filepath.Join(base, "meta.json")) if err != nil { return nil, err @@ -71,7 +54,7 @@ func newVersion(base string, allocator InodeAllocator, parent *version) (*versio ver := &version{ base: base, parent: parent, - timestamp: time.Unix(timeval, 0), + timestamp: timestamp, meta: meta, inodeAloc: allocator} @@ -170,11 +153,11 @@ func (this *version) Root() (fs.Node, error) { func (this *version) dump(root *versionedDir, depth int) { indent := strings.Repeat("\t", depth) for name, dir := range root.dirs { - fmt.Printf("%s+ %s [%s@%d]\n", indent, name, dir.node.path, dir.node.ver.timestamp.Unix()) + fmt.Printf("%s+ %s [%s@%x]\n", indent, name, dir.node.path, this.timestamp.Unix()) this.dump(dir, depth+1) } for name, file := range root.files { - fmt.Printf("%s- %s [%s@%d]\n", indent, name, file.node.path, file.node.ver.timestamp.Unix()) + fmt.Printf("%s- %s [%s@%x]\n", indent, name, file.node.path, this.timestamp.Unix()) } }