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.

170 lines
3.0 KiB

  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.deleteChild(t.name)
  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.deleteChild(src.name)
  75. }
  76. src.parent = nil
  77. // find new node
  78. target := c.root
  79. for _, p := range newPath.Split() {
  80. target = target.ensureChild(p)
  81. }
  82. parent := target.parent
  83. src.name = target.name
  84. if dir, ok := src.node.(*Dir); ok {
  85. dir.name = target.name // target is not Dir, but a shortcut
  86. }
  87. parent.deleteChild(target.name)
  88. target.deleteSelf()
  89. src.connectToParent(parent)
  90. return src
  91. }
  92. func (n *FsNode) connectToParent(parent *FsNode) {
  93. n.parent = parent
  94. oldNode := parent.findChild(n.name)
  95. if oldNode != nil {
  96. oldNode.deleteSelf()
  97. }
  98. if dir, ok := n.node.(*Dir); ok {
  99. dir.parent = parent.node.(*Dir)
  100. }
  101. n.childrenLock.Lock()
  102. parent.children[n.name] = n
  103. n.childrenLock.Unlock()
  104. }
  105. func (n *FsNode) findChild(name string) *FsNode {
  106. n.childrenLock.RLock()
  107. defer n.childrenLock.RUnlock()
  108. child, found := n.children[name]
  109. if found {
  110. return child
  111. }
  112. return nil
  113. }
  114. func (n *FsNode) ensureChild(name string) *FsNode {
  115. n.childrenLock.Lock()
  116. defer n.childrenLock.Unlock()
  117. if n.children == nil {
  118. n.children = make(map[string]*FsNode)
  119. }
  120. child, found := n.children[name]
  121. if found {
  122. return child
  123. }
  124. t := &FsNode{
  125. parent: n,
  126. node: nil,
  127. name: name,
  128. children: nil,
  129. }
  130. n.children[name] = t
  131. return t
  132. }
  133. func (n *FsNode) deleteChild(name string) {
  134. n.childrenLock.Lock()
  135. delete(n.children, name)
  136. n.childrenLock.Unlock()
  137. }
  138. func (n *FsNode) deleteSelf() {
  139. n.childrenLock.Lock()
  140. for _, child := range n.children {
  141. child.deleteSelf()
  142. }
  143. n.children = nil
  144. n.childrenLock.Unlock()
  145. n.node = nil
  146. n.parent = nil
  147. }