add locking to fs cache

This commit is contained in:
Chris Lu 2020-04-08 12:50:34 -07:00
parent bd56172b82
commit b524a40375

View file

@ -9,6 +9,7 @@ import (
type FsCache struct { type FsCache struct {
root *FsNode root *FsNode
sync.RWMutex
} }
type FsNode struct { type FsNode struct {
parent *FsNode parent *FsNode
@ -27,6 +28,14 @@ func newFsCache(root fs.Node) *FsCache {
} }
func (c *FsCache) GetFsNode(path util.FullPath) fs.Node { func (c *FsCache) GetFsNode(path util.FullPath) fs.Node {
c.RLock()
defer c.RUnlock()
return c.doGetFsNode(path)
}
func (c *FsCache) doGetFsNode(path util.FullPath) fs.Node {
t := c.root t := c.root
for _, p := range path.Split() { for _, p := range path.Split() {
t = t.findChild(p) t = t.findChild(p)
@ -38,6 +47,14 @@ func (c *FsCache) GetFsNode(path util.FullPath) fs.Node {
} }
func (c *FsCache) SetFsNode(path util.FullPath, node fs.Node) { func (c *FsCache) SetFsNode(path util.FullPath, node fs.Node) {
c.Lock()
defer c.Unlock()
c.doSetFsNode(path, node)
}
func (c *FsCache) doSetFsNode(path util.FullPath, node fs.Node) {
t := c.root t := c.root
for _, p := range path.Split() { for _, p := range path.Split() {
t = t.ensureChild(p) t = t.ensureChild(p)
@ -45,17 +62,26 @@ func (c *FsCache) SetFsNode(path util.FullPath, node fs.Node) {
t.node = node t.node = node
} }
func (c *FsCache) EnsureFsNode(path util.FullPath, genNodeFn func() fs.Node) fs.Node { func (c *FsCache) EnsureFsNode(path util.FullPath, genNodeFn func() fs.Node) fs.Node {
t := c.GetFsNode(path)
c.Lock()
defer c.Unlock()
t := c.doGetFsNode(path)
if t != nil { if t != nil {
return t return t
} }
t = genNodeFn() t = genNodeFn()
c.SetFsNode(path, t) c.doSetFsNode(path, t)
return t return t
} }
func (c *FsCache) DeleteFsNode(path util.FullPath) { func (c *FsCache) DeleteFsNode(path util.FullPath) {
c.Lock()
defer c.Unlock()
t := c.root t := c.root
for _, p := range path.Split() { for _, p := range path.Split() {
t = t.findChild(p) t = t.findChild(p)
@ -72,6 +98,9 @@ func (c *FsCache) DeleteFsNode(path util.FullPath) {
// oldPath and newPath are full path including the new name // oldPath and newPath are full path including the new name
func (c *FsCache) Move(oldPath util.FullPath, newPath util.FullPath) *FsNode { func (c *FsCache) Move(oldPath util.FullPath, newPath util.FullPath) *FsNode {
c.Lock()
defer c.Unlock()
// find old node // find old node
src := c.root src := c.root
for _, p := range oldPath.Split() { for _, p := range oldPath.Split() {