fscache.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. package filesys
  2. import (
  3. "sync"
  4. "github.com/chrislusf/seaweedfs/weed/util"
  5. "github.com/seaweedfs/fuse/fs"
  6. )
  7. type FsCache struct {
  8. root *FsNode
  9. sync.RWMutex
  10. }
  11. type FsNode struct {
  12. parent *FsNode
  13. node fs.Node
  14. name string
  15. childrenLock sync.RWMutex
  16. children map[string]*FsNode
  17. }
  18. func newFsCache(root fs.Node) *FsCache {
  19. return &FsCache{
  20. root: &FsNode{
  21. node: root,
  22. },
  23. }
  24. }
  25. func (c *FsCache) GetFsNode(path util.FullPath) fs.Node {
  26. c.RLock()
  27. defer c.RUnlock()
  28. return c.doGetFsNode(path)
  29. }
  30. func (c *FsCache) doGetFsNode(path util.FullPath) fs.Node {
  31. t := c.root
  32. for _, p := range path.Split() {
  33. t = t.findChild(p)
  34. if t == nil {
  35. return nil
  36. }
  37. }
  38. return t.node
  39. }
  40. func (c *FsCache) SetFsNode(path util.FullPath, node fs.Node) {
  41. c.Lock()
  42. defer c.Unlock()
  43. c.doSetFsNode(path, node)
  44. }
  45. func (c *FsCache) doSetFsNode(path util.FullPath, node fs.Node) {
  46. t := c.root
  47. for _, p := range path.Split() {
  48. t = t.ensureChild(p)
  49. }
  50. t.node = node
  51. }
  52. func (c *FsCache) EnsureFsNode(path util.FullPath, genNodeFn func() fs.Node) fs.Node {
  53. c.Lock()
  54. defer c.Unlock()
  55. t := c.doGetFsNode(path)
  56. if t != nil {
  57. return t
  58. }
  59. t = genNodeFn()
  60. c.doSetFsNode(path, t)
  61. return t
  62. }
  63. func (c *FsCache) DeleteFsNode(path util.FullPath) {
  64. c.Lock()
  65. defer c.Unlock()
  66. t := c.root
  67. for _, p := range path.Split() {
  68. t = t.findChild(p)
  69. if t == nil {
  70. return
  71. }
  72. }
  73. if t.parent != nil {
  74. t.parent.disconnectChild(t)
  75. }
  76. t.deleteSelf()
  77. }
  78. // oldPath and newPath are full path including the new name
  79. func (c *FsCache) Move(oldPath util.FullPath, newPath util.FullPath) *FsNode {
  80. c.Lock()
  81. defer c.Unlock()
  82. // find old node
  83. src := c.root
  84. for _, p := range oldPath.Split() {
  85. src = src.findChild(p)
  86. if src == nil {
  87. return src
  88. }
  89. }
  90. if src.parent != nil {
  91. src.parent.disconnectChild(src)
  92. }
  93. // find new node
  94. target := c.root
  95. for _, p := range newPath.Split() {
  96. target = target.ensureChild(p)
  97. }
  98. parent := target.parent
  99. src.name = target.name
  100. if dir, ok := src.node.(*Dir); ok {
  101. dir.name = target.name // target is not Dir, but a shortcut
  102. }
  103. if f, ok := src.node.(*File); ok {
  104. f.Name = target.name
  105. if f.entry != nil {
  106. f.entry.Name = f.Name
  107. }
  108. }
  109. parent.disconnectChild(target)
  110. target.deleteSelf()
  111. src.connectToParent(parent)
  112. return src
  113. }
  114. func (n *FsNode) connectToParent(parent *FsNode) {
  115. n.parent = parent
  116. oldNode := parent.findChild(n.name)
  117. if oldNode != nil {
  118. oldNode.deleteSelf()
  119. }
  120. if dir, ok := n.node.(*Dir); ok {
  121. dir.parent = parent.node.(*Dir)
  122. }
  123. if f, ok := n.node.(*File); ok {
  124. f.dir = parent.node.(*Dir)
  125. }
  126. n.childrenLock.Lock()
  127. parent.children[n.name] = n
  128. n.childrenLock.Unlock()
  129. }
  130. func (n *FsNode) findChild(name string) *FsNode {
  131. n.childrenLock.RLock()
  132. defer n.childrenLock.RUnlock()
  133. child, found := n.children[name]
  134. if found {
  135. return child
  136. }
  137. return nil
  138. }
  139. func (n *FsNode) ensureChild(name string) *FsNode {
  140. n.childrenLock.Lock()
  141. defer n.childrenLock.Unlock()
  142. if n.children == nil {
  143. n.children = make(map[string]*FsNode)
  144. }
  145. child, found := n.children[name]
  146. if found {
  147. return child
  148. }
  149. t := &FsNode{
  150. parent: n,
  151. node: nil,
  152. name: name,
  153. children: nil,
  154. }
  155. n.children[name] = t
  156. return t
  157. }
  158. func (n *FsNode) disconnectChild(child *FsNode) {
  159. n.childrenLock.Lock()
  160. delete(n.children, child.name)
  161. n.childrenLock.Unlock()
  162. child.parent = nil
  163. }
  164. func (n *FsNode) deleteSelf() {
  165. n.childrenLock.Lock()
  166. for _, child := range n.children {
  167. child.deleteSelf()
  168. }
  169. n.children = nil
  170. n.childrenLock.Unlock()
  171. n.node = nil
  172. n.parent = nil
  173. }