Skip to content

Commit

Permalink
(wip)
Browse files Browse the repository at this point in the history
  • Loading branch information
rjeczalik committed Jan 22, 2015
1 parent a54aea2 commit afeedb1
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 41 deletions.
6 changes: 3 additions & 3 deletions bigtree.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ type bigTree struct {
FS fs.Filesystem
Root node

cnd ChanNodesMap
cnd chanNodesMap
stop chan struct{}
impl impl
isrec bool
Expand Down Expand Up @@ -100,7 +100,7 @@ func (t *bigTree) loopdispatch(c <-chan EventInfo) {
func newTree(w watcher, c <-chan EventInfo) *bigTree {
t := &bigTree{
Root: node{Child: make(map[string]node), Watch: make(watchpoint)},
cnd: make(ChanNodesMap),
cnd: make(chanNodesMap),
stop: make(chan struct{}),
}
t.setimpl(w)
Expand Down Expand Up @@ -454,7 +454,7 @@ func (t *bigTree) mergewatchrec(p string, c chan<- EventInfo, e Event) error {
// there is a chance there exist one or more recursive watchpoints in the
// subtree starting at p - we would need to rewatch those as one watch can
// compensate for several smaller ones.
var nds NodeSet
var nds nodeSet
var erec = e
switch err {
case nil:
Expand Down
42 changes: 21 additions & 21 deletions node.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,12 +224,12 @@ func (nd node) WalkPath(name string, fn walkPathFunc) error {
}

// Root TODO
type Root struct {
type root struct {
nd node
}

// TODO(rjeczalik): split unix + windows
func (r Root) addroot(name string) node {
func (r root) addroot(name string) node {
if vol := filepath.VolumeName(name); vol != "" {
root, ok := r.nd.Child[vol]
if !ok {
Expand All @@ -241,7 +241,7 @@ func (r Root) addroot(name string) node {
}

// TODO(rjeczalik): split unix + windows
func (r Root) root(name string) (node, error) {
func (r root) root(name string) (node, error) {
if vol := filepath.VolumeName(name); vol != "" {
nd, ok := r.nd.Child[vol]
if !ok {
Expand All @@ -253,17 +253,17 @@ func (r Root) root(name string) (node, error) {
}

// Add TODO
func (r Root) Add(name string) node {
func (r root) Add(name string) node {
return r.addroot(name).Add(name)
}

// WalkDir TODO
func (r Root) AddDir(dir string, fn walkFunc) error {
func (r root) AddDir(dir string, fn walkFunc) error {
return r.addroot(dir).AddDir(dir, fn)
}

// Del TODO
func (r Root) Del(name string) error {
func (r root) Del(name string) error {
nd, err := r.root(name)
if err != nil {
return err
Expand All @@ -272,7 +272,7 @@ func (r Root) Del(name string) error {
}

// Get TODO
func (r Root) Get(name string) (node, error) {
func (r root) Get(name string) (node, error) {
nd, err := r.root(name)
if err != nil {
return node{}, err
Expand All @@ -281,7 +281,7 @@ func (r Root) Get(name string) (node, error) {
}

// Walk TODO
func (r Root) Walk(name string, fn walkFunc) error {
func (r root) Walk(name string, fn walkFunc) error {
nd, err := r.root(name)
if err != nil {
return err
Expand All @@ -293,7 +293,7 @@ func (r Root) Walk(name string, fn walkFunc) error {
}

// Root TODO
func (r Root) WalkPath(name string, fn walkPathFunc) error {
func (r root) WalkPath(name string, fn walkPathFunc) error {
nd, err := r.root(name)
if err != nil {
return err
Expand All @@ -302,24 +302,24 @@ func (r Root) WalkPath(name string, fn walkPathFunc) error {
}

// NodeSet TODO
type NodeSet []node
type nodeSet []node

func (p NodeSet) Len() int { return len(p) }
func (p NodeSet) Less(i, j int) bool { return p[i].Name < p[j].Name }
func (p NodeSet) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func (p nodeSet) Len() int { return len(p) }
func (p nodeSet) Less(i, j int) bool { return p[i].Name < p[j].Name }
func (p nodeSet) Swap(i, j int) { p[i], p[j] = p[j], p[i] }

func (p NodeSet) Search(nd node) int {
func (p nodeSet) Search(nd node) int {
return sort.Search(len(p), func(i int) bool { return p[i].Name >= nd.Name })
}

func (p *NodeSet) Names() (s []string) {
func (p *nodeSet) Names() (s []string) {
for i := range *p {
s = append(s, (*p)[i].Name)
}
return
}

func (p *NodeSet) Add(nd node) {
func (p *nodeSet) Add(nd node) {
switch i := p.Search(nd); {
case i == len(*p):
*p = append(*p, nd)
Expand All @@ -331,25 +331,25 @@ func (p *NodeSet) Add(nd node) {
}
}

func (p *NodeSet) Del(nd node) {
func (p *nodeSet) Del(nd node) {
if i, n := p.Search(nd), len(*p); i != n && (*p)[i].Name == nd.Name {
copy((*p)[i:], (*p)[i+1:])
*p = (*p)[:n-1]
}
}

// ChanNodesMap TODO
type ChanNodesMap map[chan<- EventInfo]*NodeSet
type chanNodesMap map[chan<- EventInfo]*nodeSet

func (m ChanNodesMap) Add(c chan<- EventInfo, nd node) {
func (m chanNodesMap) Add(c chan<- EventInfo, nd node) {
if nds, ok := m[c]; ok {
nds.Add(nd)
} else {
m[c] = &NodeSet{nd}
m[c] = &nodeSet{nd}
}
}

func (m ChanNodesMap) Del(c chan<- EventInfo, nd node) {
func (m chanNodesMap) Del(c chan<- EventInfo, nd node) {
if nds, ok := m[c]; ok {
if nds.Del(nd); len(*nds) == 0 {
delete(m, c)
Expand Down
22 changes: 11 additions & 11 deletions node_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,20 @@ import (
func TestTreeNodeSet(t *testing.T) {
cases := [...]struct {
nd []node
nds NodeSet
nds nodeSet
}{{
[]node{{Name: "g"}, {Name: "t"}, {Name: "u"}, {Name: "a"}, {Name: "b"}},
NodeSet{{Name: "a"}, {Name: "b"}, {Name: "g"}, {Name: "t"}, {Name: "u"}},
nodeSet{{Name: "a"}, {Name: "b"}, {Name: "g"}, {Name: "t"}, {Name: "u"}},
}, {
[]node{{Name: "aA"}, {Name: "aA"}, {Name: "aa"}, {Name: "AA"}},
NodeSet{{Name: "AA"}, {Name: "aA"}, {Name: "aa"}},
nodeSet{{Name: "AA"}, {Name: "aA"}, {Name: "aa"}},
}, {
[]node{{Name: "b"}, {Name: "b"}, {Name: "a"}, {Name: "Y"}, {Name: ""}, {Name: "a"}},
NodeSet{{Name: ""}, {Name: "Y"}, {Name: "a"}, {Name: "b"}},
nodeSet{{Name: ""}, {Name: "Y"}, {Name: "a"}, {Name: "b"}},
}}
Test:
for i, cas := range cases {
nds := NodeSet{}
nds := nodeSet{}
for _, nd := range cas.nd {
nds.Add(nd)
}
Expand Down Expand Up @@ -49,26 +49,26 @@ func TestTreeChanNodesMap(t *testing.T) {
ch := NewChans(10)
cases := [...]struct {
ch Chans
cnd ChanNodesMap
cnd chanNodesMap
}{{
Chans{ch[0]},
ChanNodesMap{ch[0]: {{Name: "0"}}},
chanNodesMap{ch[0]: {{Name: "0"}}},
}, {
Chans{ch[0], ch[0], ch[0]},
ChanNodesMap{
chanNodesMap{
ch[0]: {{Name: "0"}, {Name: "1"}, {Name: "2"}},
},
}, {
Chans{ch[0], ch[3], ch[2], ch[1]},
ChanNodesMap{
chanNodesMap{
ch[0]: {{Name: "0"}},
ch[1]: {{Name: "3"}},
ch[2]: {{Name: "2"}},
ch[3]: {{Name: "1"}},
},
}, {
Chans{ch[0], ch[0], ch[2], ch[1], ch[3], ch[3], ch[2], ch[2], ch[4], ch[0]},
ChanNodesMap{
chanNodesMap{
ch[0]: {{Name: "0"}, {Name: "1"}, {Name: "9"}},
ch[1]: {{Name: "3"}},
ch[2]: {{Name: "2"}, {Name: "6"}, {Name: "7"}},
Expand All @@ -77,7 +77,7 @@ func TestTreeChanNodesMap(t *testing.T) {
},
}}
for i, cas := range cases {
cnd := make(ChanNodesMap)
cnd := make(chanNodesMap)
cas.ch.Foreach(cnd.Add)
if !reflect.DeepEqual(cnd, cas.cnd) {
t.Errorf("want cnd=%v; got %v (i=%d)", cas.cnd, cnd, i)
Expand Down
64 changes: 58 additions & 6 deletions recursivetree.go
Original file line number Diff line number Diff line change
@@ -1,27 +1,79 @@
package notify

// TODO(rjeczalik)
import (
"path/filepath"
"strings"
)

// recursiveTree TODO(rjeczalik)
type recursiveTree struct {
root Root
root root
w recursiveWatcher
cnd ChanNodesMap
cnd chanNodesMap
}

func newRecursiveTree(w recursiveWatcher, c <-chan EventInfo) *recursiveTree {
func newrecursiveTree(w recursiveWatcher, c <-chan EventInfo) *recursiveTree {
t := &recursiveTree{
root: Root{nd: newnode("")},
cnd: make(ChanNodesMap),
root: root{nd: newnode("")},
cnd: make(chanNodesMap),
w: w,
}
go t.dispatch(c)
return t
}

func (t *recursiveTree) dispatch(c <-chan EventInfo) {
// TODO
}

func cleanpath(path string) (clean string, isrec bool, err error) {
if strings.HasSuffix(path, "...") {
isrec = true
path = path[:len(path)-3]
}
if path, err = filepath.Abs(path); err != nil {
return "", false, err
}
return path, isrec, nil
}

// Watch TODO(rjeczalik)
//
// Watch does not support symlinks as it does not care. If user cares, p should
// be passed to os.Readlink first.
func (t *recursiveTree) Watch(path string, c chan<- EventInfo, events ...Event) error {
if c == nil {
panic("notify: Watch using nil channel")
}
// Expanding with empty event set is a nop.
if len(events) == 0 {
return nil
}
path, isrec, err := cleanpath(path)
if err != nil {
return err
}
eventset := joinevents(events)
if isrec {
eventset |= recursive
}
parent := node{Name: path}
// Look for an existing watchpoint on the path.
err = t.root.WalkPath(path, func(nd node, _ bool) error {
if nd.Watch[nil] != 0 {
parent = nd
return skip
}
return nil
})
node := t.root.Add(path)
diff := node.Watch.Add(c, eventset)
if err == nil && parent.Watch != nil {

}

_, _, _, _ = eventset, isrec, node, diff
//
return nil
}

Expand Down
1 change: 1 addition & 0 deletions watcher_fsevents.go
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ func (fse *fsevents) RecursiveRewatch(oldpath, newpath string, oldevent, neweven
return nil
default:
// TODO(rjeczalik): rewatch newpath only if exists?
// TODO(rjeczalik): migrate w.prev to new watch?
if _, ok := fse.watches[newpath]; ok {
return errAlreadyWatched
}
Expand Down

0 comments on commit afeedb1

Please sign in to comment.