github.com/mymmsc/gox@v1.3.33/util/avltree/iterator.go (about)

     1  // Copyright (c) 2017, Benjamin Scher Purcell. 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 avltree
     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() util.ReverseIteratorWithKey {
    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  	switch iterator.position {
    39  	case begin:
    40  		iterator.position = between
    41  		iterator.node = iterator.tree.Left()
    42  	case between:
    43  		iterator.node = iterator.node.Next()
    44  	}
    45  
    46  	if iterator.node == nil {
    47  		iterator.position = end
    48  		return false
    49  	}
    50  	return true
    51  }
    52  
    53  // Prev moves the iterator to the next element and returns true if there was a previous element in the container.
    54  // If Prev() returns true, then next element's key and value can be retrieved by Key() and Value().
    55  // If Prev() was called for the first time, then it will point the iterator to the first element if it exists.
    56  // Modifies the state of the iterator.
    57  func (iterator *Iterator) Prev() bool {
    58  	switch iterator.position {
    59  	case end:
    60  		iterator.position = between
    61  		iterator.node = iterator.tree.Right()
    62  	case between:
    63  		iterator.node = iterator.node.Prev()
    64  	}
    65  
    66  	if iterator.node == nil {
    67  		iterator.position = begin
    68  		return false
    69  	}
    70  	return true
    71  }
    72  
    73  // Value returns the current element's value.
    74  // Does not modify the state of the iterator.
    75  func (iterator *Iterator) Value() interface{} {
    76  	if iterator.node == nil {
    77  		return nil
    78  	}
    79  	return iterator.node.Value
    80  }
    81  
    82  // Key returns the current element's key.
    83  // Does not modify the state of the iterator.
    84  func (iterator *Iterator) Key() interface{} {
    85  	if iterator.node == nil {
    86  		return nil
    87  	}
    88  	return iterator.node.Key
    89  }
    90  
    91  // Begin resets the iterator to its initial state (one-before-first)
    92  // Call Next() to fetch the first element if any.
    93  func (iterator *Iterator) Begin() {
    94  	iterator.node = nil
    95  	iterator.position = begin
    96  }
    97  
    98  // End moves the iterator past the last element (one-past-the-end).
    99  // Call Prev() to fetch the last element if any.
   100  func (iterator *Iterator) End() {
   101  	iterator.node = nil
   102  	iterator.position = end
   103  }
   104  
   105  // First moves the iterator to the first element and returns true if there was a first element in the container.
   106  // If First() returns true, then first element's key and value can be retrieved by Key() and Value().
   107  // Modifies the state of the iterator
   108  func (iterator *Iterator) First() bool {
   109  	iterator.Begin()
   110  	return iterator.Next()
   111  }
   112  
   113  // Last moves the iterator to the last element and returns true if there was a last element in the container.
   114  // If Last() returns true, then last element's key and value can be retrieved by Key() and Value().
   115  // Modifies the state of the iterator.
   116  func (iterator *Iterator) Last() bool {
   117  	iterator.End()
   118  	return iterator.Prev()
   119  }