diff --git a/cmd/prometheus/main_unix_test.go b/cmd/prometheus/main_unix_test.go index b49110ea91..7224e25d70 100644 --- a/cmd/prometheus/main_unix_test.go +++ b/cmd/prometheus/main_unix_test.go @@ -72,9 +72,11 @@ Loop: if !startedOk { t.Fatal("prometheus didn't start in the specified timeout") } - if err := prom.Process.Kill(); err == nil { + switch err := prom.Process.Kill(); { + case err == nil: t.Errorf("prometheus didn't shutdown gracefully after sending the Interrupt signal") - } else if stoppedErr != nil && stoppedErr.Error() != "signal: interrupt" { // TODO - find a better way to detect when the process didn't exit as expected! + case stoppedErr != nil && stoppedErr.Error() != "signal: interrupt": + // TODO: find a better way to detect when the process didn't exit as expected! t.Errorf("prometheus exited with an unexpected error: %v", stoppedErr) } } diff --git a/cmd/promtool/tsdb.go b/cmd/promtool/tsdb.go index 0e0cdb863a..84aa43a9c4 100644 --- a/cmd/promtool/tsdb.go +++ b/cmd/promtool/tsdb.go @@ -403,14 +403,15 @@ func openBlock(path, blockID string) (*tsdb.DBReadOnly, tsdb.BlockReader, error) return nil, nil, err } var block tsdb.BlockReader - if blockID != "" { + switch { + case blockID != "": for _, b := range blocks { if b.Meta().ULID.String() == blockID { block = b break } } - } else if len(blocks) > 0 { + case len(blocks) > 0: block = blocks[len(blocks)-1] } if block == nil { diff --git a/discovery/dns/dns.go b/discovery/dns/dns.go index 2b11c242ab..96e07254f0 100644 --- a/discovery/dns/dns.go +++ b/discovery/dns/dns.go @@ -285,21 +285,22 @@ func lookupWithSearchPath(name string, qtype uint16, logger log.Logger) (*dns.Ms for _, lname := range conf.NameList(name) { response, err := lookupFromAnyServer(lname, qtype, conf, logger) - if err != nil { + switch { + case err != nil: // We can't go home yet, because a later name // may give us a valid, successful answer. However // we can no longer say "this name definitely doesn't // exist", because we did not get that answer for // at least one name. allResponsesValid = false - } else if response.Rcode == dns.RcodeSuccess { + case response.Rcode == dns.RcodeSuccess: // Outcome 1: GOLD! return response, nil } } if allResponsesValid { - // Outcome 2: everyone says NXDOMAIN, that's good enough for me + // Outcome 2: everyone says NXDOMAIN, that's good enough for me. return &dns.Msg{}, nil } // Outcome 3: boned. diff --git a/discovery/kubernetes/kubernetes.go b/discovery/kubernetes/kubernetes.go index 0f03e2cdb7..a44bd513ce 100644 --- a/discovery/kubernetes/kubernetes.go +++ b/discovery/kubernetes/kubernetes.go @@ -299,12 +299,13 @@ func New(l log.Logger, conf *SDConfig) (*Discovery, error) { err error ownNamespace string ) - if conf.KubeConfig != "" { + switch { + case conf.KubeConfig != "": kcfg, err = clientcmd.BuildConfigFromFlags("", conf.KubeConfig) if err != nil { return nil, err } - } else if conf.APIServer.URL == nil { + case conf.APIServer.URL == nil: // Use the Kubernetes provided pod service account // as described in https://kubernetes.io/docs/admin/service-accounts-admin/ kcfg, err = rest.InClusterConfig() @@ -324,7 +325,7 @@ func New(l log.Logger, conf *SDConfig) (*Discovery, error) { } level.Info(l).Log("msg", "Using pod service account via in-cluster config") - } else { + default: rt, err := config.NewRoundTripperFromConfig(conf.HTTPClientConfig, "kubernetes_sd") if err != nil { return nil, err diff --git a/discovery/linode/linode.go b/discovery/linode/linode.go index 0fd0a2c370..449e13cd89 100644 --- a/discovery/linode/linode.go +++ b/discovery/linode/linode.go @@ -250,19 +250,20 @@ func (d *Discovery) refreshData(ctx context.Context) ([]*targetgroup.Group, erro continue } - if detailedIP.Public && publicIPv4 == "" { + switch { + case detailedIP.Public && publicIPv4 == "": publicIPv4 = detailedIP.Address if detailedIP.RDNS != "" && detailedIP.RDNS != "null" { publicIPv4RDNS = detailedIP.RDNS } - } else if !detailedIP.Public && privateIPv4 == "" { + case !detailedIP.Public && privateIPv4 == "": privateIPv4 = detailedIP.Address if detailedIP.RDNS != "" && detailedIP.RDNS != "null" { privateIPv4RDNS = detailedIP.RDNS } - } else { + default: extraIPs = append(extraIPs, detailedIP.Address) } } diff --git a/discovery/marathon/marathon.go b/discovery/marathon/marathon.go index 079f93ad0b..cfd3e2c083 100644 --- a/discovery/marathon/marathon.go +++ b/discovery/marathon/marathon.go @@ -136,9 +136,10 @@ func NewDiscovery(conf SDConfig, logger log.Logger) (*Discovery, error) { return nil, err } - if len(conf.AuthToken) > 0 { + switch { + case len(conf.AuthToken) > 0: rt, err = newAuthTokenRoundTripper(conf.AuthToken, rt) - } else if len(conf.AuthTokenFile) > 0 { + case len(conf.AuthTokenFile) > 0: rt, err = newAuthTokenFileRoundTripper(conf.AuthTokenFile, rt) } if err != nil { @@ -400,19 +401,20 @@ func targetsForApp(app *app) []model.LabelSet { var labels []map[string]string var prefix string - if len(app.Container.PortMappings) != 0 { + switch { + case len(app.Container.PortMappings) != 0: // In Marathon 1.5.x the "container.docker.portMappings" object was moved // to "container.portMappings". ports, labels = extractPortMapping(app.Container.PortMappings, app.isContainerNet()) prefix = portMappingLabelPrefix - } else if len(app.Container.Docker.PortMappings) != 0 { + case len(app.Container.Docker.PortMappings) != 0: // Prior to Marathon 1.5 the port mappings could be found at the path // "container.docker.portMappings". ports, labels = extractPortMapping(app.Container.Docker.PortMappings, app.isContainerNet()) prefix = portMappingLabelPrefix - } else if len(app.PortDefinitions) != 0 { + case len(app.PortDefinitions) != 0: // PortDefinitions deprecates the "ports" array and can be used to specify // a list of ports with metadata in case a mapping is not required. ports = make([]uint32, len(app.PortDefinitions)) diff --git a/documentation/examples/remote_storage/remote_storage_adapter/influxdb/client.go b/documentation/examples/remote_storage/remote_storage_adapter/influxdb/client.go index fffbc9c2ae..959656aa8f 100644 --- a/documentation/examples/remote_storage/remote_storage_adapter/influxdb/client.go +++ b/documentation/examples/remote_storage/remote_storage_adapter/influxdb/client.go @@ -290,13 +290,14 @@ func mergeSamples(a, b []prompb.Sample) []prompb.Sample { result := make([]prompb.Sample, 0, len(a)+len(b)) i, j := 0, 0 for i < len(a) && j < len(b) { - if a[i].Timestamp < b[j].Timestamp { + switch { + case a[i].Timestamp < b[j].Timestamp: result = append(result, a[i]) i++ - } else if a[i].Timestamp > b[j].Timestamp { + case a[i].Timestamp > b[j].Timestamp: result = append(result, b[j]) j++ - } else { + default: result = append(result, a[i]) i++ j++ diff --git a/model/histogram/float_histogram.go b/model/histogram/float_histogram.go index cd73083bbd..f95f0051c9 100644 --- a/model/histogram/float_histogram.go +++ b/model/histogram/float_histogram.go @@ -824,10 +824,11 @@ mergeLoop: // Merge together all buckets from the original schema that fall into origIdx += span.Offset } currIdx := i.targetIdx(origIdx) - if firstPass { + switch { + case firstPass: i.currIdx = currIdx firstPass = false - } else if currIdx != i.currIdx { + case currIdx != i.currIdx: // Reached next bucket in targetSchema. // Do not actually forward to the next bucket, but break out. break mergeLoop diff --git a/model/labels/labels.go b/model/labels/labels.go index b7398d17f9..93524ddcfc 100644 --- a/model/labels/labels.go +++ b/model/labels/labels.go @@ -169,11 +169,12 @@ func (ls Labels) HashForLabels(b []byte, names ...string) (uint64, []byte) { b = b[:0] i, j := 0, 0 for i < len(ls) && j < len(names) { - if names[j] < ls[i].Name { + switch { + case names[j] < ls[i].Name: j++ - } else if ls[i].Name < names[j] { + case ls[i].Name < names[j]: i++ - } else { + default: b = append(b, ls[i].Name...) b = append(b, seps[0]) b = append(b, ls[i].Value...) @@ -213,11 +214,12 @@ func (ls Labels) BytesWithLabels(buf []byte, names ...string) []byte { b.WriteByte(labelSep) i, j := 0, 0 for i < len(ls) && j < len(names) { - if names[j] < ls[i].Name { + switch { + case names[j] < ls[i].Name: j++ - } else if ls[i].Name < names[j] { + case ls[i].Name < names[j]: i++ - } else { + default: if b.Len() > 1 { b.WriteByte(seps[0]) } diff --git a/promql/engine.go b/promql/engine.go index 21b894b936..1f493f129c 100644 --- a/promql/engine.go +++ b/promql/engine.go @@ -400,7 +400,7 @@ func (ng *Engine) SetQueryLogger(l QueryLogger) { } // NewInstantQuery returns an evaluation query for the given expression at the given time. -func (ng *Engine) NewInstantQuery(ctx context.Context, q storage.Queryable, opts *QueryOpts, qs string, ts time.Time) (Query, error) { +func (ng *Engine) NewInstantQuery(_ context.Context, q storage.Queryable, opts *QueryOpts, qs string, ts time.Time) (Query, error) { expr, err := parser.ParseExpr(qs) if err != nil { return nil, err @@ -416,7 +416,7 @@ func (ng *Engine) NewInstantQuery(ctx context.Context, q storage.Queryable, opts // NewRangeQuery returns an evaluation query for the given time range and with // the resolution set by the interval. -func (ng *Engine) NewRangeQuery(ctx context.Context, q storage.Queryable, opts *QueryOpts, qs string, start, end time.Time, interval time.Duration) (Query, error) { +func (ng *Engine) NewRangeQuery(_ context.Context, q storage.Queryable, opts *QueryOpts, qs string, start, end time.Time, interval time.Duration) (Query, error) { expr, err := parser.ParseExpr(qs) if err != nil { return nil, err @@ -1979,7 +1979,7 @@ func (ev *evaluator) matrixIterSlice( // (b) the number of samples is relatively small. // so a linear search will be as fast as a binary search. var drop int - for drop = 0; histograms[drop].T < mint; drop++ { + for drop = 0; histograms[drop].T < mint; drop++ { // nolint:revive } ev.currentSamples -= drop copy(histograms, histograms[drop:]) @@ -2096,13 +2096,13 @@ func (ev *evaluator) VectorAnd(lhs, rhs Vector, matching *parser.VectorMatching, } func (ev *evaluator) VectorOr(lhs, rhs Vector, matching *parser.VectorMatching, lhsh, rhsh []EvalSeriesHelper, enh *EvalNodeHelper) Vector { - if matching.Card != parser.CardManyToMany { + switch { + case matching.Card != parser.CardManyToMany: panic("set operations must only use many-to-many matching") - } - if len(lhs) == 0 { // Short-circuit. + case len(lhs) == 0: // Short-circuit. enh.Out = append(enh.Out, rhs...) return enh.Out - } else if len(rhs) == 0 { + case len(rhs) == 0: enh.Out = append(enh.Out, lhs...) return enh.Out } @@ -2221,13 +2221,14 @@ func (ev *evaluator) VectorBinop(op parser.ItemType, lhs, rhs Vector, matching * hl, hr = hr, hl } floatValue, histogramValue, keep := vectorElemBinop(op, fl, fr, hl, hr) - if returnBool { + switch { + case returnBool: if keep { floatValue = 1.0 } else { floatValue = 0.0 } - } else if !keep { + case !keep: continue } metric := resultMetric(ls.Metric, rs.Metric, op, matching, enh) @@ -2514,14 +2515,15 @@ func (ev *evaluator) aggregation(op parser.ItemType, grouping []string, without if !ok { var m labels.Labels enh.resetBuilder(metric) - if without { + switch { + case without: enh.lb.Del(grouping...) enh.lb.Del(labels.MetricName) m = enh.lb.Labels() - } else if len(grouping) > 0 { + case len(grouping) > 0: enh.lb.Keep(grouping...) m = enh.lb.Labels() - } else { + default: m = labels.EmptyLabels() } newAgg := &groupedAggregation{ @@ -2530,9 +2532,10 @@ func (ev *evaluator) aggregation(op parser.ItemType, grouping []string, without mean: s.F, groupCount: 1, } - if s.H == nil { + switch { + case s.H == nil: newAgg.hasFloat = true - } else if op == parser.SUM { + case op == parser.SUM: newAgg.histogramValue = s.H.Copy() newAgg.hasHistogram = true } @@ -2542,9 +2545,10 @@ func (ev *evaluator) aggregation(op parser.ItemType, grouping []string, without inputVecLen := int64(len(vec)) resultSize := k - if k > inputVecLen { + switch { + case k > inputVecLen: resultSize = inputVecLen - } else if k == 0 { + case k == 0: resultSize = 1 } switch op { @@ -2637,12 +2641,13 @@ func (ev *evaluator) aggregation(op parser.ItemType, grouping []string, without case parser.TOPK: // We build a heap of up to k elements, with the smallest element at heap[0]. - if int64(len(group.heap)) < k { + switch { + case int64(len(group.heap)) < k: heap.Push(&group.heap, &Sample{ F: s.F, Metric: s.Metric, }) - } else if group.heap[0].F < s.F || (math.IsNaN(group.heap[0].F) && !math.IsNaN(s.F)) { + case group.heap[0].F < s.F || (math.IsNaN(group.heap[0].F) && !math.IsNaN(s.F)): // This new element is bigger than the previous smallest element - overwrite that. group.heap[0] = Sample{ F: s.F, @@ -2655,12 +2660,13 @@ func (ev *evaluator) aggregation(op parser.ItemType, grouping []string, without case parser.BOTTOMK: // We build a heap of up to k elements, with the biggest element at heap[0]. - if int64(len(group.reverseHeap)) < k { + switch { + case int64(len(group.reverseHeap)) < k: heap.Push(&group.reverseHeap, &Sample{ F: s.F, Metric: s.Metric, }) - } else if group.reverseHeap[0].F > s.F || (math.IsNaN(group.reverseHeap[0].F) && !math.IsNaN(s.F)) { + case group.reverseHeap[0].F > s.F || (math.IsNaN(group.reverseHeap[0].F) && !math.IsNaN(s.F)): // This new element is smaller than the previous biggest element - overwrite that. group.reverseHeap[0] = Sample{ F: s.F, @@ -2819,9 +2825,10 @@ func PreprocessExpr(expr parser.Expr, start, end time.Time) parser.Expr { func preprocessExprHelper(expr parser.Expr, start, end time.Time) bool { switch n := expr.(type) { case *parser.VectorSelector: - if n.StartOrEnd == parser.START { + switch n.StartOrEnd { + case parser.START: n.Timestamp = makeInt64Pointer(timestamp.FromTime(start)) - } else if n.StartOrEnd == parser.END { + case parser.END: n.Timestamp = makeInt64Pointer(timestamp.FromTime(end)) } return n.Timestamp != nil @@ -2878,9 +2885,10 @@ func preprocessExprHelper(expr parser.Expr, start, end time.Time) bool { if isInvariant { n.Expr = newStepInvariantExpr(n.Expr) } - if n.StartOrEnd == parser.START { + switch n.StartOrEnd { + case parser.START: n.Timestamp = makeInt64Pointer(timestamp.FromTime(start)) - } else if n.StartOrEnd == parser.END { + case parser.END: n.Timestamp = makeInt64Pointer(timestamp.FromTime(end)) } return n.Timestamp != nil diff --git a/promql/functions.go b/promql/functions.go index 0c22cb44c7..2983de4fde 100644 --- a/promql/functions.go +++ b/promql/functions.go @@ -804,12 +804,14 @@ func funcPi(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) V // === sgn(Vector parser.ValueTypeVector) Vector === func funcSgn(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) Vector { return simpleFunc(vals, enh, func(v float64) float64 { - if v < 0 { + switch { + case v < 0: return -1 - } else if v > 0 { + case v > 0: return 1 + default: + return v } - return v }) } diff --git a/promql/parser/ast.go b/promql/parser/ast.go index 190af2d590..f156fc6024 100644 --- a/promql/parser/ast.go +++ b/promql/parser/ast.go @@ -368,13 +368,14 @@ func Children(node Node) []Node { case *AggregateExpr: // While this does not look nice, it should avoid unnecessary allocations // caused by slice resizing - if n.Expr == nil && n.Param == nil { + switch { + case n.Expr == nil && n.Param == nil: return nil - } else if n.Expr == nil { + case n.Expr == nil: return []Node{n.Param} - } else if n.Param == nil { + case n.Param == nil: return []Node{n.Expr} - } else { + default: return []Node{n.Expr, n.Param} } case *BinaryExpr: diff --git a/promql/parser/lex.go b/promql/parser/lex.go index 657dc28095..fe5a8abfeb 100644 --- a/promql/parser/lex.go +++ b/promql/parser/lex.go @@ -347,9 +347,10 @@ func lexStatements(l *Lexer) stateFn { switch r := l.next(); { case r == eof: - if l.parenDepth != 0 { + switch { + case l.parenDepth != 0: return l.errorf("unclosed left parenthesis") - } else if l.bracketOpen { + case l.bracketOpen: return l.errorf("unclosed left bracket") } l.emit(EOF) @@ -371,12 +372,13 @@ func lexStatements(l *Lexer) stateFn { case r == '^': l.emit(POW) case r == '=': - if t := l.peek(); t == '=' { + switch t := l.peek(); t { + case '=': l.next() l.emit(EQLC) - } else if t == '~' { + case '~': return l.errorf("unexpected character after '=': %q", t) - } else { + default: l.emit(EQL) } case r == '!': @@ -791,11 +793,12 @@ Loop: default: l.backup() word := l.input[l.start:l.pos] - if kw, ok := key[strings.ToLower(word)]; ok { + switch kw, ok := key[strings.ToLower(word)]; { + case ok: l.emit(kw) - } else if !strings.Contains(word, ":") { + case !strings.Contains(word, ":"): l.emit(IDENTIFIER) - } else { + default: l.emit(METRIC_IDENTIFIER) } break Loop diff --git a/promql/parser/parse.go b/promql/parser/parse.go index 3c32f3c05b..e69ed4595c 100644 --- a/promql/parser/parse.go +++ b/promql/parser/parse.go @@ -270,14 +270,15 @@ var errUnexpected = errors.New("unexpected error") // recover is the handler that turns panics into returns from the top level of Parse. func (p *parser) recover(errp *error) { e := recover() - if _, ok := e.(runtime.Error); ok { + switch _, ok := e.(runtime.Error); { + case ok: // Print the stack trace but do not inhibit the running application. buf := make([]byte, 64<<10) buf = buf[:runtime.Stack(buf, false)] fmt.Fprintf(os.Stderr, "parser panic: %v\n%s", e, buf) *errp = errUnexpected - } else if e != nil { + case e != nil: *errp = e.(error) } } @@ -518,20 +519,18 @@ func (p *parser) checkAST(node Node) (typ ValueType) { p.addParseErrf(n.RHS.PositionRange(), "binary expression must contain only scalar and instant vector types") } - if (lt != ValueTypeVector || rt != ValueTypeVector) && n.VectorMatching != nil { + switch { + case (lt != ValueTypeVector || rt != ValueTypeVector) && n.VectorMatching != nil: if len(n.VectorMatching.MatchingLabels) > 0 { p.addParseErrf(n.PositionRange(), "vector matching only allowed between instant vectors") } n.VectorMatching = nil - } else { - // Both operands are Vectors. - if n.Op.IsSetOperator() { - if n.VectorMatching.Card == CardOneToMany || n.VectorMatching.Card == CardManyToOne { - p.addParseErrf(n.PositionRange(), "no grouping allowed for %q operation", n.Op) - } - if n.VectorMatching.Card != CardManyToMany { - p.addParseErrf(n.PositionRange(), "set operations must always be many-to-many") - } + case n.Op.IsSetOperator(): // Both operands are Vectors. + if n.VectorMatching.Card == CardOneToMany || n.VectorMatching.Card == CardManyToOne { + p.addParseErrf(n.PositionRange(), "no grouping allowed for %q operation", n.Op) + } + if n.VectorMatching.Card != CardManyToMany { + p.addParseErrf(n.PositionRange(), "set operations must always be many-to-many") } } @@ -708,9 +707,10 @@ func (p *parser) addOffset(e Node, offset time.Duration) { } // it is already ensured by parseDuration func that there never will be a zero offset modifier - if *orgoffsetp != 0 { + switch { + case *orgoffsetp != 0: p.addParseErrf(e.PositionRange(), "offset may not be set multiple times") - } else if orgoffsetp != nil { + case orgoffsetp != nil: *orgoffsetp = offset } diff --git a/promql/parser/printer.go b/promql/parser/printer.go index 1f15eeef33..ff171f2152 100644 --- a/promql/parser/printer.go +++ b/promql/parser/printer.go @@ -124,17 +124,19 @@ func (node *MatrixSelector) String() string { // Copy the Vector selector before changing the offset vecSelector := *node.VectorSelector.(*VectorSelector) offset := "" - if vecSelector.OriginalOffset > time.Duration(0) { + switch { + case vecSelector.OriginalOffset > time.Duration(0): offset = fmt.Sprintf(" offset %s", model.Duration(vecSelector.OriginalOffset)) - } else if vecSelector.OriginalOffset < time.Duration(0) { + case vecSelector.OriginalOffset < time.Duration(0): offset = fmt.Sprintf(" offset -%s", model.Duration(-vecSelector.OriginalOffset)) } at := "" - if vecSelector.Timestamp != nil { + switch { + case vecSelector.Timestamp != nil: at = fmt.Sprintf(" @ %.3f", float64(*vecSelector.Timestamp)/1000.0) - } else if vecSelector.StartOrEnd == START { + case vecSelector.StartOrEnd == START: at = " @ start()" - } else if vecSelector.StartOrEnd == END { + case vecSelector.StartOrEnd == END: at = " @ end()" } @@ -162,17 +164,19 @@ func (node *SubqueryExpr) getSubqueryTimeSuffix() string { step = model.Duration(node.Step).String() } offset := "" - if node.OriginalOffset > time.Duration(0) { + switch { + case node.OriginalOffset > time.Duration(0): offset = fmt.Sprintf(" offset %s", model.Duration(node.OriginalOffset)) - } else if node.OriginalOffset < time.Duration(0) { + case node.OriginalOffset < time.Duration(0): offset = fmt.Sprintf(" offset -%s", model.Duration(-node.OriginalOffset)) } at := "" - if node.Timestamp != nil { + switch { + case node.Timestamp != nil: at = fmt.Sprintf(" @ %.3f", float64(*node.Timestamp)/1000.0) - } else if node.StartOrEnd == START { + case node.StartOrEnd == START: at = " @ start()" - } else if node.StartOrEnd == END { + case node.StartOrEnd == END: at = " @ end()" } return fmt.Sprintf("[%s:%s]%s%s", model.Duration(node.Range), step, at, offset) @@ -207,17 +211,19 @@ func (node *VectorSelector) String() string { labelStrings = append(labelStrings, matcher.String()) } offset := "" - if node.OriginalOffset > time.Duration(0) { + switch { + case node.OriginalOffset > time.Duration(0): offset = fmt.Sprintf(" offset %s", model.Duration(node.OriginalOffset)) - } else if node.OriginalOffset < time.Duration(0) { + case node.OriginalOffset < time.Duration(0): offset = fmt.Sprintf(" offset -%s", model.Duration(-node.OriginalOffset)) } at := "" - if node.Timestamp != nil { + switch { + case node.Timestamp != nil: at = fmt.Sprintf(" @ %.3f", float64(*node.Timestamp)/1000.0) - } else if node.StartOrEnd == START { + case node.StartOrEnd == START: at = " @ start()" - } else if node.StartOrEnd == END { + case node.StartOrEnd == END: at = " @ end()" } diff --git a/promql/quantile.go b/promql/quantile.go index aaead671c7..78d0bbaf0c 100644 --- a/promql/quantile.go +++ b/promql/quantile.go @@ -169,11 +169,12 @@ func histogramQuantile(q float64, h *histogram.FloatHistogram) float64 { } } if bucket.Lower < 0 && bucket.Upper > 0 { - if len(h.NegativeBuckets) == 0 && len(h.PositiveBuckets) > 0 { + switch { + case len(h.NegativeBuckets) == 0 && len(h.PositiveBuckets) > 0: // The result is in the zero bucket and the histogram has only // positive buckets. So we consider 0 to be the lower bound. bucket.Lower = 0 - } else if len(h.PositiveBuckets) == 0 && len(h.NegativeBuckets) > 0 { + case len(h.PositiveBuckets) == 0 && len(h.NegativeBuckets) > 0: // The result is in the zero bucket and the histogram has only // negative buckets. So we consider 0 to be the upper bound. bucket.Upper = 0 @@ -244,12 +245,13 @@ func histogramFraction(lower, upper float64, h *histogram.FloatHistogram) float6 for it.Next() { b := it.At() if b.Lower < 0 && b.Upper > 0 { - if len(h.NegativeBuckets) == 0 && len(h.PositiveBuckets) > 0 { + switch { + case len(h.NegativeBuckets) == 0 && len(h.PositiveBuckets) > 0: // This is the zero bucket and the histogram has only // positive buckets. So we consider 0 to be the lower // bound. b.Lower = 0 - } else if len(h.PositiveBuckets) == 0 && len(h.NegativeBuckets) > 0 { + case len(h.PositiveBuckets) == 0 && len(h.NegativeBuckets) > 0: // This is in the zero bucket and the histogram has only // negative buckets. So we consider 0 to be the upper // bound. diff --git a/rules/alerting_test.go b/rules/alerting_test.go index 13aab98048..8cd0da2815 100644 --- a/rules/alerting_test.go +++ b/rules/alerting_test.go @@ -587,10 +587,10 @@ func TestAlertingRuleLimit(t *testing.T) { evalTime := time.Unix(0, 0) for _, test := range tests { - _, err := rule.Eval(suite.Context(), evalTime, EngineQueryFunc(suite.QueryEngine(), suite.Storage()), nil, test.limit) - if err != nil { + switch _, err := rule.Eval(suite.Context(), evalTime, EngineQueryFunc(suite.QueryEngine(), suite.Storage()), nil, test.limit); { + case err != nil: require.EqualError(t, err, test.err) - } else if test.err != "" { + case test.err != "": t.Errorf("Expected errror %s, got none", test.err) } } diff --git a/rules/manager_test.go b/rules/manager_test.go index 16bb080f55..26a7909644 100644 --- a/rules/manager_test.go +++ b/rules/manager_test.go @@ -481,17 +481,18 @@ func TestForStateRestore(t *testing.T) { }) // Checking if we have restored it correctly. - if tst.noRestore { + switch { + case tst.noRestore: require.Equal(t, tst.num, len(got)) for _, e := range got { require.Equal(t, e.ActiveAt, restoreTime) } - } else if tst.gracePeriod { + case tst.gracePeriod: require.Equal(t, tst.num, len(got)) for _, e := range got { require.Equal(t, opts.ForGracePeriod, e.ActiveAt.Add(alertForDuration).Sub(restoreTime)) } - } else { + default: exp := tst.alerts require.Equal(t, len(exp), len(got)) sortAlerts(exp) diff --git a/rules/recording_test.go b/rules/recording_test.go index 61f47e0487..35a0b1a0bd 100644 --- a/rules/recording_test.go +++ b/rules/recording_test.go @@ -223,10 +223,10 @@ func TestRecordingRuleLimit(t *testing.T) { evalTime := time.Unix(0, 0) for _, test := range tests { - _, err := rule.Eval(suite.Context(), evalTime, EngineQueryFunc(suite.QueryEngine(), suite.Storage()), nil, test.limit) - if err != nil { + switch _, err := rule.Eval(suite.Context(), evalTime, EngineQueryFunc(suite.QueryEngine(), suite.Storage()), nil, test.limit); { + case err != nil: require.EqualError(t, err, test.err) - } else if test.err != "" { + case test.err != "": t.Errorf("Expected error %s, got none", test.err) } } diff --git a/scrape/manager.go b/scrape/manager.go index 69a0eaa1f7..d75fe30cf5 100644 --- a/scrape/manager.go +++ b/scrape/manager.go @@ -288,10 +288,11 @@ func (m *Manager) ApplyConfig(cfg *config.Config) error { // Cleanup and reload pool if the configuration has changed. var failed bool for name, sp := range m.scrapePools { - if cfg, ok := m.scrapeConfigs[name]; !ok { + switch cfg, ok := m.scrapeConfigs[name]; { + case !ok: sp.stop() delete(m.scrapePools, name) - } else if !reflect.DeepEqual(sp.config, cfg) { + case !reflect.DeepEqual(sp.config, cfg): err := sp.reload(cfg) if err != nil { level.Error(m.logger).Log("msg", "error reloading scrape pool", "err", err, "scrape_pool", name) diff --git a/scrape/scrape.go b/scrape/scrape.go index f38527ff30..680585af89 100644 --- a/scrape/scrape.go +++ b/scrape/scrape.go @@ -503,9 +503,10 @@ func (sp *scrapePool) Sync(tgs []*targetgroup.Group) { // Replicate .Labels().IsEmpty() with a loop here to avoid generating garbage. nonEmpty := false t.LabelsRange(func(l labels.Label) { nonEmpty = true }) - if nonEmpty { + switch { + case nonEmpty: all = append(all, t) - } else if !t.discoveredLabels.IsEmpty() { + case !t.discoveredLabels.IsEmpty(): sp.droppedTargets = append(sp.droppedTargets, t) } } @@ -946,9 +947,10 @@ func (c *scrapeCache) iterDone(flushCache bool) { count := len(c.series) + len(c.droppedSeries) + len(c.metadata) c.metaMtx.Unlock() - if flushCache { + switch { + case flushCache: c.successfulCount = count - } else if count > c.successfulCount*2+1000 { + case count > c.successfulCount*2+1000: // If a target had varying labels in scrapes that ultimately failed, // the caches would grow indefinitely. Force a flush when this happens. // We use the heuristic that this is a doubling of the cache size diff --git a/scrape/scrape_test.go b/scrape/scrape_test.go index a8028b652a..6b4b2d5f57 100644 --- a/scrape/scrape_test.go +++ b/scrape/scrape_test.go @@ -724,9 +724,10 @@ func TestScrapeLoopStop(t *testing.T) { // All samples in a scrape must have the same timestamp. var ts int64 for i, s := range appender.result { - if i%6 == 0 { + switch { + case i%6 == 0: ts = s.t - } else if s.t != ts { + case s.t != ts: t.Fatalf("Unexpected multiple timestamps within single scrape") } } @@ -1139,10 +1140,11 @@ func TestScrapeLoopRunCreatesStaleMarkersOnFailedScrape(t *testing.T) { scraper.scrapeFunc = func(ctx context.Context, w io.Writer) error { numScrapes++ - if numScrapes == 1 { + switch numScrapes { + case 1: w.Write([]byte("metric_a 42\n")) return nil - } else if numScrapes == 5 { + case 5: cancel() } return errors.New("scrape failed") @@ -1200,13 +1202,14 @@ func TestScrapeLoopRunCreatesStaleMarkersOnParseFailure(t *testing.T) { scraper.scrapeFunc = func(ctx context.Context, w io.Writer) error { numScrapes++ - if numScrapes == 1 { + switch numScrapes { + case 1: w.Write([]byte("metric_a 42\n")) return nil - } else if numScrapes == 2 { + case 2: w.Write([]byte("7&-\n")) return nil - } else if numScrapes == 3 { + case 3: cancel() } return errors.New("scrape failed") @@ -1265,14 +1268,15 @@ func TestScrapeLoopCache(t *testing.T) { numScrapes := 0 scraper.scrapeFunc = func(ctx context.Context, w io.Writer) error { - if numScrapes == 1 || numScrapes == 2 { + switch numScrapes { + case 1, 2: if _, ok := sl.cache.series["metric_a"]; !ok { t.Errorf("metric_a missing from cache after scrape %d", numScrapes) } if _, ok := sl.cache.series["metric_b"]; !ok { t.Errorf("metric_b missing from cache after scrape %d", numScrapes) } - } else if numScrapes == 3 { + case 3: if _, ok := sl.cache.series["metric_a"]; !ok { t.Errorf("metric_a missing from cache after scrape %d", numScrapes) } @@ -1283,13 +1287,14 @@ func TestScrapeLoopCache(t *testing.T) { numScrapes++ - if numScrapes == 1 { + switch numScrapes { + case 1: w.Write([]byte("metric_a 42\nmetric_b 43\n")) return nil - } else if numScrapes == 3 { + case 3: w.Write([]byte("metric_a 44\n")) return nil - } else if numScrapes == 4 { + case 4: cancel() } return fmt.Errorf("scrape failed") @@ -2280,11 +2285,12 @@ func TestTargetScrapeScrapeCancel(t *testing.T) { go func() { _, err := ts.scrape(ctx, io.Discard) - if err == nil { + switch { + case err == nil: errc <- errors.New("Expected error but got nil") - } else if ctx.Err() != context.Canceled { + case ctx.Err() != context.Canceled: errc <- errors.Errorf("Expected context cancellation error but got: %s", ctx.Err()) - } else { + default: close(errc) } }() diff --git a/storage/fanout.go b/storage/fanout.go index 4f995afbac..a9db4f6280 100644 --- a/storage/fanout.go +++ b/storage/fanout.go @@ -222,9 +222,10 @@ func (f *fanoutAppender) Rollback() (err error) { for _, appender := range f.secondaries { rollbackErr := appender.Rollback() - if err == nil { + switch { + case err == nil: err = rollbackErr - } else if rollbackErr != nil { + case rollbackErr != nil: level.Error(f.logger).Log("msg", "Squashed rollback error on rollback", "err", rollbackErr) } } diff --git a/storage/merge.go b/storage/merge.go index 193a025227..c0665d720b 100644 --- a/storage/merge.go +++ b/storage/merge.go @@ -197,13 +197,14 @@ func mergeStrings(a, b []string) []string { res := make([]string, 0, maxl*10/9) for len(a) > 0 && len(b) > 0 { - if a[0] == b[0] { + switch { + case a[0] == b[0]: res = append(res, a[0]) a, b = a[1:], b[1:] - } else if a[0] < b[0] { + case a[0] < b[0]: res = append(res, a[0]) a = a[1:] - } else { + default: res = append(res, b[0]) b = b[1:] } diff --git a/storage/remote/codec.go b/storage/remote/codec.go index bfbd08d24b..2ceed4de11 100644 --- a/storage/remote/codec.go +++ b/storage/remote/codec.go @@ -291,13 +291,14 @@ func MergeLabels(primary, secondary []prompb.Label) []prompb.Label { result := make([]prompb.Label, 0, len(primary)+len(secondary)) i, j := 0, 0 for i < len(primary) && j < len(secondary) { - if primary[i].Name < secondary[j].Name { + switch { + case primary[i].Name < secondary[j].Name: result = append(result, primary[i]) i++ - } else if primary[i].Name > secondary[j].Name { + case primary[i].Name > secondary[j].Name: result = append(result, secondary[j]) j++ - } else { + default: result = append(result, primary[i]) i++ j++ @@ -429,7 +430,8 @@ func (c *concreteSeriesIterator) Seek(t int64) chunkenc.ValueType { return c.series.histograms[n+c.histogramsCur].Timestamp >= t }) - if c.floatsCur < len(c.series.floats) && c.histogramsCur < len(c.series.histograms) { + switch { + case c.floatsCur < len(c.series.floats) && c.histogramsCur < len(c.series.histograms): // If float samples and histogram samples have overlapping timestamps prefer the float samples. if c.series.floats[c.floatsCur].Timestamp <= c.series.histograms[c.histogramsCur].Timestamp { c.curValType = chunkenc.ValFloat @@ -445,9 +447,9 @@ func (c *concreteSeriesIterator) Seek(t int64) chunkenc.ValueType { c.floatsCur-- } } - } else if c.floatsCur < len(c.series.floats) { + case c.floatsCur < len(c.series.floats): c.curValType = chunkenc.ValFloat - } else if c.histogramsCur < len(c.series.histograms) { + case c.histogramsCur < len(c.series.histograms): c.curValType = getHistogramValType(&c.series.histograms[c.histogramsCur]) } @@ -515,18 +517,19 @@ func (c *concreteSeriesIterator) Next() chunkenc.ValueType { } c.curValType = chunkenc.ValNone - if peekFloatTS < peekHistTS { + switch { + case peekFloatTS < peekHistTS: c.floatsCur++ c.curValType = chunkenc.ValFloat - } else if peekHistTS < peekFloatTS { + case peekHistTS < peekFloatTS: c.histogramsCur++ c.curValType = chunkenc.ValHistogram - } else if peekFloatTS == noTS && peekHistTS == noTS { + case peekFloatTS == noTS && peekHistTS == noTS: // This only happens when the iterator is exhausted; we set the cursors off the end to prevent // Seek() from returning anything afterwards. c.floatsCur = len(c.series.floats) c.histogramsCur = len(c.series.histograms) - } else { + default: // Prefer float samples to histogram samples if there's a conflict. We advance the cursor for histograms // anyway otherwise the histogram sample will get selected on the next call to Next(). c.floatsCur++ diff --git a/storage/remote/ewma.go b/storage/remote/ewma.go index c7fb0289b0..ea4472c494 100644 --- a/storage/remote/ewma.go +++ b/storage/remote/ewma.go @@ -55,9 +55,10 @@ func (r *ewmaRate) tick() { r.mutex.Lock() defer r.mutex.Unlock() - if r.init { + switch { + case r.init: r.lastRate += r.alpha * (instantRate - r.lastRate) - } else if newEvents > 0 { + case newEvents > 0: r.init = true r.lastRate = instantRate } diff --git a/storage/remote/queue_manager.go b/storage/remote/queue_manager.go index 62bd17a66d..10fb6d153d 100644 --- a/storage/remote/queue_manager.go +++ b/storage/remote/queue_manager.go @@ -1030,9 +1030,10 @@ func (t *QueueManager) calculateDesiredShards() int { return t.numShards } - if numShards > t.cfg.MaxShards { + switch { + case numShards > t.cfg.MaxShards: numShards = t.cfg.MaxShards - } else if numShards < t.cfg.MinShards { + case numShards < t.cfg.MinShards: numShards = t.cfg.MinShards } return numShards @@ -1575,10 +1576,11 @@ func sendWriteRequestWithBackoff(ctx context.Context, cfg config.QueueConfig, l } sleepDuration = backoff - if backoffErr.retryAfter > 0 { + switch { + case backoffErr.retryAfter > 0: sleepDuration = backoffErr.retryAfter level.Info(l).Log("msg", "Retrying after duration specified by Retry-After header", "duration", sleepDuration) - } else if backoffErr.retryAfter < 0 { + case backoffErr.retryAfter < 0: level.Debug(l).Log("msg", "retry-after cannot be in past, retrying using default backoff mechanism") } diff --git a/tsdb/agent/db.go b/tsdb/agent/db.go index cb075f3060..3343ee18ef 100644 --- a/tsdb/agent/db.go +++ b/tsdb/agent/db.go @@ -951,7 +951,8 @@ func (a *appender) AppendHistogram(ref storage.SeriesRef, l labels.Labels, t int return 0, storage.ErrOutOfOrderSample } - if h != nil { + switch { + case h != nil: // NOTE: always modify pendingHistograms and histogramSeries together a.pendingHistograms = append(a.pendingHistograms, record.RefHistogramSample{ Ref: series.ref, @@ -959,7 +960,7 @@ func (a *appender) AppendHistogram(ref storage.SeriesRef, l labels.Labels, t int H: h, }) a.histogramSeries = append(a.histogramSeries, series) - } else if fh != nil { + case fh != nil: // NOTE: always modify pendingFloatHistograms and floatHistogramSeries together a.pendingFloatHistograms = append(a.pendingFloatHistograms, record.RefFloatHistogramSample{ Ref: series.ref, diff --git a/tsdb/chunkenc/xor.go b/tsdb/chunkenc/xor.go index ba2d96d36b..133ed9952a 100644 --- a/tsdb/chunkenc/xor.go +++ b/tsdb/chunkenc/xor.go @@ -164,14 +164,15 @@ func (a *xorAppender) Append(t int64, v float64) { var tDelta uint64 num := binary.BigEndian.Uint16(a.b.bytes()) - if num == 0 { + switch num { + case 0: buf := make([]byte, binary.MaxVarintLen64) for _, b := range buf[:binary.PutVarint(buf, t)] { a.b.writeByte(b) } a.b.writeBits(math.Float64bits(v), 64) - } else if num == 1 { + case 1: tDelta = uint64(t - a.t) buf := make([]byte, binary.MaxVarintLen64) @@ -181,7 +182,7 @@ func (a *xorAppender) Append(t int64, v float64) { a.writeVDelta(v) - } else { + default: tDelta = uint64(t - a.t) dod := int64(tDelta - a.tDelta) diff --git a/tsdb/chunks/head_chunks.go b/tsdb/chunks/head_chunks.go index a7ff90475e..bcdab21254 100644 --- a/tsdb/chunks/head_chunks.go +++ b/tsdb/chunks/head_chunks.go @@ -999,9 +999,10 @@ func (cdm *ChunkDiskMapper) DeleteCorrupted(originalErr error) error { cdm.readPathMtx.RLock() lastSeq := 0 for seg := range cdm.mmappedChunkFiles { - if seg >= cerr.FileIndex { + switch { + case seg >= cerr.FileIndex: segs = append(segs, seg) - } else if seg > lastSeq { + case seg > lastSeq: lastSeq = seg } } diff --git a/tsdb/db.go b/tsdb/db.go index 659251c3ca..45c0771b1c 100644 --- a/tsdb/db.go +++ b/tsdb/db.go @@ -963,10 +963,11 @@ func (db *DB) ApplyConfig(conf *config.Config) error { // Create WBL if it was not present and if OOO is enabled with WAL enabled. var wblog *wlog.WL var err error - if db.head.wbl != nil { + switch { + case db.head.wbl != nil: // The existing WBL from the disk might have been replayed while OOO was disabled. wblog = db.head.wbl - } else if !db.oooWasEnabled.Load() && oooTimeWindow > 0 && db.opts.WALSegmentSize >= 0 { + case !db.oooWasEnabled.Load() && oooTimeWindow > 0 && db.opts.WALSegmentSize >= 0: segmentSize := wlog.DefaultSegmentSize // Wal is set to a custom size. if db.opts.WALSegmentSize > 0 { @@ -1532,10 +1533,11 @@ func (db *DB) deleteBlocks(blocks map[ulid.ULID]*Block) error { } toDelete := filepath.Join(db.dir, ulid.String()) - if _, err := os.Stat(toDelete); os.IsNotExist(err) { + switch _, err := os.Stat(toDelete); { + case os.IsNotExist(err): // Noop. continue - } else if err != nil { + case err != nil: return errors.Wrapf(err, "stat dir %v", toDelete) } diff --git a/tsdb/head_append.go b/tsdb/head_append.go index 6bc91ae06d..86cb097513 100644 --- a/tsdb/head_append.go +++ b/tsdb/head_append.go @@ -344,9 +344,10 @@ func (a *headAppender) Append(ref storage.SeriesRef, lset labels.Labels, t int64 } if value.IsStaleNaN(v) { - if s.lastHistogramValue != nil { + switch { + case s.lastHistogramValue != nil: return a.AppendHistogram(ref, lset, t, &histogram.Histogram{Sum: v}, nil) - } else if s.lastFloatHistogramValue != nil { + case s.lastFloatHistogramValue != nil: return a.AppendHistogram(ref, lset, t, nil, &histogram.FloatHistogram{Sum: v}) } } @@ -552,9 +553,10 @@ func (a *headAppender) AppendHistogram(ref storage.SeriesRef, lset labels.Labels return 0, err } if created { - if h != nil { + switch { + case h != nil: s.lastHistogramValue = &histogram.Histogram{} - } else if fh != nil { + case fh != nil: s.lastFloatHistogramValue = &histogram.FloatHistogram{} } a.series = append(a.series, record.RefSeries{ @@ -564,7 +566,8 @@ func (a *headAppender) AppendHistogram(ref storage.SeriesRef, lset labels.Labels } } - if h != nil { + switch { + case h != nil: s.Lock() if err := s.appendableHistogram(t, h); err != nil { s.Unlock() @@ -581,7 +584,7 @@ func (a *headAppender) AppendHistogram(ref storage.SeriesRef, lset labels.Labels H: h, }) a.histogramSeries = append(a.histogramSeries, s) - } else if fh != nil { + case fh != nil: s.Lock() if err := s.appendableFloatHistogram(t, fh); err != nil { s.Unlock() @@ -938,7 +941,10 @@ func (a *headAppender) Commit() (err error) { var ok, chunkCreated bool - if err == nil && oooSample { + switch { + case err != nil: + // Do nothing here. + case oooSample: // Sample is OOO and OOO handling is enabled // and the delta is within the OOO tolerance. var mmapRef chunks.ChunkDiskMapperRef @@ -976,7 +982,7 @@ func (a *headAppender) Commit() (err error) { // TODO(codesome): Add error reporting? It depends on addressing https://github.com/prometheus/prometheus/discussions/10305. samplesAppended-- } - } else if err == nil { + default: ok, chunkCreated = series.append(s.T, s.V, a.appendID, a.head.chunkDiskMapper, chunkRange) if ok { if s.T < inOrderMint { @@ -1177,14 +1183,15 @@ func (s *memSeries) appendHistogram(t int64, h *histogram.Histogram, appendID ui app.RecodeHistogram(h, pBackwardInserts, nBackwardInserts) } // We have 3 cases here - // - !okToAppend -> We need to cut a new chunk. + // - !okToAppend or counterReset -> We need to cut a new chunk. // - okToAppend but we have inserts → Existing chunk needs // recoding before we can append our histogram. // - okToAppend and no inserts → Chunk is ready to support our histogram. - if !okToAppend || counterReset { + switch { + case !okToAppend || counterReset: c = s.cutNewHeadChunk(t, chunkenc.EncHistogram, chunkDiskMapper, chunkRange) chunkCreated = true - } else if len(pForwardInserts) > 0 || len(nForwardInserts) > 0 { + case len(pForwardInserts) > 0 || len(nForwardInserts) > 0: // New buckets have appeared. We need to recode all // prior histogram samples within the chunk before we // can process this one. @@ -1270,14 +1277,15 @@ func (s *memSeries) appendFloatHistogram(t int64, fh *histogram.FloatHistogram, app.RecodeHistogramm(fh, pBackwardInserts, nBackwardInserts) } // We have 3 cases here - // - !okToAppend -> We need to cut a new chunk. + // - !okToAppend or counterReset -> We need to cut a new chunk. // - okToAppend but we have inserts → Existing chunk needs // recoding before we can append our histogram. // - okToAppend and no inserts → Chunk is ready to support our histogram. - if !okToAppend || counterReset { + switch { + case !okToAppend || counterReset: c = s.cutNewHeadChunk(t, chunkenc.EncFloatHistogram, chunkDiskMapper, chunkRange) chunkCreated = true - } else if len(pForwardInserts) > 0 || len(nForwardInserts) > 0 { + case len(pForwardInserts) > 0 || len(nForwardInserts) > 0: // New buckets have appeared. We need to recode all // prior histogram samples within the chunk before we // can process this one. diff --git a/tsdb/head_read.go b/tsdb/head_read.go index 9c40bcd7a8..9c546ab164 100644 --- a/tsdb/head_read.go +++ b/tsdb/head_read.go @@ -424,7 +424,8 @@ func (s *memSeries) oooMergedChunk(meta chunks.Meta, cdm *chunks.ChunkDiskMapper break } - if chunkRef == meta.OOOLastRef { + switch { + case chunkRef == meta.OOOLastRef: tmpChks = append(tmpChks, chunkMetaAndChunkDiskMapperRef{ meta: chunks.Meta{ MinTime: meta.OOOLastMinTime, @@ -435,7 +436,7 @@ func (s *memSeries) oooMergedChunk(meta chunks.Meta, cdm *chunks.ChunkDiskMapper origMinT: c.minTime, origMaxT: c.maxTime, }) - } else if c.OverlapsClosedInterval(mint, maxt) { + case c.OverlapsClosedInterval(mint, maxt): tmpChks = append(tmpChks, chunkMetaAndChunkDiskMapperRef{ meta: chunks.Meta{ MinTime: c.minTime, @@ -594,12 +595,14 @@ type boundedIterator struct { func (b boundedIterator) Next() chunkenc.ValueType { for b.Iterator.Next() == chunkenc.ValFloat { t, _ := b.Iterator.At() - if t < b.minT { + switch { + case t < b.minT: continue - } else if t > b.maxT { + case t > b.maxT: return chunkenc.ValNone + default: + return chunkenc.ValFloat } - return chunkenc.ValFloat } return chunkenc.ValNone } diff --git a/tsdb/head_test.go b/tsdb/head_test.go index 39bcf4c78b..a183e99c09 100644 --- a/tsdb/head_test.go +++ b/tsdb/head_test.go @@ -2960,10 +2960,11 @@ func TestAppendHistogram(t *testing.T) { actHistograms := make([]tsdbutil.Sample, 0, len(expHistograms)) actFloatHistograms := make([]tsdbutil.Sample, 0, len(expFloatHistograms)) for typ := it.Next(); typ != chunkenc.ValNone; typ = it.Next() { - if typ == chunkenc.ValHistogram { + switch typ { + case chunkenc.ValHistogram: ts, h := it.AtHistogram() actHistograms = append(actHistograms, sample{t: ts, h: h}) - } else if typ == chunkenc.ValFloatHistogram { + case chunkenc.ValFloatHistogram: ts, fh := it.AtFloatHistogram() actFloatHistograms = append(actFloatHistograms, sample{t: ts, fh: fh}) } @@ -3565,14 +3566,15 @@ func testHistogramStaleSampleHelper(t *testing.T, floatHistogram bool) { for i, eh := range expHistograms { ah := actHistograms[i] if floatHistogram { - if value.IsStaleNaN(eh.fh.Sum) { + switch { + case value.IsStaleNaN(eh.fh.Sum): actNumStale++ require.True(t, value.IsStaleNaN(ah.fh.Sum)) // To make require.Equal work. ah.fh.Sum = 0 eh.fh = eh.fh.Copy() eh.fh.Sum = 0 - } else if i > 0 { + case i > 0: prev := expHistograms[i-1] if prev.fh == nil || value.IsStaleNaN(prev.fh.Sum) { eh.fh.CounterResetHint = histogram.UnknownCounterReset @@ -3580,14 +3582,15 @@ func testHistogramStaleSampleHelper(t *testing.T, floatHistogram bool) { } require.Equal(t, eh, ah) } else { - if value.IsStaleNaN(eh.h.Sum) { + switch { + case value.IsStaleNaN(eh.h.Sum): actNumStale++ require.True(t, value.IsStaleNaN(ah.h.Sum)) // To make require.Equal work. ah.h.Sum = 0 eh.h = eh.h.Copy() eh.h.Sum = 0 - } else if i > 0 { + case i > 0: prev := expHistograms[i-1] if prev.h == nil || value.IsStaleNaN(prev.h.Sum) { eh.h.CounterResetHint = histogram.UnknownCounterReset @@ -4488,19 +4491,19 @@ func TestHistogramValidation(t *testing.T) { for testName, tc := range tests { t.Run(testName, func(t *testing.T) { - err := ValidateHistogram(tc.h) - if tc.errMsg != "" { + switch err := ValidateHistogram(tc.h); { + case tc.errMsg != "": require.ErrorContains(t, err, tc.errMsg) - } else { + default: require.NoError(t, err) } - err = ValidateFloatHistogram(tc.h.ToFloat()) - if tc.errMsgFloat != "" { + switch err := ValidateFloatHistogram(tc.h.ToFloat()); { + case tc.errMsgFloat != "": require.ErrorContains(t, err, tc.errMsgFloat) - } else if tc.errMsg != "" { + case tc.errMsg != "": require.ErrorContains(t, err, tc.errMsg) - } else { + default: require.NoError(t, err) } }) diff --git a/tsdb/index/postings.go b/tsdb/index/postings.go index 15df374fc5..514775210e 100644 --- a/tsdb/index/postings.go +++ b/tsdb/index/postings.go @@ -565,12 +565,11 @@ func newMergedPostings(p []Postings) (m *mergedPostings, nonEmpty bool) { for _, it := range p { // NOTE: mergedPostings struct requires the user to issue an initial Next. - if it.Next() { + switch { + case it.Next(): ph = append(ph, it) - } else { - if it.Err() != nil { - return &mergedPostings{err: it.Err()}, true - } + case it.Err() != nil: + return &mergedPostings{err: it.Err()}, true } } @@ -704,16 +703,16 @@ func (rp *removedPostings) Next() bool { return true } - fcur, rcur := rp.full.At(), rp.remove.At() - if fcur < rcur { + switch fcur, rcur := rp.full.At(), rp.remove.At(); { + case fcur < rcur: rp.cur = fcur rp.fok = rp.full.Next() return true - } else if rcur < fcur { + case rcur < fcur: // Forward the remove postings to the right position. rp.rok = rp.remove.Seek(fcur) - } else { + default: // Skip the current posting. rp.fok = rp.full.Next() } @@ -848,9 +847,10 @@ func (it *bigEndianPostings) Err() error { func FindIntersectingPostings(p Postings, candidates []Postings) (indexes []int, err error) { h := make(postingsWithIndexHeap, 0, len(candidates)) for idx, it := range candidates { - if it.Next() { + switch { + case it.Next(): h = append(h, postingsWithIndex{index: idx, p: it}) - } else if it.Err() != nil { + case it.Err() != nil: return nil, it.Err() } } diff --git a/tsdb/ooo_head_read.go b/tsdb/ooo_head_read.go index fd16c6ca8f..8ba3ea39af 100644 --- a/tsdb/ooo_head_read.go +++ b/tsdb/ooo_head_read.go @@ -123,7 +123,7 @@ func (oh *OOOHeadIndexReader) series(ref storage.SeriesRef, builder *labels.Scra } } - // There is nothing to do if we did not collect any chunk + // There is nothing to do if we did not collect any chunk. if len(tmpChks) == 0 { return nil } @@ -136,14 +136,15 @@ func (oh *OOOHeadIndexReader) series(ref storage.SeriesRef, builder *labels.Scra // chunks Meta the first chunk that overlaps with others. // Example chunks of a series: 5:(100, 200) 6:(500, 600) 7:(150, 250) 8:(550, 650) // In the example 5 overlaps with 7 and 6 overlaps with 8 so we only want to - // to return chunk Metas for chunk 5 and chunk 6 + // to return chunk Metas for chunk 5 and chunk 6e *chks = append(*chks, tmpChks[0]) - maxTime := tmpChks[0].MaxTime // tracks the maxTime of the previous "to be merged chunk" + maxTime := tmpChks[0].MaxTime // Tracks the maxTime of the previous "to be merged chunk". for _, c := range tmpChks[1:] { - if c.MinTime > maxTime { + switch { + case c.MinTime > maxTime: *chks = append(*chks, c) maxTime = c.MaxTime - } else if c.MaxTime > maxTime { + case c.MaxTime > maxTime: maxTime = c.MaxTime (*chks)[len(*chks)-1].MaxTime = c.MaxTime } diff --git a/tsdb/querier.go b/tsdb/querier.go index f3852d517b..abddebb870 100644 --- a/tsdb/querier.go +++ b/tsdb/querier.go @@ -239,18 +239,20 @@ func PostingsForMatchers(ix IndexReader, ms ...*labels.Matcher) (index.Postings, } for _, m := range ms { - if m.Name == "" && m.Value == "" { // Special-case for AllPostings, used in tests at least. + switch { + case m.Name == "" && m.Value == "": // Special-case for AllPostings, used in tests at least. k, v := index.AllPostingsKey() allPostings, err := ix.Postings(k, v) if err != nil { return nil, err } its = append(its, allPostings) - } else if labelMustBeSet[m.Name] { + case labelMustBeSet[m.Name]: // If this matcher must be non-empty, we can be smarter. matchesEmpty := m.Matches("") isNot := m.Type == labels.MatchNotEqual || m.Type == labels.MatchNotRegexp - if isNot && matchesEmpty { // l!="foo" + switch { + case isNot && matchesEmpty: // l!="foo" // If the label can't be empty and is a Not and the inner matcher // doesn't match empty, then subtract it out at the end. inverse, err := m.Inverse() @@ -263,7 +265,7 @@ func PostingsForMatchers(ix IndexReader, ms ...*labels.Matcher) (index.Postings, return nil, err } notIts = append(notIts, it) - } else if isNot && !matchesEmpty { // l!="" + case isNot && !matchesEmpty: // l!="" // If the label can't be empty and is a Not, but the inner matcher can // be empty we need to use inversePostingsForMatcher. inverse, err := m.Inverse() @@ -279,7 +281,7 @@ func PostingsForMatchers(ix IndexReader, ms ...*labels.Matcher) (index.Postings, return index.EmptyPostings(), nil } its = append(its, it) - } else { // l="a" + default: // l="a" // Non-Not matcher, use normal postingsForMatcher. it, err := postingsForMatcher(ix, m) if err != nil { @@ -290,7 +292,7 @@ func PostingsForMatchers(ix IndexReader, ms ...*labels.Matcher) (index.Postings, } its = append(its, it) } - } else { // l="" + default: // l="" // If the matchers for a labelname selects an empty value, it selects all // the series which don't have the label name set too. See: // https://github.com/prometheus/prometheus/issues/3575 and @@ -966,23 +968,24 @@ func (m *mergedStringIter) Next() bool { return false } - if !m.aok { + switch { + case !m.aok: m.cur = m.b.At() m.bok = m.b.Next() m.err = m.b.Err() - } else if !m.bok { + case !m.bok: m.cur = m.a.At() m.aok = m.a.Next() m.err = m.a.Err() - } else if m.b.At() > m.a.At() { + case m.b.At() > m.a.At(): m.cur = m.a.At() m.aok = m.a.Next() m.err = m.a.Err() - } else if m.a.At() > m.b.At() { + case m.a.At() > m.b.At(): m.cur = m.b.At() m.bok = m.b.Next() m.err = m.b.Err() - } else { // Equal. + default: // Equal. m.cur = m.b.At() m.aok = m.a.Next() m.err = m.a.Err() diff --git a/tsdb/tombstones/tombstones.go b/tsdb/tombstones/tombstones.go index f7e2a2a1e7..a52e1caa97 100644 --- a/tsdb/tombstones/tombstones.go +++ b/tsdb/tombstones/tombstones.go @@ -190,9 +190,10 @@ type Stone struct { func ReadTombstones(dir string) (Reader, int64, error) { b, err := os.ReadFile(filepath.Join(dir, TombstonesFilename)) - if os.IsNotExist(err) { + switch { + case os.IsNotExist(err): return NewMemTombstones(), 0, nil - } else if err != nil { + case err != nil: return nil, 0, err } diff --git a/tsdb/wal.go b/tsdb/wal.go index 93d445a126..0c57865e66 100644 --- a/tsdb/wal.go +++ b/tsdb/wal.go @@ -522,9 +522,10 @@ func (w *SegmentWAL) openSegmentFile(name string) (*os.File, error) { } }() - if n, err := f.Read(metab); err != nil { + switch n, err := f.Read(metab); { + case err != nil: return nil, errors.Wrapf(err, "validate meta %q", f.Name()) - } else if n != 8 { + case n != 8: return nil, errors.Errorf("invalid header size %d in %q", n, f.Name()) } @@ -1063,9 +1064,10 @@ func (r *walReader) entry(cr io.Reader) (WALEntryType, byte, []byte, error) { tr := io.TeeReader(cr, r.crc32) b := make([]byte, 6) - if n, err := tr.Read(b); err != nil { + switch n, err := tr.Read(b); { + case err != nil: return 0, 0, nil, err - } else if n != 6 { + case n != 6: return 0, 0, nil, r.corruptionErr("invalid entry header size %d", n) } @@ -1087,15 +1089,17 @@ func (r *walReader) entry(cr io.Reader) (WALEntryType, byte, []byte, error) { } buf := r.buf[:length] - if n, err := tr.Read(buf); err != nil { + switch n, err := tr.Read(buf); { + case err != nil: return 0, 0, nil, err - } else if n != length { + case n != length: return 0, 0, nil, r.corruptionErr("invalid entry body size %d", n) } - if n, err := cr.Read(b[:4]); err != nil { + switch n, err := cr.Read(b[:4]); { + case err != nil: return 0, 0, nil, err - } else if n != 4 { + case n != 4: return 0, 0, nil, r.corruptionErr("invalid checksum length %d", n) } if exp, has := binary.BigEndian.Uint32(b[:4]), r.crc32.Sum32(); has != exp { diff --git a/tsdb/wlog/live_reader.go b/tsdb/wlog/live_reader.go index 29467aef4a..0ca69093a5 100644 --- a/tsdb/wlog/live_reader.go +++ b/tsdb/wlog/live_reader.go @@ -126,9 +126,10 @@ func (r *LiveReader) Next() bool { // we return EOF and the user can try again later. If we have a full // page, buildRecord is guaranteed to return a record or a non-EOF; it // has checks the records fit in pages. - if ok, err := r.buildRecord(); ok { + switch ok, err := r.buildRecord(); { + case ok: return true - } else if err != nil && err != io.EOF { + case err != nil && err != io.EOF: r.err = err return false } diff --git a/tsdb/wlog/watcher.go b/tsdb/wlog/watcher.go index 72121283d8..b0c17dcbac 100644 --- a/tsdb/wlog/watcher.go +++ b/tsdb/wlog/watcher.go @@ -405,9 +405,10 @@ func (w *Watcher) watch(segmentNum int, tail bool) error { // Ignore errors reading to end of segment whilst replaying the WAL. if !tail { - if err != nil && errors.Cause(err) != io.EOF { + switch { + case err != nil && errors.Cause(err) != io.EOF: level.Warn(w.logger).Log("msg", "Ignoring error reading to end of segment, may have dropped data", "err", err) - } else if reader.Offset() != size { + case reader.Offset() != size: level.Warn(w.logger).Log("msg", "Expected to have read whole segment, may have dropped data", "segment", segmentNum, "read", reader.Offset(), "size", size) } return nil @@ -425,9 +426,10 @@ func (w *Watcher) watch(segmentNum int, tail bool) error { // Ignore all errors reading to end of segment whilst replaying the WAL. if !tail { - if err != nil && errors.Cause(err) != io.EOF { + switch { + case err != nil && errors.Cause(err) != io.EOF: level.Warn(w.logger).Log("msg", "Ignoring error reading to end of segment, may have dropped data", "segment", segmentNum, "err", err) - } else if reader.Offset() != size { + case reader.Offset() != size: level.Warn(w.logger).Log("msg", "Expected to have read whole segment, may have dropped data", "segment", segmentNum, "read", reader.Offset(), "size", size) } return nil diff --git a/util/treecache/treecache.go b/util/treecache/treecache.go index acdd6f7bea..bece9d5c83 100644 --- a/util/treecache/treecache.go +++ b/util/treecache/treecache.go @@ -176,11 +176,11 @@ func (tc *ZookeeperTreeCache) loop(path string) { node = childNode } - err := tc.recursiveNodeUpdate(ev.Path, node) - if err != nil { + switch err := tc.recursiveNodeUpdate(ev.Path, node); { + case err != nil: level.Error(tc.logger).Log("msg", "Error during processing of Zookeeper event", "err", err) failure() - } else if tc.head.data == nil { + case tc.head.data == nil: level.Error(tc.logger).Log("msg", "Error during processing of Zookeeper event", "err", "path no longer exists", "path", tc.prefix) failure() } @@ -214,13 +214,14 @@ func (tc *ZookeeperTreeCache) loop(path string) { func (tc *ZookeeperTreeCache) recursiveNodeUpdate(path string, node *zookeeperTreeCacheNode) error { data, _, dataWatcher, err := tc.conn.GetW(path) - if errors.Is(err, zk.ErrNoNode) { + switch { + case errors.Is(err, zk.ErrNoNode): tc.recursiveDelete(path, node) if node == tc.head { return fmt.Errorf("path %s does not exist", path) } return nil - } else if err != nil { + case err != nil: return err } @@ -230,10 +231,11 @@ func (tc *ZookeeperTreeCache) recursiveNodeUpdate(path string, node *zookeeperTr } children, _, childWatcher, err := tc.conn.ChildrenW(path) - if errors.Is(err, zk.ErrNoNode) { + switch { + case errors.Is(err, zk.ErrNoNode): tc.recursiveDelete(path, node) return nil - } else if err != nil { + case err != nil: return err } diff --git a/web/api/v1/api.go b/web/api/v1/api.go index 0624cf2d8b..f4d6d27da1 100644 --- a/web/api/v1/api.go +++ b/web/api/v1/api.go @@ -989,12 +989,14 @@ func (api *API) targets(r *http.Request) apiFuncResult { ScrapeURL: target.URL().String(), GlobalURL: globalURL.String(), LastError: func() string { - if err == nil && lastErrStr == "" { + switch { + case err == nil && lastErrStr == "": return "" - } else if err != nil { + case err != nil: return errors.Wrapf(err, lastErrStr).Error() + default: + return lastErrStr } - return lastErrStr }(), LastScrape: target.LastScrape(), LastScrapeDuration: target.LastScrapeDuration().Seconds(), diff --git a/web/federate_test.go b/web/federate_test.go index 76d4b9cf67..61ef62f46d 100644 --- a/web/federate_test.go +++ b/web/federate_test.go @@ -388,13 +388,13 @@ func TestFederationWithNativeHistograms(t *testing.T) { break } require.NoError(t, err) - if et == textparse.EntryHelp { - metricFamilies++ - } if et == textparse.EntryHistogram || et == textparse.EntrySeries { p.Metric(&l) } - if et == textparse.EntryHistogram { + switch et { + case textparse.EntryHelp: + metricFamilies++ + case textparse.EntryHistogram: _, parsedTimestamp, h, fh := p.Histogram() require.Nil(t, h) actVec = append(actVec, promql.Sample{ @@ -402,7 +402,7 @@ func TestFederationWithNativeHistograms(t *testing.T) { H: fh, Metric: l, }) - } else if et == textparse.EntrySeries { + case textparse.EntrySeries: _, parsedTimestamp, f := p.Series() actVec = append(actVec, promql.Sample{ T: *parsedTimestamp,