https://github.com/valsov/laziter
Lazy loading iterator
https://github.com/valsov/laziter
Last synced: about 1 year ago
JSON representation
Lazy loading iterator
- Host: GitHub
- URL: https://github.com/valsov/laziter
- Owner: valsov
- Created: 2023-09-23T12:50:39.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2023-10-15T06:53:14.000Z (over 2 years ago)
- Last Synced: 2025-01-26T05:41:35.338Z (about 1 year ago)
- Language: Go
- Homepage:
- Size: 10.7 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Laziter
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.
## Example
### Base use
```go
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
}
}
```
### Partial iteration
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.
```go
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)
}
```
### Values persistence
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.
```go
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)
}
```