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.

179 lines
3.2 KiB

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