An open API service indexing awesome lists of open source software.

https://github.com/valsov/laziter

Lazy loading iterator
https://github.com/valsov/laziter

Last synced: about 1 year ago
JSON representation

Lazy loading iterator

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)
}
```