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 }