16e34a806e
Funciones genericas reutilizables: - RetryWithBackoff: reintento con backoff exponencial (impure) - Memoize: cache de funciones puras (pure) - Pipeline: composición T→T en secuencia (pure) - MapConcurrent: map paralelo con worker pool (impure) - Partition: divide slice en dos por predicado (pure) - Chunk: divide slice en trozos de tamaño N (pure) Todas con implementación real y documentación .md. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
44 lines
808 B
Go
44 lines
808 B
Go
package core
|
|
|
|
import "sync"
|
|
|
|
// MapConcurrent applies fn to each element of xs using a pool of worker goroutines.
|
|
// The number of concurrent workers is capped by the workers parameter.
|
|
// Results preserve the original index order. If workers <= 0, it defaults to 1.
|
|
func MapConcurrent[T any, U any](xs []T, fn func(T) U, workers int) []U {
|
|
if workers <= 0 {
|
|
workers = 1
|
|
}
|
|
n := len(xs)
|
|
if n == 0 {
|
|
return []U{}
|
|
}
|
|
|
|
results := make([]U, n)
|
|
var wg sync.WaitGroup
|
|
ch := make(chan int, n)
|
|
|
|
// Feed indices into the channel.
|
|
for i := range xs {
|
|
ch <- i
|
|
}
|
|
close(ch)
|
|
|
|
// Spawn workers.
|
|
if workers > n {
|
|
workers = n
|
|
}
|
|
wg.Add(workers)
|
|
for w := 0; w < workers; w++ {
|
|
go func() {
|
|
defer wg.Done()
|
|
for i := range ch {
|
|
results[i] = fn(xs[i])
|
|
}
|
|
}()
|
|
}
|
|
|
|
wg.Wait()
|
|
return results
|
|
}
|