// Map routines to iterate a function over an array, potentially splitting the array slice into // chunks so that each chunk is processed concurrently. When using concurrent processing the // Chunk size is either the nearest even division of the total array over the chosen concurrent // processing goroutines or a specified maximum chunk size, whichever is smaller. Reducing // chunk size can reduce the impact of divergence in time for processing chunks, but may add // to overhead. func Map(set Mapper, threads, maxChunkSize int) (results []interface{}, err error) { queue := make(chan Operator, 1) p := NewProcessor(queue, 0, threads) defer p.Stop() chunkSize := util.Min(int(math.Ceil(float64(set.Len())/float64(threads))), maxChunkSize) quit := make(chan struct{}) go func() { for s := 0; s*chunkSize < set.Len(); s++ { select { case <-quit: break default: endChunk := util.Min(chunkSize*(s+1), set.Len()) queue <- set.Slice(chunkSize*s, endChunk) } } }() for r := 0; r*chunkSize < set.Len(); r++ { result := <-p.out if result.Err != nil { err = fmt.Errorf("concurrent: map failed: %v", err) close(quit) break } results = append(results, result.Value) } return }
// Pack a sequence into the Packed sequence. Returns a string giving diagnostic information. func (pa *Packer) Pack(seq *linear.Seq) (string, error) { if pa.packed.Alpha == nil { pa.packed.Alpha = seq.Alpha } else if pa.packed.Alpha != seq.Alpha { return "", errors.New("pals: alphabet mismatch") } c := contig{Seq: seq} padding := binSize - seq.Len()%binSize if padding < minPadding { padding += binSize } pa.length += pa.lastPad c.from = pa.length pa.length += seq.Len() pa.lastPad = padding m := &pa.packed.seqMap bins := make([]int, (padding+seq.Len())/binSize) for i := 0; i < len(bins); i++ { bins[i] = len(m.contigs) } m.binMap = append(m.binMap, bins...) m.contigs = append(m.contigs, c) return fmt.Sprintf("%20s\t%10d\t%7d-%-d", seq.ID[:util.Min(20, len(seq.ID))], seq.Len(), len(m.binMap)-len(bins), len(m.binMap)-1), nil }