// Package model define model struct of model runtime service package model import ( "context" "errors" "fmt" "modelRT/constants" "modelRT/diagram" "modelRT/logger" "modelRT/orm" "github.com/RediSearch/redisearch-go/v2/redisearch" ) // TraverseMeasurementGroupTables define func to traverse component measurement group tables func TraverseMeasurementGroupTables(ctx context.Context, measSet orm.MeasurementSet) (map[string]string, map[string]string, error) { rdb := diagram.GetRedisClientInstance() pipe := rdb.Pipeline() compTagToFullPath := make(map[string]string) isLocalCompTagToFullPath := make(map[string]string) zoneToGridPath := make(map[string]string) for gridTag, zoneTags := range measSet.GridToZoneTags { for _, zoneTag := range zoneTags { zoneToGridPath[zoneTag] = gridTag } } stationToZonePath := make(map[string]string) for zoneTag, stationTags := range measSet.ZoneToStationTags { gridTag := zoneToGridPath[zoneTag] for _, stationTag := range stationTags { stationToZonePath[stationTag] = fmt.Sprintf("%s.%s", gridTag, zoneTag) } } compNSPathToStationPath := make(map[string]string) for stationTag, nsPaths := range measSet.StationToCompNSPaths { zonePath := stationToZonePath[stationTag] for _, nsPath := range nsPaths { compNSPathToStationPath[nsPath] = fmt.Sprintf("%s.%s", zonePath, stationTag) } } compTagToNSPathPath := make(map[string]string) isLocalCompTagToNSPathPath := make(map[string]string) for nsPath, compTags := range measSet.CompNSPathToCompTags { stationPath := compNSPathToStationPath[nsPath] for _, compTag := range compTags { compTagToNSPathPath[compTag] = fmt.Sprintf("%s.%s", stationPath, nsPath) isLocalCompTagToNSPathPath[compTag] = nsPath } } // define a safe SAdd function to avoid errors caused by empty slices safeSAdd := func(key string, members []string) { if len(members) > 0 { pipe.SAdd(ctx, key, members) } } safeSAdd(constants.RedisAllGridSetKey, measSet.AllGridTags) gridSug := make([]redisearch.Suggestion, 0, len(measSet.AllGridTags)) for _, gridTag := range measSet.AllGridTags { gridSug = append(gridSug, redisearch.Suggestion{Term: gridTag, Score: constants.DefaultScore}) } ac.AddTerms(gridSug...) safeSAdd(constants.RedisAllZoneSetKey, measSet.AllZoneTags) safeSAdd(constants.RedisAllStationSetKey, measSet.AllStationTags) safeSAdd(constants.RedisAllCompNSPathSetKey, measSet.AllCompNSPaths) safeSAdd(constants.RedisAllCompTagSetKey, measSet.AllCompTags) safeSAdd(constants.RedisAllConfigSetKey, measSet.AllConfigTags) safeSAdd(constants.RedisAllMeasTagSetKey, measSet.AllMeasTags) // building the grid -> zones hierarchy for gridTag, zoneTags := range measSet.GridToZoneTags { sug := make([]redisearch.Suggestion, 0, len(zoneTags)) for _, zoneTag := range zoneTags { term := fmt.Sprintf("%s.%s", gridTag, zoneTag) // add redis fuzzy search suggestion for token1-token7 type sug = append(sug, redisearch.Suggestion{Term: term, Score: constants.DefaultScore}) } safeSAdd(fmt.Sprintf(constants.RedisSpecGridZoneSetKey, gridTag), zoneTags) ac.AddTerms(sug...) } // building the zone -> stations hierarchy for zoneTag, stationTags := range measSet.ZoneToStationTags { sug := make([]redisearch.Suggestion, 0, len(stationTags)) gridTag, exists := zoneToGridPath[zoneTag] if !exists { err := fmt.Errorf("zone tag to grid tag mapping not found for zoneTag: %s", zoneTag) logger.Error(ctx, "zone tag to grid tag mapping not found", "zoneTag", zoneTag, "error", err) return nil, nil, err } for _, stationTag := range stationTags { // add redis fuzzy search suggestion for token1-token7 type term := fmt.Sprintf("%s.%s.%s", gridTag, zoneTag, stationTag) sug = append(sug, redisearch.Suggestion{Term: term, Score: constants.DefaultScore}) } safeSAdd(fmt.Sprintf(constants.RedisSpecZoneStationSetKey, zoneTag), stationTags) ac.AddTerms(sug...) } // building the station -> component nspaths hierarchy for stationTag, compNSPaths := range measSet.StationToCompNSPaths { sug := make([]redisearch.Suggestion, 0, len(compNSPaths)*2) parentPath, exists := stationToZonePath[stationTag] if !exists { err := fmt.Errorf("station tag to zone tag mapping not found for stationTag: %s", stationTag) logger.Error(ctx, "zone tag to grid tag mapping not found", "stationTag", stationTag, "error", err) return nil, nil, err } for _, nsPath := range compNSPaths { // add redis fuzzy search suggestion for token1-token7 type term := fmt.Sprintf("%s.%s.%s", parentPath, stationTag, nsPath) sug = append(sug, redisearch.Suggestion{Term: term, Score: constants.DefaultScore}) // add redis fuzzy search suggestion for token4-token7 type sug = append(sug, redisearch.Suggestion{Term: nsPath, Score: constants.DefaultScore}) } safeSAdd(fmt.Sprintf(constants.RedisSpecStationCompNSPATHSetKey, stationTag), compNSPaths) ac.AddTerms(sug...) } // building the component nspath -> component tags hierarchy for compNSPath, compTags := range measSet.CompNSPathToCompTags { sug := make([]redisearch.Suggestion, 0, len(compTags)*2) parentPath, exists := compNSPathToStationPath[compNSPath] if !exists { err := fmt.Errorf("component nspath tag to station tag mapping not found for compNSPath: %s", compNSPath) logger.Error(ctx, "component nspath tag to station tag mapping not found", "compNSPath", compNSPath, "error", err) return nil, nil, err } for _, compTag := range compTags { fullPath := fmt.Sprintf("%s.%s.%s", parentPath, compNSPath, compTag) compTagToFullPath[compTag] = fullPath fullPath = fmt.Sprintf("%s.%s", compNSPath, compTag) isLocalCompTagToFullPath[compTag] = fullPath // add redis fuzzy search suggestion for token1-token7 type term := fullPath sug = append(sug, redisearch.Suggestion{Term: term, Score: constants.DefaultScore}) // add redis fuzzy search suggestion for token4-token7 type term = fmt.Sprintf("%s.%s", compNSPath, compTag) sug = append(sug, redisearch.Suggestion{Term: term, Score: constants.DefaultScore}) } safeSAdd(fmt.Sprintf(constants.RedisSpecCompNSPathCompTagSetKey, compNSPath), compTags) ac.AddTerms(sug...) } // building the component tag -> measurement tags hierarchy for compTag, measTags := range measSet.CompTagToMeasTags { sug := make([]redisearch.Suggestion, 0, len(measTags)*4) parentPath, exists := compTagToNSPathPath[compTag] if !exists { err := fmt.Errorf("component tag to component nspath mapping not found for compTag: %s", compTag) logger.Error(ctx, "component tag to component nspath mapping not found", "compTag", compTag, "error", err) return nil, nil, err } isLocalParentPath, exists := isLocalCompTagToNSPathPath[compTag] if !exists { err := fmt.Errorf("component tag to component nspath is local mapping not found for compTag: %s", compTag) logger.Error(ctx, "component tag to component nspath is local mapping not found", "compTag", compTag, "error", err) return nil, nil, err } for _, measTag := range measTags { // add redis fuzzy search suggestion for token1-token7 type configTerm := fmt.Sprintf("%s.%s.%s", parentPath, compTag, "bay") sug = append(sug, redisearch.Suggestion{Term: configTerm, Score: constants.DefaultScore}) measTerm := fmt.Sprintf("%s.%s.%s.%s", parentPath, compTag, "bay", measTag) sug = append(sug, redisearch.Suggestion{Term: measTerm, Score: constants.DefaultScore}) // add redis fuzzy search suggestion for token4-token7 type configTerm = fmt.Sprintf("%s.%s.%s", isLocalParentPath, compTag, "bay") sug = append(sug, redisearch.Suggestion{Term: configTerm, Score: constants.DefaultScore}) measTerm = fmt.Sprintf("%s.%s.%s.%s", isLocalParentPath, compTag, "bay", measTag) sug = append(sug, redisearch.Suggestion{Term: measTerm, Score: constants.DefaultScore}) } safeSAdd(fmt.Sprintf(constants.RedisSpecCompTagMeasSetKey, compTag), measTags) ac.AddTerms(sug...) } var allErrs []error cmders, execErr := pipe.Exec(ctx) if execErr != nil { logger.Error(ctx, "pipeline execution failed", "error", execErr) allErrs = append(allErrs, execErr) } // check for errors in each subcommand of the pipeline for _, cmder := range cmders { cmdErr := cmder.Err() if cmdErr != nil { logger.Error(ctx, "individual redis command failed", "command", cmder.Name(), "args", cmder.Args(), "error", cmdErr) allErrs = append(allErrs, cmdErr) } } if len(allErrs) > 0 { return nil, nil, errors.Join(allErrs...) } return compTagToFullPath, isLocalCompTagToFullPath, nil }