// Copyright 2022 PingCAP, Inc. Licensed under Apache-2.0. package iter import ( "context" "github.com/pingcap/tidb/br/pkg/utils" ) // TransformConfig is the config for the combinator "transform". type TransformConfig func(*chunkMappingCfg) func WithConcurrency(n uint) TransformConfig { return func(c *chunkMappingCfg) { c.quota = utils.NewWorkerPool(n, "transforming") } } func WithChunkSize(n uint) TransformConfig { return func(c *chunkMappingCfg) { c.chunkSize = n } } // Transform returns an iterator that performs an impure procedure for each element, // then emitting the result of that procedure. // The execution of that procedure can be paralleled with the config `WithConcurrency`. // You may also need to config the `WithChunkSize`, because the concurrent execution is only available intra-batch. func Transform[T, R any](it TryNextor[T], with func(context.Context, T) (R, error), cs ...TransformConfig) TryNextor[R] { r := &chunkMapping[T, R]{ inner: it, mapper: with, chunkMappingCfg: chunkMappingCfg{ chunkSize: 1, }, } for _, c := range cs { c(&r.chunkMappingCfg) } if r.quota == nil { r.quota = utils.NewWorkerPool(r.chunkSize, "max-concurrency") } if r.quota.Limit() > int(r.chunkSize) { r.chunkSize = uint(r.quota.Limit()) } return r } // FilterOut returns an iterator that yields all elements the original iterator // generated and DOESN'T satisfies the predicate. func FilterOut[T any](it TryNextor[T], f func(T) bool) TryNextor[T] { return filter[T]{ inner: it, filterOutIf: f, } } // TakeFirst takes the first n elements of the iterator. func TakeFirst[T any](inner TryNextor[T], n uint) TryNextor[T] { return &take[T]{ n: n, inner: inner, } } // FlapMap applies the mapper over every elements the origin iterator generates, // then flatten them. func FlatMap[T, R any](it TryNextor[T], mapper func(T) TryNextor[R]) TryNextor[R] { return &join[R]{ inner: pureMap[T, TryNextor[R]]{ inner: it, mapper: mapper, }, current: empty[R]{}, } } // Map applies the mapper over every elements the origin iterator yields. func Map[T, R any](it TryNextor[T], mapper func(T) R) TryNextor[R] { return pureMap[T, R]{ inner: it, mapper: mapper, } } // ConcatAll concatenates all elements yields by the iterators. // In another word, it 'chains' all the input iterators. func ConcatAll[T any](items ...TryNextor[T]) TryNextor[T] { return &join[T]{ inner: FromSlice(items), current: empty[T]{}, } }