package tsdb import ( "errors" "fmt" "io" "os" "regexp" "sort" "time" "github.com/influxdata/influxdb/influxql" "github.com/influxdata/influxdb/models" "github.com/influxdata/influxdb/pkg/estimator" "go.uber.org/zap" ) var ( // ErrFormatNotFound is returned when no format can be determined from a path. ErrFormatNotFound = errors.New("format not found") // ErrUnknownEngineFormat is returned when the engine format is // unknown. ErrUnknownEngineFormat is currently returned if a format // other than tsm1 is encountered. ErrUnknownEngineFormat = errors.New("unknown engine format") ) // Engine represents a swappable storage engine for the shard. type Engine interface { Open() error Close() error SetEnabled(enabled bool) WithLogger(zap.Logger) LoadMetadataIndex(shardID uint64, index Index) error CreateSnapshot() (string, error) Backup(w io.Writer, basePath string, since time.Time) error Restore(r io.Reader, basePath string) error CreateIterator(opt influxql.IteratorOptions) (influxql.Iterator, error) WritePoints(points []models.Point) error CreateSeriesIfNotExists(name []byte, tags models.Tags) error DeleteSeriesRange(keys [][]byte, min, max int64) error SeriesN() (uint64, error) SeriesSketches() (estimator.Sketch, estimator.Sketch, error) MeasurementsSketches() (estimator.Sketch, estimator.Sketch, error) DeleteMeasurement(name []byte) error Measurement(name []byte) (*Measurement, error) Measurements() (Measurements, error) MeasurementsByExpr(expr influxql.Expr) (Measurements, bool, error) MeasurementNamesByRegex(re *regexp.Regexp) ([][]byte, error) MeasurementFields(measurement string) *MeasurementFields // Statistics will return statistics relevant to this engine. Statistics(tags map[string]string) []models.Statistic LastModified() time.Time io.WriterTo } // EngineFormat represents the format for an engine. type EngineFormat int const ( // TSM1Format is the format used by the tsm1 engine. TSM1Format EngineFormat = 2 ) // NewEngineFunc creates a new engine. type NewEngineFunc func(id uint64, i Index, path string, walPath string, options EngineOptions) Engine // newEngineFuncs is a lookup of engine constructors by name. var newEngineFuncs = make(map[string]NewEngineFunc) // RegisterEngine registers a storage engine initializer by name. func RegisterEngine(name string, fn NewEngineFunc) { if _, ok := newEngineFuncs[name]; ok { panic("engine already registered: " + name) } newEngineFuncs[name] = fn } // RegisteredEngines returns the slice of currently registered engines. func RegisteredEngines() []string { a := make([]string, 0, len(newEngineFuncs)) for k := range newEngineFuncs { a = append(a, k) } sort.Strings(a) return a } // NewEngine returns an instance of an engine based on its format. // If the path does not exist then the DefaultFormat is used. func NewEngine(id uint64, i Index, path string, walPath string, options EngineOptions) (Engine, error) { // Create a new engine if _, err := os.Stat(path); os.IsNotExist(err) { return newEngineFuncs[options.EngineVersion](id, i, path, walPath, options), nil } // If it's a dir then it's a tsm1 engine format := DefaultEngine if fi, err := os.Stat(path); err != nil { return nil, err } else if !fi.Mode().IsDir() { return nil, ErrUnknownEngineFormat } else { format = "tsm1" } // Lookup engine by format. fn := newEngineFuncs[format] if fn == nil { return nil, fmt.Errorf("invalid engine format: %q", format) } return fn(id, i, path, walPath, options), nil } // EngineOptions represents the options used to initialize the engine. type EngineOptions struct { EngineVersion string IndexVersion string ShardID uint64 InmemIndex interface{} // shared in-memory index Config Config } // NewEngineOptions returns the default options. func NewEngineOptions() EngineOptions { return EngineOptions{ EngineVersion: DefaultEngine, IndexVersion: DefaultIndex, Config: NewConfig(), } }