package crontab import ( "errors" "strconv" "strings" "474420502.top/eson/structure/priority_list" randomdata "github.com/Pallinder/go-randomdata" ) type randLR struct { left, right int } // NodeCount 用于priority_list type NodeCount struct { plist.Node randLR } type hInterval struct { PlanFailCount plist.PriorityList PlanTrueCount plist.PriorityList PlanFail []randLR PlanTrue []randLR Count int ConstCount int } func (interval *hInterval) reset() { interval.Count = interval.ConstCount } // Compare NodeCount比较函数 func (rlr *NodeCount) Compare(v plist.INode) bool { return rlr.GetValue().(int) > v.GetValue().(int) } func parseIntervalFail(interval *hInterval, FN string) { scharIndex := strings.Index(FN, ">") if scharIndex != -1 { if FN[scharIndex+1] != '=' { panic(errors.New("= is not exist")) } fc := FN[0:scharIndex] flr := FN[scharIndex+2:] node := new(NodeCount) node.SetValue(getInt(fc[1:])) node.randLR = parseRandLR(flr) interval.PlanFailCount.Insert(node) } else { if FN[1] != '=' { panic(errors.New("= is not exist")) } fvalue := FN[2:] interval.PlanFail = append(interval.PlanFail, parseRandLR(fvalue)) } } func parseIntervalSuccess(interval *hInterval, FN string) { scharIndex := strings.Index(FN, ">") if scharIndex != -1 { if FN[scharIndex+1] != '=' { panic(errors.New("= is not exist")) } tc := FN[0:scharIndex] tlr := FN[scharIndex+2:] node := new(NodeCount) node.SetValue(getInt(tc[1:])) node.randLR = parseRandLR(tlr) interval.PlanTrueCount.Insert(node) } else { if FN[1] != '=' { panic(errors.New("= is not exist")) } tvalue := FN[2:] interval.PlanTrue = append(interval.PlanTrue, parseRandLR(tvalue)) } } func parseIntervalString(crontab string) []interface{} { var result []interface{} values := strings.Split(crontab, ",") for _, value := range values { interval := &hInterval{} // 次数 valuesCounts := strings.Split(value, "x") switch len(valuesCounts) { case 1: interval.ConstCount = 1 case 2: count, err := strconv.Atoi(valuesCounts[1]) if err != nil { panic(err) } interval.ConstCount = count default: panic("valuesCounts error, the len is not in range") } // 统计失败与普通间隔值的数组 failAndNormal := valuesCounts[0] valuesFN := strings.Split(failAndNormal, "|") for _, FN := range valuesFN { if FN == "" { continue } switch FN[0] { case 'f', 'F': parseIntervalFail(interval, FN) case 's', 'S': parseIntervalSuccess(interval, FN) default: FN = "s=" + FN parseIntervalSuccess(interval, FN) } } interval.reset() result = append(result, interval) } return result } func parseRandLR(lrvalue string) randLR { vlen := len(lrvalue) lastchar := lrvalue[vlen-1] lr := strings.Split(lrvalue, "-") switch len(lr) { case 1: lr := randLR{parseTimeValue(lr[0], lastchar), parseTimeValue(lr[0], lastchar)} return lr case 2: lr := randLR{parseTimeValue(lr[0], lastchar), parseTimeValue(lr[1], lastchar)} return lr default: panic("lr is error") } } // intervalPriorityListISecond 获取优先链表比较的值 func intervalPriorityListISecond(planlist *plist.PriorityList, count int) int { if planlist.Size() > 0 { node := new(NodeCount) node.SetValue(count) iwantNode := planlist.GetCompare(node) if iwantNode != nil { wantNode := iwantNode.(*NodeCount) lr := wantNode.randLR return randomdata.Number(lr.left, lr.right+1) } } return -1 } func getInt(v string) int { vint, err := strconv.Atoi(v) if err != nil { panic(err) } return vint } func parseTimeValue(v string, lastchar byte) int { vlen := len(v) switch lastchar { case 's': return getInt(v[:vlen-1]) case 'm': return getInt(v[:vlen-1]) * 60 case 'h': return getInt(v[:vlen-1]) * 3600 case 'd': return getInt(v[:vlen-1]) * 3600 * 24 default: return getInt(v) } }