it

package module
v0.0.0-...-668503c Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 1, 2025 License: MIT Imports: 9 Imported by: 0

README

it - Buffered Iterator Utility for Go

The it package provides a powerful and flexible iterator for Go, enabling buffered iteration over any iter.Seq[T] sequence with advanced features like peeking, seeking, rewinding, and configurable buffer management. It supports various data sources (slices, channels, maps, and IO readers) and is optimized for performance and memory efficiency.

Features

  • Buffered Iteration: Store elements for efficient navigation and rewinding.
  • Peek Ahead: Inspect the next element without advancing the iterator.
  • Relative and Absolute Navigation: Use Seek to move relative positions or SeekTo for absolute positions.
  • Rewind Capability: Reset to the initial state while preserving the buffer.
  • Configurable Buffer Limits: Set initial and maximum buffer sizes for memory control.
  • Multiple Source Adapters: Iterate over slices, channels, map keys/values, and IO streams (lines, bytes, runes).
  • Context Support: Integrate cancellation for IO operations.
  • Efficient Memory Management: Minimal allocations with optimized buffer growth.
  • Transform Functions: Apply transformations during iteration or dumping.

Installation

go get github.com/olekukonko/it

Quick Start

Here’s a simple example using a Fibonacci sequence to demonstrate the it package’s core features:

package main

import (
	"fmt"
	"github.com/olekukonko/it"
	"iter"
)

// Fibonacci generator
func fibonacci() iter.Seq[int] {
	return func(yield func(int) bool) {
		a, b := 0, 1
		for {
			if !yield(a) {
				return
			}
			a, b = b, a+b
		}
	}
}

func main() {
	// Create iterator from Fibonacci sequence
	it, err := it.Wrap(fibonacci())
	if err != nil {
		fmt.Println("Error:", err)
		return
	}

	// Iterate over first 5 numbers
	for i := 0; i < 5; i++ {
		v, ok := it.Next()
		if !ok {
			break
		}
		fmt.Printf("Fibonacci[%d]: %d\n", i, v)
	}

	// Peek at the next number
	if v, ok := it.Peek(); ok {
		fmt.Println("Next Fibonacci:", v)
	}

	// Rewind and iterate again
	it.Rewind()
	for i := 0; i < 3; i++ {
		v, ok := it.Next()
		if !ok {
			break
		}
		fmt.Printf("Rewound Fibonacci[%d]: %d\n", i, v)
	}
}

Output:

Fibonacci[0]: 0
Fibonacci[1]: 1
Fibonacci[2]: 1
Fibonacci[3]: 2
Fibonacci[4]: 3
Next Fibonacci: 5
Rewound Fibonacci[0]: 0
Rewound Fibonacci[1]: 1
Rewound Fibonacci[2]: 1

Key Features and Examples

Buffered Iteration

Create an iterator from a slice and navigate through elements:

it, err := it.Slice([]string{"a", "b", "c"})
if err != nil {
	fmt.Println("Error:", err)
	return
}
for v, ok := it.Next(); ok; v, ok = it.Next() {
	fmt.Println(v)
}
Seeking and Navigation

Move relative to the current position with Seek or to an absolute position with SeekTo:

it, err := it.Slice([]string{"a", "b", "c", "d"})
if err != nil {
	fmt.Println("Error:", err)
	return
}
it.Next() // Move to "a"
if v, ok := it.Seek(1); ok { // Skip 1 element, move to "c"
	fmt.Println("After Seek(1):", v) // Output: c
}
if v, ok := it.SeekTo(1); ok { // Move to position 1 ("b")
	fmt.Println("After SeekTo(1):", v) // Output: b
}
IO Operations

Read lines, bytes, or runes from an IO source with configurable buffer sizes:

import "strings"

reader := strings.NewReader("line 1\nline 2\nline 3")
cfg := it.Config().BufferSize(1024).MaxLineLength(8192)
lines, err := cfg.Lines(reader)
if err != nil {
	fmt.Println("Error:", err)
	return
}
for line, ok := lines.Next(); ok; line, ok = lines.Next() {
	fmt.Println(line)
}
Transform Functions

Apply transformations when dumping all elements:

it, err := it.Slice([]int{1, 2, 3})
if err != nil {
	fmt.Println("Error:", err)
	return
}
doubled, err := it.Dump(func(n int) int { return n * 2 })
if err != nil {
	fmt.Println("Error:", err)
	return
}
fmt.Println(doubled) // Output: [2 4 6]

