Browse Source

update file

Xiang Li 12 years ago
parent
commit
cc77613fd9
3 changed files with 64 additions and 32 deletions
  1. 19 11
      file_system/file_system.go
  2. 26 0
      file_system/file_system_test.go
  3. 19 21
      file_system/node.go

+ 19 - 11
file_system/file_system.go

@@ -75,23 +75,31 @@ func (fs *FileSystem) Set(key_path string, value string, expireTime time.Time, i
 		return nil, err
 	}
 
-	f := newFile(key_path, value, fs.Index, fs.Term, d, "", expireTime)
 	e := newEvent(Set, key_path, fs.Index, fs.Term)
-	e.Value = f.Value
+	e.Value = value
 
-	// remove previous file if exist
-	oldFile, err := d.GetFile(name)
+	f, err := d.GetFile(name)
 
 	if err == nil {
-		if oldFile != nil {
-			oldFile.Remove(false)
-			e.PrevValue = oldFile.Value
+
+		if f != nil { // update previous file if exist
+			e.PrevValue = f.Value
+			f.Write(e.Value)
+
+			// if the previous ExpireTime is not Permanent and expireTime is given
+			// we stop the previous expire routine
+			if f.ExpireTime != Permanent && expireTime != Permanent {
+				f.stopExpire <- true
+			}
+		} else { // create new file
+
+			f = newFile(key_path, value, fs.Index, fs.Term, d, "", expireTime)
+
+			err = d.Add(f)
+
 		}
-	} else {
-		return nil, err
-	}
 
-	err = d.Add(f)
+	}
 
 	if err != nil {
 		return nil, err

+ 26 - 0
file_system/file_system_test.go

@@ -12,6 +12,32 @@ func TestSetAndGet(t *testing.T) {
 	setAndGet(fs, "/foo/foo/bar", t)
 }
 
+func TestUpdateFile(t *testing.T) {
+	fs := New()
+
+	_, err := fs.Set("/foo/bar", "bar", Permanent, 1, 1)
+
+	if err != nil {
+		t.Fatalf("cannot set %s=bar [%s]", "/foo/bar", err.Error())
+	}
+
+	_, err = fs.Set("/foo/bar", "barbar", Permanent, 2, 1)
+
+	if err != nil {
+		t.Fatalf("cannot set %s=barbar [%s]", "/foo/bar", err.Error())
+	}
+
+	e, err := fs.Get("/foo/bar", false, 2, 1)
+
+	if err != nil {
+		t.Fatalf("cannot get %s [%s]", "/foo/bar", err.Error())
+	}
+
+	if e.Value != "barbar" {
+		t.Fatalf("expect value of %s is barbar [%s]", "/foo/bar", e.Value)
+	}
+}
+
 func TestListDirectory(t *testing.T) {
 	fs := New()
 

+ 19 - 21
file_system/node.go

@@ -29,7 +29,7 @@ type Node struct {
 	Children    map[string]*Node // for directory
 	status      int
 	mu          sync.Mutex
-	removeChan  chan bool // remove channel
+	stopExpire  chan bool // stop expire routine channel
 }
 
 func newFile(key_path string, value string, createIndex uint64, createTerm uint64, parent *Node, ACL string, expireTime time.Time) *Node {
@@ -39,7 +39,7 @@ func newFile(key_path string, value string, createIndex uint64, createTerm uint6
 		CreateTerm:  createTerm,
 		Parent:      parent,
 		ACL:         ACL,
-		removeChan:  make(chan bool, 1),
+		stopExpire:  make(chan bool, 1),
 		ExpireTime:  expireTime,
 		Value:       value,
 	}
@@ -52,7 +52,7 @@ func newDir(key_path string, createIndex uint64, createTerm uint64, parent *Node
 		CreateTerm:  createTerm,
 		Parent:      parent,
 		ACL:         ACL,
-		removeChan:  make(chan bool, 1),
+		stopExpire:  make(chan bool, 1),
 		Children:    make(map[string]*Node),
 	}
 }
@@ -75,7 +75,7 @@ func (n *Node) Remove(recursive bool) error {
 			// This is the only pointer to Node object
 			// Handled by garbage collector
 			delete(n.Parent.Children, name)
-			n.removeChan <- true
+			n.stopExpire <- true
 			n.status = removed
 		}
 
@@ -94,7 +94,7 @@ func (n *Node) Remove(recursive bool) error {
 	_, name := path.Split(n.Path)
 	if n.Parent.Children[name] == n {
 		delete(n.Parent.Children, name)
-		n.removeChan <- true
+		n.stopExpire <- true
 		n.status = removed
 	}
 
@@ -226,25 +226,23 @@ func (n *Node) IsDir() bool {
 }
 
 func (n *Node) Expire() {
-	for {
-		duration := n.ExpireTime.Sub(time.Now())
-		if duration <= 0 {
-			n.Remove(true)
-			return
-		}
+	duration := n.ExpireTime.Sub(time.Now())
+	if duration <= 0 {
+		n.Remove(true)
+		return
+	}
 
-		select {
-		// if timeout, delete the node
-		case <-time.After(duration):
-			n.Remove(true)
-			return
+	select {
+	// if timeout, delete the node
+	case <-time.After(duration):
+		n.Remove(true)
+		return
 
-		// if removed, return
-		case <-n.removeChan:
-			fmt.Println("node removed")
-			return
+	// if stopped, return
+	case <-n.stopExpire:
+		fmt.Println("expire stopped")
+		return
 
-		}
 	}
 }