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