func (w *Watcher) doRemove(name string) {
	delete(w.names, name)
	fi, ok := w.files[name]
	if !ok {
		return  
	}
	delete(w.files, name)
	if !fi.IsDir() {
		return
	}
	for fp := range w.files {
		if filepath.Dir(fp) == name {
			delete(w.files, fp)
		}
	}
}
doRemove does the actual remove operation
it does not consider the mutex protection
package watcher
import (
	"io/ioutil"
	"os"
	"path/filepath"
	"sync"
	"time"
	"github.com/pingcap/errors"
	"github.com/siddontang/go/sync2"
)
var (
	ErrWatcherStarted = errors.New("watcher already started")
	ErrWatcherClosed  = errors.New("watcher already closed")
)
type Watcher struct {
	Events chan Event
	Errors chan error
	running sync2.AtomicInt32
	closed  chan struct{}
	wg      sync.WaitGroup
	mu      sync.Mutex
	names map[string]struct{}     
	files map[string]os.FileInfo  
}
func NewWatcher() *Watcher {
	w := &Watcher{
		Events: make(chan Event),
		Errors: make(chan error),
		closed: make(chan struct{}),
		names:  make(map[string]struct{}),
		files:  make(map[string]os.FileInfo),
	}
	return w
}
func (w *Watcher) Start(d time.Duration) error {
	if !w.running.CompareAndSwap(0, 1) {
		return ErrWatcherStarted
	}
	select {
	case <-w.closed:
		return ErrWatcherClosed
	default:
	}
	w.wg.Add(1)
	go func() {
		defer w.wg.Done()
		w.doWatch(d)
	}()
	return nil
}
func (w *Watcher) Close() {
	if !w.running.CompareAndSwap(1, 0) {
		return
	}
	close(w.closed)
	w.wg.Wait()
	close(w.Events)
	close(w.Errors)
	w.mu.Lock()
	w.names = make(map[string]struct{})
	w.files = make(map[string]os.FileInfo)
	w.mu.Unlock()
}
func (w *Watcher) Add(name string) error {
	w.mu.Lock()
	defer w.mu.Unlock()
	select {
	case <-w.closed:
		return ErrWatcherClosed
	default:
	}
	fileList, err := listForName(name)
	if err != nil {
		return errors.Trace(err)
	}
	w.names[name] = struct{}{}
	for fp, fi := range fileList {
		w.files[fp] = fi
	}
	return nil
}
func (w *Watcher) Remove(name string) error {
	w.mu.Lock()
	defer w.mu.Unlock()
	select {
	case <-w.closed:
		return ErrWatcherClosed
	default:
	}
	w.doRemove(name)
	return nil
}