map.go 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. // Copyright (c) 2017 Arista Networks, Inc.
  2. // Use of this source code is governed by the Apache License 2.0
  3. // that can be found in the COPYING file.
  4. package path
  5. import (
  6. "bytes"
  7. "fmt"
  8. "sort"
  9. "notabug.org/themusicgod1/goarista/key"
  10. )
  11. // Map associates paths to values. It allows wildcards. A Map
  12. // is primarily used to register handlers with paths that can
  13. // be easily looked up each time a path is updated.
  14. type Map struct {
  15. val interface{}
  16. ok bool
  17. wildcard *Map
  18. children map[key.Key]*Map
  19. }
  20. // VisitorFunc is a function that handles the value associated
  21. // with a path in a Map. Note that only the value is passed in
  22. // as an argument since the path can be stored inside the value
  23. // if needed.
  24. type VisitorFunc func(v interface{}) error
  25. // Visit calls a function fn for every value in the Map
  26. // that is registered with a match of a path p. In the
  27. // general case, time complexity is linear with respect
  28. // to the length of p but it can be as bad as O(2^len(p))
  29. // if there are a lot of paths with wildcards registered.
  30. //
  31. // Example:
  32. //
  33. // a := path.New("foo", "bar", "baz")
  34. // b := path.New("foo", path.Wildcard, "baz")
  35. // c := path.New(path.Wildcard, "bar", "baz")
  36. // d := path.New("foo", "bar", path.Wildcard)
  37. // e := path.New(path.Wildcard, path.Wildcard, "baz")
  38. // f := path.New(path.Wildcard, "bar", path.Wildcard)
  39. // g := path.New("foo", path.Wildcard, path.Wildcard)
  40. // h := path.New(path.Wildcard, path.Wildcard, path.Wildcard)
  41. //
  42. // m.Set(a, 1)
  43. // m.Set(b, 2)
  44. // m.Set(c, 3)
  45. // m.Set(d, 4)
  46. // m.Set(e, 5)
  47. // m.Set(f, 6)
  48. // m.Set(g, 7)
  49. // m.Set(h, 8)
  50. //
  51. // p := path.New("foo", "bar", "baz")
  52. //
  53. // m.Visit(p, fn)
  54. //
  55. // Result: fn(1), fn(2), fn(3), fn(4), fn(5), fn(6), fn(7) and fn(8)
  56. func (m *Map) Visit(p key.Path, fn VisitorFunc) error {
  57. for i, element := range p {
  58. if m.wildcard != nil {
  59. if err := m.wildcard.Visit(p[i+1:], fn); err != nil {
  60. return err
  61. }
  62. }
  63. next, ok := m.children[element]
  64. if !ok {
  65. return nil
  66. }
  67. m = next
  68. }
  69. if !m.ok {
  70. return nil
  71. }
  72. return fn(m.val)
  73. }
  74. // VisitPrefixes calls a function fn for every value in the
  75. // Map that is registered with a prefix of a path p.
  76. //
  77. // Example:
  78. //
  79. // a := path.New()
  80. // b := path.New("foo")
  81. // c := path.New("foo", "bar")
  82. // d := path.New("foo", "baz")
  83. // e := path.New(path.Wildcard, "bar")
  84. //
  85. // m.Set(a, 1)
  86. // m.Set(b, 2)
  87. // m.Set(c, 3)
  88. // m.Set(d, 4)
  89. // m.Set(e, 5)
  90. //
  91. // p := path.New("foo", "bar", "baz")
  92. //
  93. // m.VisitPrefixes(p, fn)
  94. //
  95. // Result: fn(1), fn(2), fn(3), fn(5)
  96. func (m *Map) VisitPrefixes(p key.Path, fn VisitorFunc) error {
  97. for i, element := range p {
  98. if m.ok {
  99. if err := fn(m.val); err != nil {
  100. return err
  101. }
  102. }
  103. if m.wildcard != nil {
  104. if err := m.wildcard.VisitPrefixes(p[i+1:], fn); err != nil {
  105. return err
  106. }
  107. }
  108. next, ok := m.children[element]
  109. if !ok {
  110. return nil
  111. }
  112. m = next
  113. }
  114. if !m.ok {
  115. return nil
  116. }
  117. return fn(m.val)
  118. }
  119. // VisitPrefixed calls fn for every value in the map that is
  120. // registerd with a path that is prefixed by p. This method
  121. // can be used to visit every registered path if p is the
  122. // empty path (or root path) which prefixes all paths.
  123. //
  124. // Example:
  125. //
  126. // a := path.New("foo")
  127. // b := path.New("foo", "bar")
  128. // c := path.New("foo", "bar", "baz")
  129. // d := path.New("foo", path.Wildcard)
  130. //
  131. // m.Set(a, 1)
  132. // m.Set(b, 2)
  133. // m.Set(c, 3)
  134. // m.Set(d, 4)
  135. //
  136. // p := path.New("foo", "bar")
  137. //
  138. // m.VisitPrefixed(p, fn)
  139. //
  140. // Result: fn(2), fn(3), fn(4)
  141. func (m *Map) VisitPrefixed(p key.Path, fn VisitorFunc) error {
  142. for i, element := range p {
  143. if m.wildcard != nil {
  144. if err := m.wildcard.VisitPrefixed(p[i+1:], fn); err != nil {
  145. return err
  146. }
  147. }
  148. next, ok := m.children[element]
  149. if !ok {
  150. return nil
  151. }
  152. m = next
  153. }
  154. return m.visitSubtree(fn)
  155. }
  156. func (m *Map) visitSubtree(fn VisitorFunc) error {
  157. if m.ok {
  158. if err := fn(m.val); err != nil {
  159. return err
  160. }
  161. }
  162. if m.wildcard != nil {
  163. if err := m.wildcard.visitSubtree(fn); err != nil {
  164. return err
  165. }
  166. }
  167. for _, next := range m.children {
  168. if err := next.visitSubtree(fn); err != nil {
  169. return err
  170. }
  171. }
  172. return nil
  173. }
  174. // Get returns the value registered with an exact match of a
  175. // path p. If there is no exact match for p, Get returns nil
  176. // and false. If p has an exact match and it is set to true,
  177. // Get returns nil and true.
  178. //
  179. // Example:
  180. //
  181. // m.Set(path.New("foo", "bar"), 1)
  182. // m.Set(path.New("baz", "qux"), nil)
  183. //
  184. // a := m.Get(path.New("foo", "bar"))
  185. // b := m.Get(path.New("foo", path.Wildcard))
  186. // c, ok := m.Get(path.New("baz", "qux"))
  187. //
  188. // Result: a == 1, b == nil, c == nil and ok == true
  189. func (m *Map) Get(p key.Path) (interface{}, bool) {
  190. for _, element := range p {
  191. if element.Equal(Wildcard) {
  192. if m.wildcard == nil {
  193. return nil, false
  194. }
  195. m = m.wildcard
  196. continue
  197. }
  198. next, ok := m.children[element]
  199. if !ok {
  200. return nil, false
  201. }
  202. m = next
  203. }
  204. return m.val, m.ok
  205. }
  206. // Set registers a path p with a value. Any previous value that
  207. // was registered with p is overwritten.
  208. //
  209. // Example:
  210. //
  211. // p := path.New("foo", "bar")
  212. //
  213. // m.Set(p, 0)
  214. // m.Set(p, 1)
  215. //
  216. // v := m.Get(p)
  217. //
  218. // Result: v == 1
  219. func (m *Map) Set(p key.Path, v interface{}) {
  220. for _, element := range p {
  221. if element.Equal(Wildcard) {
  222. if m.wildcard == nil {
  223. m.wildcard = &Map{}
  224. }
  225. m = m.wildcard
  226. continue
  227. }
  228. if m.children == nil {
  229. m.children = map[key.Key]*Map{}
  230. }
  231. next, ok := m.children[element]
  232. if !ok {
  233. next = &Map{}
  234. m.children[element] = next
  235. }
  236. m = next
  237. }
  238. m.val, m.ok = v, true
  239. }
  240. // Delete unregisters the value registered with a path. It
  241. // returns true if a value was deleted and false otherwise.
  242. //
  243. // Example:
  244. //
  245. // p := path.New("foo", "bar")
  246. //
  247. // m.Set(p, 0)
  248. //
  249. // a := m.Delete(p)
  250. // b := m.Delete(p)
  251. //
  252. // Result: a == true and b == false
  253. func (m *Map) Delete(p key.Path) bool {
  254. maps := make([]*Map, len(p)+1)
  255. for i, element := range p {
  256. maps[i] = m
  257. if element.Equal(Wildcard) {
  258. if m.wildcard == nil {
  259. return false
  260. }
  261. m = m.wildcard
  262. continue
  263. }
  264. next, ok := m.children[element]
  265. if !ok {
  266. return false
  267. }
  268. m = next
  269. }
  270. m.val, m.ok = nil, false
  271. maps[len(p)] = m
  272. // Remove any empty maps.
  273. for i := len(p); i > 0; i-- {
  274. m = maps[i]
  275. if m.ok || m.wildcard != nil || len(m.children) > 0 {
  276. break
  277. }
  278. parent := maps[i-1]
  279. element := p[i-1]
  280. if element.Equal(Wildcard) {
  281. parent.wildcard = nil
  282. } else {
  283. delete(parent.children, element)
  284. }
  285. }
  286. return true
  287. }
  288. func (m *Map) String() string {
  289. var b bytes.Buffer
  290. m.write(&b, "")
  291. return b.String()
  292. }
  293. func (m *Map) write(b *bytes.Buffer, indent string) {
  294. if m.ok {
  295. b.WriteString(indent)
  296. fmt.Fprintf(b, "Val: %v", m.val)
  297. b.WriteString("\n")
  298. }
  299. if m.wildcard != nil {
  300. b.WriteString(indent)
  301. fmt.Fprintf(b, "Child %q:\n", Wildcard)
  302. m.wildcard.write(b, indent+" ")
  303. }
  304. children := make([]key.Key, 0, len(m.children))
  305. for key := range m.children {
  306. children = append(children, key)
  307. }
  308. sort.Slice(children, func(i, j int) bool {
  309. return children[i].String() < children[j].String()
  310. })
  311. for _, key := range children {
  312. child := m.children[key]
  313. b.WriteString(indent)
  314. fmt.Fprintf(b, "Child %q:\n", key.String())
  315. child.write(b, indent+" ")
  316. }
  317. }