iter_stack.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. // Copyright 2018 The Cockroach Authors.
  2. // Copyright 2021 Andrew Werner.
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
  13. // implied. See the License for the specific language governing
  14. // permissions and limitations under the License.
  15. package abstract
  16. // iterStack represents a stack of (node, pos) tuples, which captures
  17. // iteration state as an Iterator descends a AugBTree.
  18. type iterStack[K, V, A any] struct {
  19. a iterStackArr[K, V, A]
  20. aLen int16 // -1 when using s
  21. s []iterFrame[K, V, A]
  22. }
  23. const iterStackDepth = 10
  24. // Used to avoid allocations for stacks below a certain size.
  25. type iterStackArr[K, V, A any] [iterStackDepth]iterFrame[K, V, A]
  26. type iterFrame[K, V, A any] struct {
  27. node *Node[K, V, A]
  28. pos int16
  29. }
  30. func (is *iterStack[K, V, A]) push(f iterFrame[K, V, A]) {
  31. if is.aLen == -1 {
  32. is.s = append(is.s, f)
  33. } else if int(is.aLen) == len(is.a) {
  34. is.s = make([](iterFrame[K, V, A]), int(is.aLen)+1, 2*int(is.aLen))
  35. copy(is.s, is.a[:])
  36. is.s[int(is.aLen)] = f
  37. is.aLen = -1
  38. } else {
  39. is.a[is.aLen] = f
  40. is.aLen++
  41. }
  42. }
  43. func (is *iterStack[K, V, A]) pop() iterFrame[K, V, A] {
  44. if is.aLen == -1 {
  45. f := is.s[len(is.s)-1]
  46. is.s = is.s[:len(is.s)-1]
  47. return f
  48. }
  49. is.aLen--
  50. return is.a[is.aLen]
  51. }
  52. func (is *iterStack[K, V, A]) len() int {
  53. if is.aLen == -1 {
  54. return len(is.s)
  55. }
  56. return int(is.aLen)
  57. }
  58. func (is *iterStack[K, V, A]) reset() {
  59. if is.aLen == -1 {
  60. is.s = is.s[:0]
  61. } else {
  62. is.aLen = 0
  63. }
  64. }