| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- package fileSystem
- import (
- "fmt"
- "path/filepath"
- "strings"
- "time"
- etcdErr "github.com/coreos/etcd/error"
- )
- type FileSystem struct {
- Root *Node
- EventHistory *EventHistory
- WatcherHub *watcherHub
- Index uint64
- Term uint64
- }
- func New() *FileSystem {
- return &FileSystem{
- Root: newDir("/", 0, 0, nil, ""),
- WatcherHub: newWatchHub(1000),
- }
- }
- func (fs *FileSystem) InternalGet(path string, index uint64, term uint64) (*Node, error) {
- fmt.Println("GET: ", path)
- path = filepath.Clean("/" + path)
- // update file system known index and term
- fs.Index, fs.Term = index, term
- walkFunc := func(parent *Node, dirName string) (*Node, error) {
- child, ok := parent.Children[dirName]
- if ok {
- return child, nil
- }
- return nil, etcdErr.NewError(100, "get")
- }
- f, err := fs.walk(path, walkFunc)
- if err != nil {
- return nil, err
- }
- return f, nil
- }
- func (fs *FileSystem) Set(path string, value string, expireTime time.Time, index uint64, term uint64) error {
- path = filepath.Clean("/" + path)
- // update file system known index and term
- fs.Index, fs.Term = index, term
- dir, name := filepath.Split(path)
- // walk through the path and get the last directory node
- d, err := fs.walk(dir, fs.checkDir)
- if err != nil {
- return err
- }
- f := newFile(name, value, fs.Index, fs.Term, d, "", expireTime)
- err = d.Add(f)
- if err == nil {
- if expireTime != Permanent {
- go f.Expire()
- }
- }
- return err
- }
- func (fs *FileSystem) TestAndSet() {
- }
- func (fs *FileSystem) TestIndexAndSet() {
- }
- func (fs *FileSystem) Delete(path string, recurisive bool, index uint64, term uint64) error {
- n, err := fs.InternalGet(path, index, term)
- if err != nil {
- return err
- }
- return n.Remove(recurisive)
- }
- // walk function walks all the path and apply the walkFunc on each directory
- func (fs *FileSystem) walk(path string, walkFunc func(prev *Node, component string) (*Node, error)) (*Node, error) {
- components := strings.Split(path, "/")
- curr := fs.Root
- var err error
- for i := 1; i < len(components); i++ {
- if len(components[i]) == 0 { // ignore empty string
- return curr, nil
- }
- curr, err = walkFunc(curr, components[i])
- if err != nil {
- return nil, err
- }
- }
- return curr, nil
- }
- // checkDir function will check whether the component is a directory under parent node.
- // If it is a directory, this function will return the pointer to that node.
- // If it does not exist, this function will create a new directory and return the pointer to that node.
- // If it is a file, this function will return error.
- func (fs *FileSystem) checkDir(parent *Node, dirName string) (*Node, error) {
- subDir, ok := parent.Children[dirName]
- if ok {
- return subDir, nil
- }
- n := newDir(filepath.Join(parent.Path, dirName), fs.Index, fs.Term, parent, parent.ACL)
- parent.Children[dirName] = n
- return n, nil
- }
|