+ if true {
+ // low memory mode
+ for _, seqname := range seqnames {
+ log.Infof("assembling %q", seqname)
+ cmd.exportSeq(out, bedout, tilelib.taglib.keylen, seqname, refseq[seqname], tileVariant, cgs)
+ log.Infof("assembled %q", seqname)
+ }
+ return nil
+ }
+
+ outbuf := make([]bytes.Buffer, len(seqnames))
+ bedbuf := make([]bytes.Buffer, len(seqnames))
+ ready := make([]chan struct{}, len(seqnames))
+ for i := range ready {
+ ready[i] = make(chan struct{})
+ }
+
+ var output sync.WaitGroup
+ output.Add(1)
+ go func() {
+ defer output.Done()
+ for i, seqname := range seqnames {
+ <-ready[i]
+ log.Infof("writing outbuf %s", seqname)
+ io.Copy(out, &outbuf[i])
+ log.Infof("writing outbuf %s done", seqname)
+ }
+ }()
+ output.Add(1)
+ go func() {
+ defer output.Done()
+ if bedout != nil {
+ for i, seqname := range seqnames {
+ <-ready[i]
+ log.Infof("writing bedbuf %s", seqname)
+ io.Copy(bedout, &bedbuf[i])
+ log.Infof("writing bedbuf %s done", seqname)
+ }
+ }
+ }()
+
+ throttle := throttle{Max: 8}
+ log.Infof("assembling %d sequences in %d goroutines", len(seqnames), throttle.Max)
+ for seqidx, seqname := range seqnames {
+ seqidx, seqname := seqidx, seqname
+ outbuf := &outbuf[seqidx]
+ bedbuf := &bedbuf[seqidx]
+ if bedout == nil {
+ bedbuf = nil
+ }
+ throttle.Acquire()
+ go func() {
+ defer throttle.Release()
+ defer close(ready[seqidx])
+ cmd.exportSeq(outbuf, bedbuf, tilelib.taglib.keylen, seqname, refseq[seqname], tileVariant, cgs)
+ log.Infof("assembled %q to outbuf %d bedbuf %d", seqname, outbuf.Len(), bedbuf.Len())
+ }()
+ }
+
+ output.Wait()
+ return nil
+}
+
+// Align genome tiles to reference tiles, write diffs to outw, and (if
+// bedw is not nil) write tile coverage to bedw.
+func (cmd *exporter) exportSeq(outw, bedw io.Writer, taglen int, seqname string, reftiles []tileLibRef, tileVariant map[tileLibRef]TileVariant, cgs []CompactGenome) {