func (b *BAMProvider) FileInfo() (FileInfo, error) {
	b.initInfo()
	if err := b.err.Err(); err != nil {
		return FileInfo{}, err
	}
	return b.info, nil
}
FileInfo implements the Provider interface.
package bamprovider
import (
	"fmt"
	"io"
	"strings"
	"sync"
	"github.com/grailbio/base/errors"
	"github.com/grailbio/base/file"
	"github.com/grailbio/base/vcontext"
	"github.com/grailbio/bio/biopb"
	gbam "github.com/grailbio/bio/encoding/bam"
	"github.com/grailbio/hts/bam"
	"github.com/grailbio/hts/bgzf"
	"github.com/grailbio/hts/bgzf/index"
	"github.com/grailbio/hts/sam"
	"v.io/x/lib/vlog"
)
const (
	DefaultBytesPerShard = int64(128 << 20)
	DefaultMinBasesPerShard = 10000
)
type BAMProvider struct {
	Path string
	Index string
	err   errors.Once
	mu        sync.Mutex
	nActive   int
	freeIters []*bamIterator
	indexOnce sync.Once
	bindex    *bam.Index
	gindex    *gbam.GIndex
	infoOnce sync.Once
	header   *sam.Header
	info     FileInfo
}
type bamIterator struct {
	provider *BAMProvider
	in       file.File
	reader   *bam.Reader
	firstRecord bgzf.Offset
	startAddr, limitAddr biopb.Coord
	active bool
	err    error
	next   *sam.Record
	done   bool
}
func (b *BAMProvider) indexPath() string {
	index := b.Index
	if index == "" {
		index = b.Path + ".bai"
	}
	return index
}
func (b *BAMProvider) readIndex() error {
	b.indexOnce.Do(func() {
		ctx := vcontext.Background()
		in, err := file.Open(ctx, b.indexPath())
		if err != nil {
			b.err.Set(err)
			return
		}
		var bindex *bam.Index
		var gindex *gbam.GIndex
		if strings.HasSuffix(b.indexPath(), ".gbai") {
			gindex, err = gbam.ReadGIndex(in.Reader(ctx))
		} else {
			bindex, err = bam.ReadIndex(in.Reader(ctx))
		}
		if err != nil {
			b.err.Set(err)
			return
		}
		if err = in.Close(ctx); err != nil {
			b.err.Set(err)
			return
		}
		b.bindex = bindex
		b.gindex = gindex
	})
	return b.err.Err()
}