github.com/safing/portbase@v0.19.5/database/iterator/iterator.go (about)

     1  package iterator
     2  
     3  import (
     4  	"sync"
     5  
     6  	"github.com/tevino/abool"
     7  
     8  	"github.com/safing/portbase/database/record"
     9  )
    10  
    11  // Iterator defines the iterator structure.
    12  type Iterator struct {
    13  	Next chan record.Record
    14  	Done chan struct{}
    15  
    16  	errLock    sync.Mutex
    17  	err        error
    18  	doneClosed *abool.AtomicBool
    19  }
    20  
    21  // New creates a new Iterator.
    22  func New() *Iterator {
    23  	return &Iterator{
    24  		Next:       make(chan record.Record, 10),
    25  		Done:       make(chan struct{}),
    26  		doneClosed: abool.NewBool(false),
    27  	}
    28  }
    29  
    30  // Finish is called be the storage to signal the end of the query results.
    31  func (it *Iterator) Finish(err error) {
    32  	close(it.Next)
    33  	if it.doneClosed.SetToIf(false, true) {
    34  		close(it.Done)
    35  	}
    36  
    37  	it.errLock.Lock()
    38  	defer it.errLock.Unlock()
    39  	it.err = err
    40  }
    41  
    42  // Cancel is called by the iteration consumer to cancel the running query.
    43  func (it *Iterator) Cancel() {
    44  	if it.doneClosed.SetToIf(false, true) {
    45  		close(it.Done)
    46  	}
    47  }
    48  
    49  // Err returns the iterator error, if exists.
    50  func (it *Iterator) Err() error {
    51  	it.errLock.Lock()
    52  	defer it.errLock.Unlock()
    53  	return it.err
    54  }