metrics: Fix --templateMetricsHints

Also improve non-string comparisons.

Fixes #7048
This commit is contained in:
Bjørn Erik Pedersen 2020-03-12 17:09:49 +01:00
parent 18cb21ff2e
commit 5eadc4c0a8
3 changed files with 85 additions and 10 deletions

View file

@ -15,6 +15,12 @@
package metrics
import (
"reflect"
"github.com/gohugoio/hugo/helpers"
"github.com/gohugoio/hugo/common/types"
"fmt"
"io"
"math"
@ -25,8 +31,6 @@ import (
"time"
"github.com/gohugoio/hugo/compare"
"github.com/gohugoio/hugo/common/hreflect"
)
// The Provider interface defines an interface for measuring metrics.
@ -51,15 +55,17 @@ type diff struct {
simSum int
}
var counter = 0
func (d *diff) add(v interface{}) *diff {
if !hreflect.IsTruthful(v) {
if types.IsNil(d.baseline) {
d.baseline = v
d.count = 1
d.simSum = 100 // If we get only one it is very cache friendly.
return d
}
d.simSum += howSimilar(v, d.baseline)
adder := howSimilar(v, d.baseline)
d.simSum += adder
d.count++
return d
@ -113,6 +119,7 @@ func (s *Store) TrackValue(key string, value interface{}) {
}
d.add(value)
s.diffmu.Unlock()
}
@ -135,6 +142,7 @@ func (s *Store) WriteMetrics(w io.Writer) {
var max time.Duration
diff, found := s.diffs[k]
cacheFactor := 0
if found {
cacheFactor = int(math.Floor(float64(diff.simSum) / float64(diff.count)))
@ -196,11 +204,19 @@ func (b bySum) Less(i, j int) bool { return b[i].sum > b[j].sum }
// howSimilar is a naive diff implementation that returns
// a number between 0-100 indicating how similar a and b are.
func howSimilar(a, b interface{}) int {
// TODO(bep) object equality fast path, but remember that
// we can get anytning in here.
t1, t2 := reflect.TypeOf(a), reflect.TypeOf(b)
if t1 != t2 {
return 0
}
as, ok1 := a.(string)
bs, ok2 := b.(string)
if t1.Comparable() && t2.Comparable() {
if a == b {
return 100
}
}
as, ok1 := types.TypeToString(a)
bs, ok2 := types.TypeToString(b)
if ok1 && ok2 {
return howSimilarStrings(as, bs)
@ -222,13 +238,21 @@ func howSimilar(a, b interface{}) int {
return 90
}
h1, h2 := helpers.HashString(a), helpers.HashString(b)
if h1 == h2 {
return 100
}
return 0
}
// howSimilar is a naive diff implementation that returns
// a number between 0-100 indicating how similar a and b are.
// 100 is when all words in a also exists in b.
func howSimilarStrings(a, b string) int {
if a == b {
return 100
}
// Give some weight to the word positions.
const partitionSize = 4