slices.go

 1package csync
 2
 3import (
 4	"iter"
 5	"sync"
 6)
 7
 8// LazySlice is a thread-safe lazy-loaded slice.
 9type LazySlice[K any] struct {
10	inner []K
11	mu    sync.Mutex
12}
13
14// NewLazySlice creates a new slice and runs the [load] function in a goroutine
15// to populate it.
16func NewLazySlice[K any](load func() []K) *LazySlice[K] {
17	s := &LazySlice[K]{}
18	s.mu.Lock()
19	go func() {
20		s.inner = load()
21		s.mu.Unlock()
22	}()
23	return s
24}
25
26// Seq returns an iterator that yields elements from the slice.
27func (s *LazySlice[K]) Seq() iter.Seq[K] {
28	s.mu.Lock()
29	inner := s.inner
30	s.mu.Unlock()
31	return func(yield func(K) bool) {
32		for _, v := range inner {
33			if !yield(v) {
34				return
35			}
36		}
37	}
38}