github.com/mymmsc/gox@v1.3.33/util/redblacktree/iterator.go (about) 1 // Copyright (c) 2015, Emir Pasic. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package redblacktree 6 7 import ( 8 "github.com/mymmsc/gox/util" 9 ) 10 11 func assertIteratorImplementation() { 12 var _ util.ReverseIteratorWithKey = (*Iterator)(nil) 13 } 14 15 // Iterator holding the iterator's state 16 type Iterator struct { 17 tree *Tree 18 node *Node 19 position position 20 } 21 22 type position byte 23 24 const ( 25 begin, between, end position = 0, 1, 2 26 ) 27 28 // Iterator returns a stateful iterator whose elements are key/value pairs. 29 func (tree *Tree) Iterator() Iterator { 30 return Iterator{tree: tree, node: nil, position: begin} 31 } 32 33 // Next moves the iterator to the next element and returns true if there was a next element in the container. 34 // If Next() returns true, then next element's key and value can be retrieved by Key() and Value(). 35 // If Next() was called for the first time, then it will point the iterator to the first element if it exists. 36 // Modifies the state of the iterator. 37 func (iterator *Iterator) Next() bool { 38 if iterator.position == end { 39 goto end 40 } 41 if iterator.position == begin { 42 left := iterator.tree.Left() 43 if left == nil { 44 goto end 45 } 46 iterator.node = left 47 goto between 48 } 49 if iterator.node.Right != nil { 50 iterator.node = iterator.node.Right 51 for iterator.node.Left != nil { 52 iterator.node = iterator.node.Left 53 } 54 goto between 55 } 56 if iterator.node.Parent != nil { 57 node := iterator.node 58 for iterator.node.Parent != nil { 59 iterator.node = iterator.node.Parent 60 if iterator.tree.Comparator(node.Key, iterator.node.Key) <= 0 { 61 goto between 62 } 63 } 64 } 65 66 end: 67 iterator.node = nil 68 iterator.position = end 69 return false 70 71 between: 72 iterator.position = between 73 return true 74 } 75 76 // Prev moves the iterator to the previous element and returns true if there was a previous element in the container. 77 // If Prev() returns true, then previous element's key and value can be retrieved by Key() and Value(). 78 // Modifies the state of the iterator. 79 func (iterator *Iterator) Prev() bool { 80 if iterator.position == begin { 81 goto begin 82 } 83 if iterator.position == end { 84 right := iterator.tree.Right() 85 if right == nil { 86 goto begin 87 } 88 iterator.node = right 89 goto between 90 } 91 if iterator.node.Left != nil { 92 iterator.node = iterator.node.Left 93 for iterator.node.Right != nil { 94 iterator.node = iterator.node.Right 95 } 96 goto between 97 } 98 if iterator.node.Parent != nil { 99 node := iterator.node 100 for iterator.node.Parent != nil { 101 iterator.node = iterator.node.Parent 102 if iterator.tree.Comparator(node.Key, iterator.node.Key) >= 0 { 103 goto between 104 } 105 } 106 } 107 108 begin: 109 iterator.node = nil 110 iterator.position = begin 111 return false 112 113 between: 114 iterator.position = between 115 return true 116 } 117 118 // Value returns the current element's value. 119 // Does not modify the state of the iterator. 120 func (iterator *Iterator) Value() interface{} { 121 return iterator.node.Value 122 } 123 124 // Key returns the current element's key. 125 // Does not modify the state of the iterator. 126 func (iterator *Iterator) Key() interface{} { 127 return iterator.node.Key 128 } 129 130 // Begin resets the iterator to its initial state (one-before-first) 131 // Call Next() to fetch the first element if any. 132 func (iterator *Iterator) Begin() { 133 iterator.node = nil 134 iterator.position = begin 135 } 136 137 // End moves the iterator past the last element (one-past-the-end). 138 // Call Prev() to fetch the last element if any. 139 func (iterator *Iterator) End() { 140 iterator.node = nil 141 iterator.position = end 142 } 143 144 // First moves the iterator to the first element and returns true if there was a first element in the container. 145 // If First() returns true, then first element's key and value can be retrieved by Key() and Value(). 146 // Modifies the state of the iterator 147 func (iterator *Iterator) First() bool { 148 iterator.Begin() 149 return iterator.Next() 150 } 151 152 // Last moves the iterator to the last element and returns true if there was a last element in the container. 153 // If Last() returns true, then last element's key and value can be retrieved by Key() and Value(). 154 // Modifies the state of the iterator. 155 func (iterator *Iterator) Last() bool { 156 iterator.End() 157 return iterator.Prev() 158 }