Handle deleting and re-creating of files

This commit is contained in:
Alex Yatskov 2015-06-23 16:36:57 +09:00
parent 338e01223c
commit 76a517d1a3
2 changed files with 65 additions and 16 deletions

77
meta.go
View File

@ -26,21 +26,28 @@ import (
"encoding/json"
"io/ioutil"
"os"
"path"
"strings"
"sync"
)
//
// verMeta
//
type verMeta struct {
type verFmt struct {
Deleted []string `json:"deleted"`
}
type verMeta struct {
path string
dirty bool
deleted map[string]bool
modified bool
mutex sync.Mutex
}
func newVerMeta(path string) (*verMeta, error) {
meta := &verMeta{path: path}
meta := &verMeta{path, make(map[string]bool), false, sync.Mutex{}}
if err := meta.load(); err != nil {
return nil, err
}
@ -49,9 +56,13 @@ func newVerMeta(path string) (*verMeta, error) {
}
func (m *verMeta) filter(nodes verNodeMap) {
for _, delPath := range m.Deleted {
for path, deleted := range m.deleted {
if !deleted {
continue
}
for name, node := range nodes {
if strings.HasPrefix(node.path, delPath) {
if strings.HasPrefix(node.path, path) {
delete(nodes, name)
}
}
@ -59,21 +70,26 @@ func (m *verMeta) filter(nodes verNodeMap) {
}
func (m *verMeta) removeNode(path string) {
m.Deleted = append(m.Deleted, path)
m.dirty = true
m.mutex.Lock()
m.deleted[path] = true
m.mutex.Unlock()
m.modified = true
}
func (m *verMeta) createNode(path string) {
m.dirty = true
m.mutex.Lock()
m.deleted[path] = false
m.mutex.Unlock()
m.modified = true
}
func (m *verMeta) modifyNode(path string) {
m.dirty = true
m.modified = true
}
func (m *verMeta) load() error {
m.dirty = false
if _, err := os.Stat(m.path); os.IsNotExist(err) {
return nil
}
@ -83,19 +99,52 @@ func (m *verMeta) load() error {
return err
}
if err := json.Unmarshal(bytes, &m); err != nil {
var vd verFmt
if err := json.Unmarshal(bytes, &vd); err != nil {
return err
}
m.deleted = make(map[string]bool)
for _, path := range vd.Deleted {
m.deleted[path] = true
}
m.modified = false
return nil
}
func (m *verMeta) checkRedundantDel(child string) bool {
parent := path.Dir(child)
if parent == "/" {
return false
}
if deleted, _ := m.deleted[parent]; deleted {
return true
}
return m.checkRedundantDel(parent)
}
func (m *verMeta) save() error {
if !m.dirty {
if !m.modified {
return nil
}
js, err := json.Marshal(m)
var vd verFmt
for path, deleted := range m.deleted {
if !deleted {
continue
}
if m.checkRedundantDel(path) {
continue
}
vd.Deleted = append(vd.Deleted, path)
}
js, err := json.Marshal(vd)
if err != nil {
return err
}

View File

@ -142,7 +142,7 @@ func (v *version) rebasePath(paths ...string) string {
}
func (v *version) finalize(last bool) error {
if v.meta.dirty {
if v.meta.modified {
return v.meta.save()
} else if last {
if err := os.RemoveAll(v.base); err != nil {