You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

212 lines
3.6 KiB

4 years ago
4 years ago
4 years ago
4 years ago
  1. package filesys
  2. import (
  3. "sync"
  4. "github.com/seaweedfs/fuse/fs"
  5. "github.com/chrislusf/seaweedfs/weed/util"
  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. if dir, ok := src.node.(*Dir); ok {
  100. dir.name = target.name // target is not Dir, but a shortcut
  101. }
  102. if f, ok := src.node.(*File); ok {
  103. f.Name = target.name
  104. if f.entry != nil {
  105. f.entry.Name = f.Name
  106. }
  107. }
  108. parent.disconnectChild(target)
  109. target.deleteSelf()
  110. src.name = target.name
  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. if parent.node != nil {
  122. dir.parent = parent.node.(*Dir)
  123. }
  124. }
  125. if f, ok := n.node.(*File); ok {
  126. if parent.node != nil {
  127. f.dir = parent.node.(*Dir)
  128. }
  129. }
  130. n.childrenLock.Lock()
  131. parent.children[n.name] = n
  132. n.childrenLock.Unlock()
  133. }
  134. func (n *FsNode) findChild(name string) *FsNode {
  135. n.childrenLock.RLock()
  136. defer n.childrenLock.RUnlock()
  137. child, found := n.children[name]
  138. if found {
  139. return child
  140. }
  141. return nil
  142. }
  143. func (n *FsNode) ensureChild(name string) *FsNode {
  144. n.childrenLock.Lock()
  145. defer n.childrenLock.Unlock()
  146. if n.children == nil {
  147. n.children = make(map[string]*FsNode)
  148. }
  149. child, found := n.children[name]
  150. if found {
  151. return child
  152. }
  153. t := &FsNode{
  154. parent: n,
  155. node: nil,
  156. name: name,
  157. children: nil,
  158. }
  159. n.children[name] = t
  160. return t
  161. }
  162. func (n *FsNode) disconnectChild(child *FsNode) {
  163. n.childrenLock.Lock()
  164. delete(n.children, child.name)
  165. n.childrenLock.Unlock()
  166. child.parent = nil
  167. }
  168. func (n *FsNode) deleteSelf() {
  169. n.childrenLock.Lock()
  170. for _, child := range n.children {
  171. child.deleteSelf()
  172. }
  173. n.children = nil
  174. n.childrenLock.Unlock()
  175. n.node = nil
  176. n.parent = nil
  177. }