tree.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. package store
  2. import (
  3. "path"
  4. "strings"
  5. "sort"
  6. )
  7. type tree struct {
  8. Root *treeNode
  9. }
  10. type treeNode struct {
  11. Value Node
  12. Dir bool //for clearity
  13. NodeMap map[string]*treeNode
  14. }
  15. type tnWithKey struct{
  16. key string
  17. tn *treeNode
  18. }
  19. type tnWithKeySlice []tnWithKey
  20. func (s tnWithKeySlice) Len() int { return len(s) }
  21. func (s tnWithKeySlice) Less(i, j int) bool { return s[i].key < s[j].key }
  22. func (s tnWithKeySlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
  23. var emptyNode = Node{".", PERMANENT, nil}
  24. // set the key to value, return the old value if the key exists
  25. func (t *tree) set(key string, value Node) bool {
  26. key = "/" + key
  27. key = path.Clean(key)
  28. nodes := strings.Split(key, "/")
  29. nodes = nodes[1:]
  30. //fmt.Println("TreeStore: Nodes ", nodes, " length: ", len(nodes))
  31. nodeMap := t.Root.NodeMap
  32. i := 0
  33. newDir := false
  34. for i = 0; i < len(nodes) - 1; i++ {
  35. if newDir {
  36. node := &treeNode{emptyNode, true, make(map[string]*treeNode)}
  37. nodeMap[nodes[i]] = node
  38. nodeMap = node.NodeMap
  39. continue
  40. }
  41. node, ok := nodeMap[nodes[i]]
  42. // add new dir
  43. if !ok {
  44. //fmt.Println("TreeStore: Add a dir ", nodes[i])
  45. newDir = true
  46. node := &treeNode{emptyNode, true, make(map[string]*treeNode)}
  47. nodeMap[nodes[i]] = node
  48. nodeMap = node.NodeMap
  49. } else if ok && !node.Dir {
  50. return false
  51. } else {
  52. //fmt.Println("TreeStore: found dir ", nodes[i])
  53. nodeMap = node.NodeMap
  54. }
  55. }
  56. // add the last node and value
  57. node, ok := nodeMap[nodes[i]]
  58. if !ok {
  59. node := &treeNode{value, false, nil}
  60. nodeMap[nodes[i]] = node
  61. //fmt.Println("TreeStore: Add a new Node ", key, "=", value)
  62. } else {
  63. node.Value = value
  64. //fmt.Println("TreeStore: Update a Node ", key, "=", value, "[", oldValue, "]")
  65. }
  66. return true
  67. }
  68. // use internally to get the internal tree node
  69. func (t *tree)internalGet(key string) (*treeNode, bool) {
  70. key = "/" + key
  71. key = path.Clean(key)
  72. nodes := strings.Split(key, "/")
  73. nodes = nodes[1:]
  74. //fmt.Println("TreeStore: Nodes ", nodes, " length: ", len(nodes))
  75. nodeMap := t.Root.NodeMap
  76. var i int
  77. for i = 0; i < len(nodes) - 1; i++ {
  78. node, ok := nodeMap[nodes[i]]
  79. if !ok || !node.Dir {
  80. return nil, false
  81. }
  82. nodeMap = node.NodeMap
  83. }
  84. treeNode, ok := nodeMap[nodes[i]]
  85. if ok {
  86. return treeNode, ok
  87. } else {
  88. return nil, ok
  89. }
  90. }
  91. // get the node of the key
  92. func (t *tree) get(key string) (Node, bool) {
  93. treeNode, ok := t.internalGet(key)
  94. if ok {
  95. return treeNode.Value, ok
  96. } else {
  97. return emptyNode, ok
  98. }
  99. }
  100. // return the nodes under the directory
  101. func (t *tree) list(prefix string) ([]Node, []string, []string, bool) {
  102. treeNode, ok := t.internalGet(prefix)
  103. if !ok {
  104. return nil, nil, nil, ok
  105. } else {
  106. length := len(treeNode.NodeMap)
  107. nodes := make([]Node, length)
  108. keys := make([]string, length)
  109. dirs := make([]string, length)
  110. i := 0
  111. for key, node := range treeNode.NodeMap {
  112. nodes[i] = node.Value
  113. keys[i] = key
  114. if node.Dir {
  115. dirs[i] = "d"
  116. } else {
  117. dirs[i] = "f"
  118. }
  119. i++
  120. }
  121. return nodes, keys, dirs, ok
  122. }
  123. }
  124. // delete the key, return the old value if the key exists
  125. func (t *tree) delete(key string) bool {
  126. key = "/" + key
  127. key = path.Clean(key)
  128. nodes := strings.Split(key, "/")
  129. nodes = nodes[1:]
  130. //fmt.Println("TreeStore: Nodes ", nodes, " length: ", len(nodes))
  131. nodeMap := t.Root.NodeMap
  132. var i int
  133. for i = 0; i < len(nodes) - 1; i++ {
  134. node, ok := nodeMap[nodes[i]]
  135. if !ok || !node.Dir {
  136. return false
  137. }
  138. nodeMap = node.NodeMap
  139. }
  140. node, ok := nodeMap[nodes[i]]
  141. if ok && !node.Dir{
  142. delete(nodeMap, nodes[i])
  143. return true
  144. }
  145. return false
  146. }
  147. func (t *tree) traverse(f func(string, *Node), sort bool) {
  148. if sort {
  149. sortDfs("", t.Root, f)
  150. } else {
  151. dfs("", t.Root, f)
  152. }
  153. }
  154. func dfs(key string, t *treeNode, f func(string, *Node)) {
  155. // base case
  156. if len(t.NodeMap) == 0{
  157. f(key, &t.Value)
  158. // recursion
  159. } else {
  160. for nodeKey, _treeNode := range t.NodeMap {
  161. newKey := key + "/" + nodeKey
  162. dfs(newKey, _treeNode, f)
  163. }
  164. }
  165. }
  166. func sortDfs(key string, t *treeNode, f func(string, *Node)) {
  167. // base case
  168. if len(t.NodeMap) == 0{
  169. f(key, &t.Value)
  170. // recursion
  171. } else {
  172. s := make(tnWithKeySlice, len(t.NodeMap))
  173. i := 0
  174. // copy
  175. for nodeKey, _treeNode := range t.NodeMap {
  176. newKey := key + "/" + nodeKey
  177. s[i] = tnWithKey{newKey, _treeNode}
  178. i++
  179. }
  180. // sort
  181. sort.Sort(s)
  182. // traverse
  183. for i = 0; i < len(t.NodeMap); i++ {
  184. sortDfs(s[i].key, s[i].tn, f)
  185. }
  186. }
  187. }