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

79
meta.go
View File

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

View File

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