// Package main implement redis test data injection package main import ( "context" "fmt" "log" "math/rand" "strconv" "time" "modelRT/orm" util "modelRT/deploy/redis-test-data/util" "github.com/redis/go-redis/v9" "gorm.io/driver/postgres" "gorm.io/gorm" ) const ( redisAddr = "localhost:6379" ) var globalRedisClient *redis.Client var ( highEnd, highStart, lowStart, lowEnd int totalLength int highSegmentLength int lowSegmentLength int ) func selectRandomInt() int { options := []int{0, 2} randomIndex := rand.Intn(len(options)) return options[randomIndex] } // generateMixedData define func to generate a set of floating-point data that meets specific conditions func generateMixedData(highMin, lowMin, highBase, lowBase, baseValue, normalBase float64) []float64 { totalLength = 500 highSegmentLength = 20 lowSegmentLength = 20 seed := time.Now().UnixNano() source := rand.NewSource(seed) r := rand.New(source) data := make([]float64, totalLength) highStart = rand.Intn(totalLength - highSegmentLength - lowSegmentLength - 1) highEnd = highStart + highSegmentLength lowStart = rand.Intn(totalLength-lowSegmentLength-highEnd) + highEnd lowEnd = lowStart + lowSegmentLength for i := 0; i < totalLength; i++ { if i >= highStart && i < highStart+highSegmentLength { // 数据值均大于 55.0,在 [55.5, 60.0] 范围内随机 // rand.Float64() 生成 [0.0, 1.0) 范围的浮点数 data[i] = highMin + r.Float64()*(highBase) } else if i >= lowStart && i < lowStart+lowSegmentLength { // 数据值均小于 45.0,在 [40.0, 44.5] 范围内随机 data[i] = lowMin + r.Float64()*(lowBase) } else { // 数据在 [45.0, 55.0] 范围内随机 (baseValue ± 5) // 50 + rand.Float64() * 10 - 5 change := normalBase - r.Float64()*normalBase*2 data[i] = baseValue + change } } return data } func main() { rootCtx := context.Background() pgURI := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s", "192.168.1.101", 5432, "postgres", "coslight", "demo") postgresDBClient, err := gorm.Open(postgres.Open(pgURI)) if err != nil { panic(err) } defer func() { sqlDB, err := postgresDBClient.DB() if err != nil { panic(err) } sqlDB.Close() }() cancelCtx, cancel := context.WithTimeout(rootCtx, 5*time.Second) defer cancel() var measurements []orm.Measurement result := postgresDBClient.WithContext(cancelCtx).Find(&measurements) if result.Error != nil { panic(result.Error) } log.Println("总共读取到测量点数量:", len(measurements)) measInfos := util.ProcessMeasurements(measurements) globalRedisClient = util.InitRedisClient(redisAddr) rCancelCtx, cancel := context.WithCancel(rootCtx) defer cancel() for key, measInfo := range measInfos { var highMin, highBase float64 var lowMin, lowBase float64 var normalBase float64 // TODO 生成一次测试数据 changes := measInfo.Changes baseValue := measInfo.BaseValue if len(changes) == 2 { highMin = baseValue + changes[0] lowMin = baseValue + changes[1] highBase = changes[0] lowBase = changes[1] normalBase = changes[0] } else { randomIndex := selectRandomInt() highMin = baseValue + changes[randomIndex] lowMin = baseValue + changes[randomIndex+1] highBase = changes[randomIndex] lowBase = changes[randomIndex+1] normalBase = changes[0] } datas := generateMixedData(highMin, lowMin, highBase, lowBase, baseValue, normalBase) // log.Printf("key:%s\n datas:%v\n", key, datas) allHigh := true for i := highStart; i < highEnd; i++ { if datas[i] <= highMin { allHigh = false break } } log.Printf("\n// 验证结果 (高值段在 %d-%d): 所有值是否 > %.2f? %t\n", highStart, highEnd-1, highMin, allHigh) allLow := true for i := lowStart; i < lowEnd; i++ { if datas[i] >= lowMin { allLow = false break } } log.Printf("// 验证结果 (低值段在 %d-%d): 所有值是否 < %.2f? %t\n", lowStart, lowEnd-1, lowMin, allLow) allTrue := true for i := 0; i < totalLength-1; i++ { value := datas[i] if i < highStart || (i >= highEnd && i < lowStart) || i >= lowEnd { log.Printf("index:%d, value:%.2f\n", i, value) if value >= highMin && value <= lowMin { allTrue = false } } } log.Printf("// 验证结果 (正常段在 %d-%d): 所有值是否 <= %.2f或>= %.2f %t\n", 0, totalLength-1, highMin, lowMin, allTrue) log.Printf("启动数据写入程序, Redis Key: %s, 基准值: %.4f, 变化范围: %+v\n", key, measInfo.BaseValue, measInfo.Changes) pipe := globalRedisClient.Pipeline() redisZs := make([]redis.Z, 0, totalLength) currentTime := time.Now().UnixNano() for i := range totalLength { sequentialTime := currentTime + int64(i) z := redis.Z{ Score: datas[i], Member: strconv.FormatInt(sequentialTime, 10), } redisZs = append(redisZs, z) } log.Printf("启动数据写入程序, Redis Key: %s, 写入数据量: %d\n", key, len(redisZs)) pipe.ZAdd(rCancelCtx, key, redisZs...) _, err = pipe.Exec(rCancelCtx) if err != nil { log.Printf("redis pipeline execution failed: %v\n", err) } } }