API Reference

Core Methods
  • Next() (T, bool): Advances to the next element, returning its value and whether it exists.
  • Peek() (T, bool): Returns the next element without advancing.
  • Seek(n int) (T, bool): Moves n elements forward (or backward if negative), returning the element at the new position.
  • SeekTo(pos int) (T, bool): Jumps to the absolute position pos.
  • Rewind(): Resets the iterator to the initial state.
  • Buffer() []T: Returns a copy of buffered elements.
  • Dump(...func(T) T) ([]T, error): Consumes the iterator and returns all elements, optionally applying transformations.
  • Position() int: Returns the current position.
  • BufferedLen() int: Returns the number of buffered elements.
  • Cap() int: Returns the current buffer capacity.
Factory Functions
  • New[T](src Seq[T], initialCap, maxCap int) (*Iter[T], error): Creates an iterator with custom buffer settings.
  • Wrap[T](src Seq[T]) (*Iter[T], error): Creates an iterator with default settings (initialCap=64, maxCap=0).
  • Must[T](src Seq[T]) *Iter[T]: Creates an iterator or panics on error.
  • Slice[T](s []T) (*Iter[T], error): Creates an iterator from a slice.
  • Chan[T](c *C, ch <-chan T) (*Iter[T], error): Creates an iterator from a channel.
  • Keys[K, V](m map[K]V) (*Iter[K], error): Creates an iterator over map keys.
  • Vals[K, V](m map[K]V) (*Iter[V], error): Creates an iterator over map values.
  • Pairs[K, V](m map[K]V) (*Iter[Pair[K, V]], error): Creates an iterator over map key-value pairs.
  • Tea(sources ...io.Reader) (*Iter[string], error): Creates an iterator over lines from multiple readers.
  • C.Lines(r io.Reader) (*Iter[string], error): Creates an iterator over lines from a reader.
  • C.Bytes(r io.Reader) (*Iter[[]byte], error): Creates an iterator over byte chunks.
  • C.Runes(r io.Reader) (*Iter[rune], error): Creates an iterator over runes.
Configuration

Customize iterator behavior with the Config builder:

cfg := it.Config().
	InitialCap(128).           // Initial buffer capacity
	MaxCap(1024).              // Maximum buffer capacity
	BufferSize(8192).          // IO buffer size
	MaxLineLength(128 * 1024). // Maximum line length
	WithContext(ctx)           // Context for cancellation

it, err := cfg.Lines(reader)

Testing and Reliability

The it package is thoroughly tested to ensure reliability across various use cases, including:

  • Basic iteration (TestNext, TestSeq)
  • Peeking and seeking (TestPeek, TestSeek, TestSeekTo)
  • Buffer management (TestBuffer)
  • IO operations (TestLines, TestBytes, TestRunes)
  • Edge cases (TestEmptyIterator, TestSingleElement)

Run the tests to verify:

go test -v

Performance

  • Minimal Allocations: Optimized buffer growth reduces memory overhead.
  • Configurable Limits: Set maxCap to control memory usage.
  • Efficient Navigation: Buffered elements enable fast seeking and rewinding.
  • Concurrent Safety: Channel-based iteration ensures safe sequence consumption.

Contributing

Contributions are welcome! Please submit issues or pull requests to the GitHub repository: github.com/olekukonko/it.

License

MIT License

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type C

type C struct {
	// contains filtered or unexported fields
}

C provides a builder for advanced iterator configuration.

func Config

func Config() *C

Config starts a configuration builder for customized iterator creation. Defaults: InitialCap=64, MaxCap=0 (unlimited), BufferSize=4KB, MaxLineLength=64KB.

func (*C) BufferSize

func (c *C) BufferSize(n int) *C

BufferSize sets the buffer size for Bytes (default 4KB).

func (*C) Bytes

func (c *C) Bytes(r io.Reader) (*Iter[[]byte], error)

Bytes creates an Iter from io.Reader (chunks) with configuration. Returns an error for nil readers or read errors (except io.EOF).

func (*C) InitialCap

func (c *C) InitialCap(n int) *C

InitialCap sets the initial buffer capacity (default 64).

func (*C) Lines

func (c *C) Lines(r io.Reader) (*Iter[string], error)

Lines creates an Iter from io.Reader (line by line) with configuration. Returns an error for nil readers or scanning errors.

func (*C) MaxCap

func (c *C) MaxCap(n int) *C

MaxCap sets the maximum buffer capacity (default 0, unlimited).

