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.

177 lines
3.1 KiB

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. f.dir = target.parent.node.(*Dir)
  92. }
  93. parent.disconnectChild(target)
  94. target.deleteSelf()
  95. src.connectToParent(parent)
  96. return src
  97. }
  98. func (n *FsNode) connectToParent(parent *FsNode) {
  99. n.parent = parent
  100. oldNode := parent.findChild(n.name)
  101. if oldNode != nil {
  102. oldNode.deleteSelf()
  103. }
  104. if dir, ok := n.node.(*Dir); ok {
  105. dir.parent = parent.node.(*Dir)
  106. }
  107. n.childrenLock.Lock()
  108. parent.children[n.name] = n
  109. n.childrenLock.Unlock()
  110. }
  111. func (n *FsNode) findChild(name string) *FsNode {
  112. n.childrenLock.RLock()
  113. defer n.childrenLock.RUnlock()
  114. child, found := n.children[name]
  115. if found {
  116. return child
  117. }
  118. return nil
  119. }
  120. func (n *FsNode) ensureChild(name string) *FsNode {
  121. n.childrenLock.Lock()
  122. defer n.childrenLock.Unlock()
  123. if n.children == nil {
  124. n.children = make(map[string]*FsNode)
  125. }
  126. child, found := n.children[name]
  127. if found {
  128. return child
  129. }
  130. t := &FsNode{
  131. parent: n,
  132. node: nil,
  133. name: name,
  134. children: nil,
  135. }
  136. n.children[name] = t
  137. return t
  138. }
  139. func (n *FsNode) disconnectChild(child *FsNode) {
  140. n.childrenLock.Lock()
  141. delete(n.children, child.name)
  142. n.childrenLock.Unlock()
  143. child.parent = nil
  144. }
  145. func (n *FsNode) deleteSelf() {
  146. n.childrenLock.Lock()
  147. for _, child := range n.children {
  148. child.deleteSelf()
  149. }
  150. n.children = nil
  151. n.childrenLock.Unlock()
  152. n.node = nil
  153. n.parent = nil
  154. }