Lazy iterator experimentation. The aim of this lib is to enable lazy loading an iterator's content. The lazy loading is achieved using a goroutine and two channels per iterator.
func main() {
iter := laziter.New[int](false) // No persistence needed here
defer iter.Close() // Close() should always be called to prevent leaking goroutines
// Start values provider goroutine
go sampleValuesGenerator(iter.GetValuesProvider(), 5)
// Iterate over values
for iter.Next() {
value, _ := iter.GetCurrentValue()
}
}
func sampleValuesGenerator(vp *laziter.ValuesProvider[int], valuesCount int) {
defer vp.Close()
for i := 0; i < valuesCount; i++ {
if !vp.Wait() {
// Iterator stopped iteration, quit
break
}
vp.Yield(i) // Produce value
}
}The following example shows a partial iteration with the lazy iterator. Once sampleFunction() returns, sampleValuesGenerator() goroutine will end, skipping the last 2 values that won't be evaluated (3 & 4). You may stop the iteration early by calling iter.Done(), here it is called in a defer statement.
func sampleFunction() {
iter := laziter.New[int](false) // No persistence needed here
defer iter.Close()
// Start values provider goroutine
go sampleValuesGenerator(iter.GetValuesProvider(), 5)
// Get 3 values
for i := 0; i < 4; i++ {
value, _ := iter.GetCurrentValue()
}
}
func sampleValuesGenerator(vp *laziter.ValuesProvider[int], valuesCount int) {
// [...] (same as above)
}The current Iterator implementation allows values persistence which enables, for example, multiple for iter.Next() { [...] } statements.
It is also possible to call ResetIteratorPosition() while iterating. This will pause values retrieval until the iterator needs more.
func main() {
iter := laziter.New[int](true) // Persistence enabled
defer iter.Close()
go sampleValuesGenerator(iter.GetValuesProvider(), 5)
// Iterate over values once
for iter.Next() {
value, _ := iter.GetCurrentValue()
}
// Reset the iterator position
iter.ResetIteratorPosition()
// From now on, values are fetched from the iterator's persisted storage.
// sampleValuesGenerator() goroutine already exited.
// Iterate over values again
for iter.Next() {
value, _ := iter.GetCurrentValue()
}
}
func sampleValuesGenerator(vp *laziter.ValuesProvider[int], valuesCount int) {
// [...] (same as above)
}