func (s *BaseSimulator) Next(p *data.Point) bool {
	if s.generatorIndex == uint64(len(s.generators)) {
		s.generatorIndex = 0
		s.simulatedMeasurementIndex++
	}
	if s.simulatedMeasurementIndex == len(s.generators[0].Measurements()) {
		s.simulatedMeasurementIndex = 0
		for i := 0; i < len(s.generators); i++ {
			s.generators[i].TickAll(s.interval)
		}
		s.adjustNumHostsForEpoch()
	}
	generator := s.generators[s.generatorIndex]
	for _, tag := range generator.Tags() {
		p.AppendTag(tag.Key, tag.Value)
	}
	generator.Measurements()[s.simulatedMeasurementIndex].ToPoint(p)
	ret := s.generatorIndex < s.epochGenerators
	s.madePoints++
	s.generatorIndex++
	return ret
}
Next advances a Point to the next state in the generator.
package common
import (
	"github.com/timescale/tsbs/pkg/data"
	"reflect"
	"time"
)
type SimulatorConfig interface {
	NewSimulator(time.Duration, uint64) Simulator
}
type BaseSimulatorConfig struct {
	Start time.Time
	End time.Time
	InitGeneratorScale uint64
	GeneratorScale uint64
	GeneratorConstructor func(i int, start time.Time) Generator
}
func calculateEpochs(duration time.Duration, interval time.Duration) uint64 {
	return uint64(duration.Nanoseconds() / interval.Nanoseconds())
}
func (sc *BaseSimulatorConfig) NewSimulator(interval time.Duration, limit uint64) Simulator {
	generators := make([]Generator, sc.GeneratorScale)
	for i := 0; i < len(generators); i++ {
		generators[i] = sc.GeneratorConstructor(i, sc.Start)
	}
	epochs := calculateEpochs(sc.End.Sub(sc.Start), interval)
	maxPoints := epochs * sc.GeneratorScale * uint64(len(generators[0].Measurements()))
	if limit > 0 && limit < maxPoints {
		maxPoints = limit
	}
	sim := &BaseSimulator{
		madePoints: 0,
		maxPoints:  maxPoints,
		generatorIndex: 0,
		generators:     generators,
		epoch:           0,
		epochs:          epochs,
		epochGenerators: sc.InitGeneratorScale,
		initGenerators:  sc.InitGeneratorScale,
		timestampStart:  sc.Start,
		timestampEnd:    sc.End,
		interval:        interval,
		simulatedMeasurementIndex: 0,
	}
	return sim
}
type GeneratedDataHeaders struct {
	TagTypes  []string
	TagKeys   []string
	FieldKeys map[string][]string
}
type Simulator interface {
	Finished() bool
	Next(*data.Point) bool
	Fields() map[string][]string
	TagKeys() []string
	TagTypes() []string
	Headers() *GeneratedDataHeaders
}
type BaseSimulator struct {
	madePoints uint64
	maxPoints  uint64
	generatorIndex uint64
	generators     []Generator
	epoch           uint64
	epochs          uint64
	epochGenerators uint64
	initGenerators  uint64
	timestampStart time.Time
	timestampEnd   time.Time
	interval       time.Duration
	simulatedMeasurementIndex int
}
func (s *BaseSimulator) Finished() bool {
	return s.madePoints >= s.maxPoints
}