func (*C) MaxLineLength

func (c *C) MaxLineLength(n int) *C

MaxLineLength sets the maximum line length for Lines (default 64KB).

func (*C) Runes

func (c *C) Runes(r io.Reader) (*Iter[rune], error)

Runes creates an Iter from io.Reader (runes) with configuration. Handles UTF-8 decoding, yielding unicode.ReplacementChar for invalid sequences. Returns an error for nil readers or read errors (except io.EOF).

func (*C) WithContext

func (c *C) WithContext(ctx context.Context) *C

WithContext sets the context for operations (default context.Background()).

type Iter

type Iter[T any] struct {
	// contains filtered or unexported fields
}

Iter provides buffered iteration over any iter.Seq[T] with: - Peek ahead without consumption - Relative (Seek) and absolute (SeekTo) navigation - Rewind capabilities - Configurable buffer limits

func Chan

func Chan[T any](c *C, ch <-chan T) (*Iter[T], error)

Chan creates an Iter from a channel with configuration and context. Returns an error for nil channels or context cancellation.

func Keys

func Keys[K comparable, V any](m map[K]V) (*Iter[K], error)

Keys creates an Iter from map keys. Order is random (Go map iteration order). Returns an error for nil maps.

func Must

func Must[T any](src iter.Seq[T]) *Iter[T]

Must creates an Iter, panicking on error.

func New

func New[T any](src iter.Seq[T], initialCap, maxCap int) (*Iter[T], error)

New creates an Iter with configurable buffer behavior. initialCap defaults to 64 if <= 0; maxCap of 0 means unlimited. Returns an error if the source sequence is nil.

func Pairs

func Pairs[K comparable, V any](m map[K]V) (*Iter[Pair[K, V]], error)

Pairs creates an Iter from map entries. Order is random (Go map iteration order). Returns an error for nil maps.

func Slice

func Slice[T any](s []T) (*Iter[T], error)

Slice creates an Iter from []T. Preserves order and buffers all elements. Returns an error for nil slices.

func Tea

func Tea(sources ...io.Reader) (*Iter[string], error)

Tea creates an Iter yielding lines from multiple io.Reader sources sequentially. Uses configuration from Config() with 64KB max line length. Returns an error for nil readers or if any reader is nil.

func Vals

func Vals[K comparable, V any](m map[K]V) (*Iter[V], error)

Vals creates an Iter from map values. Order is random (Go map iteration order). Returns an error for nil maps.

func Wrap

func Wrap[T any](src iter.Seq[T]) (*Iter[T], error)

Wrap creates an Iter with defaults (initialCap=64, maxCap=0).

func (*Iter[T]) Buffer

func (it *Iter[T]) Buffer() []T

Buffer returns a copy of all buffered elements.

func (*Iter[T]) BufferedLen

func (it *Iter[T]) BufferedLen() int

BufferedLen returns number of elements available for rewinding.

func (*Iter[T]) Cap

func (it *Iter[T]) Cap() int

Cap returns current buffer capacity.

func (*Iter[T]) Current

func (it *Iter[T]) Current() (T, bool)

Current returns the element at current position.

func (*Iter[T]) Dump

func (it *Iter[T]) Dump(fs ...func(value T) T) ([]T, error)

Dump consumes the iterator and returns all elements as a slice. Similar to io.ReadAll, it includes buffered and remaining source elements.

func (*Iter[T]) Next

func (it *Iter[T]) Next() (T, bool)

Next advances to the next element, growing buffer if needed.

func (*Iter[T]) Peek

func (it *Iter[T]) Peek() (T, bool)

Peek returns the next element without advancing.

func (*Iter[T]) Position

func (it *Iter[T]) Position() int

Position returns current index (-1 = before start).

func (*Iter[T]) Rewind

func (it *Iter[T]) Rewind()

Rewind resets to initial state while preserving buffer.

func (*Iter[T]) Seek

func (it *Iter[T]) Seek(n int) (T, bool)

Seek moves n positions relative to current location, treating n as the number of elements to skip.

func (*Iter[T]) SeekTo

func (it *Iter[T]) SeekTo(pos int) (T, bool)

SeekTo jumps to absolute position.

func (*Iter[T]) Seq

func (it *Iter[T]) Seq() iter.Seq[T]

Seq returns the iterator as iter.Seq[T] for range loops.

type Pair

type Pair[K, V any] struct {
	Key   K
	Value V
}

Pair represents a key-value pair for map entry iterators.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL