func (i *Index) Close() error {
	i.mu.Lock()
	defer i.mu.Unlock()
	for _, p := range i.partitions {
		if err := p.Close(); err != nil {
			return err
		}
	}
	i.opened = false
	return nil
}
Close closes the index.
package tsi1
import (
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"
	"runtime"
	"strconv"
	"sync"
	"sync/atomic"
	"github.com/cespare/xxhash"
	"github.com/influxdata/influxdb/models"
	"github.com/influxdata/influxdb/pkg/estimator"
	"github.com/influxdata/influxdb/pkg/estimator/hll"
	"github.com/influxdata/influxdb/pkg/slices"
	"github.com/influxdata/influxdb/tsdb"
	"github.com/influxdata/influxql"
	"go.uber.org/zap"
)
const IndexName = "tsi1"
var ErrCompactionInterrupted = errors.New("tsi1: compaction interrupted")
func init() {
	if os.Getenv("TSI_PARTITIONS") != "" {
		i, err := strconv.Atoi(os.Getenv("TSI_PARTITIONS"))
		if err != nil {
			panic(err)
		}
		DefaultPartitionN = uint64(i)
	}
	tsdb.RegisterIndex(IndexName, func(_ uint64, db, path string, _ *tsdb.SeriesIDSet, sfile *tsdb.SeriesFile, opt tsdb.EngineOptions) tsdb.Index {
		idx := NewIndex(sfile, db, WithPath(path), WithMaximumLogFileSize(int64(opt.Config.MaxIndexLogFileSize)))
		return idx
	})
}
var DefaultPartitionN uint64 = 8
type IndexOption func(i *Index)
var WithPath = func(path string) IndexOption {
	return func(i *Index) {
		i.path = path
	}
}
var DisableCompactions = func() IndexOption {
	return func(i *Index) {
		i.disableCompactions = true
	}
}
var WithLogger = func(l zap.Logger) IndexOption {
	return func(i *Index) {
		i.logger = l.With(zap.String("index", "tsi"))
	}
}
var WithMaximumLogFileSize = func(size int64) IndexOption {
	return func(i *Index) {
		i.maxLogFileSize = size
	}
}
type Index struct {
	mu         sync.RWMutex
	partitions []*Partition
	opened     bool
	path               string       
	disableCompactions bool         
	maxLogFileSize     int64        
	logger             *zap.Logger  
	sfile    *tsdb.SeriesFile  
	database string            
	version int
	PartitionN uint64
}
func NewIndex(sfile *tsdb.SeriesFile, database string, options ...IndexOption) *Index {
	idx := &Index{
		maxLogFileSize: tsdb.DefaultMaxIndexLogFileSize,
		logger:         zap.NewNop(),
		version:        Version,
		sfile:          sfile,
		database:       database,
		PartitionN:     DefaultPartitionN,
	}
	for _, option := range options {
		option(idx)
	}
	return idx
}
func (i *Index) Database() string {
	return i.database
}
func (i *Index) WithLogger(l *zap.Logger) {
	i.mu.Lock()
	defer i.mu.Unlock()
	i.logger = l.With(zap.String("index", "tsi"))
}
func (i *Index) Type() string { return IndexName }
func (i *Index) SeriesFile() *tsdb.SeriesFile { return i.sfile }
func (i *Index) SeriesIDSet() *tsdb.SeriesIDSet {
	seriesIDSet := tsdb.NewSeriesIDSet()
	others := make([]*tsdb.SeriesIDSet, 0, i.PartitionN)
	for _, p := range i.partitions {
		others = append(others, p.seriesIDSet)
	}
	seriesIDSet.Merge(others...)
	return seriesIDSet
}
func (i *Index) Open() error {
	i.mu.Lock()
	defer i.mu.Unlock()
	if i.opened {
		return errors.New("index already open")
	}
	if err := os.MkdirAll(i.path, 0777); err != nil {
		return err
	}
	i.partitions = make([]*Partition, i.PartitionN)
	for j := 0; j < len(i.partitions); j++ {
		p := NewPartition(i.sfile, filepath.Join(i.path, fmt.Sprint(j)))
		p.MaxLogFileSize = i.maxLogFileSize
		p.Database = i.database
		p.logger = i.logger.With(zap.String("tsi1_partition", fmt.Sprint(j+1)))
		i.partitions[j] = p
	}
	partitionN := len(i.partitions)
	n := i.availableThreads()
	errC := make(chan error, partitionN)
	var pidx uint32  
	for k := 0; k < n; k++ {
		go func(k int) {
			for {
				idx := int(atomic.AddUint32(&pidx, 1) - 1)  
				if idx >= partitionN {
					return  
				}
				err := i.partitions[idx].Open()
				errC <- err
			}
		}(k)
	}
	for i := 0; i < partitionN; i++ {
		if err := <-errC; err != nil {
			return err
		}
	}
	i.opened = true
	i.logger.Info(fmt.Sprintf("index opened with %d partitions", partitionN))
	return nil
}
func (i *Index) Compact() {
	i.mu.Lock()
	defer i.mu.Unlock()
	for _, p := range i.partitions {
		p.Compact()
	}
}
func (i *Index) EnableCompactions() {
	for _, p := range i.partitions {
		p.EnableCompactions()
	}
}
func (i *Index) DisableCompactions() {
	for _, p := range i.partitions {
		p.DisableCompactions()
	}
}
func (i *Index) Wait() {
	for _, p := range i.partitions {
		p.Wait()
	}
}