167 lines
3.9 KiB
Go
167 lines
3.9 KiB
Go
package stats
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/omniscale/imposm3/logging"
|
|
"time"
|
|
)
|
|
|
|
type Counter struct {
|
|
start time.Time
|
|
Coords *RpsCounter
|
|
Nodes *RpsCounter
|
|
Ways *RpsCounter
|
|
Relations *RpsCounter
|
|
}
|
|
|
|
func (c *Counter) Tick() {
|
|
c.Coords.Tick()
|
|
c.Nodes.Tick()
|
|
c.Ways.Tick()
|
|
c.Relations.Tick()
|
|
}
|
|
|
|
func NewCounter() *Counter {
|
|
return &Counter{
|
|
start: time.Now(),
|
|
Coords: NewRpsCounter(),
|
|
Nodes: NewRpsCounter(),
|
|
Ways: NewRpsCounter(),
|
|
Relations: NewRpsCounter(),
|
|
}
|
|
}
|
|
|
|
func NewCounterWithEstimate(counts ElementCounts) *Counter {
|
|
counter := NewCounter()
|
|
counter.Coords.total = counts.Coords.Current
|
|
counter.Nodes.total = counts.Nodes.Current
|
|
counter.Ways.total = counts.Ways.Current
|
|
counter.Relations.total = counts.Relations.Current
|
|
return counter
|
|
}
|
|
|
|
type ElementCounts struct {
|
|
Coords, Nodes, Ways, Relations ElementCount
|
|
}
|
|
|
|
// Duration returns the duration since start with seconds precission.
|
|
func (c *Counter) CurrentCount() *ElementCounts {
|
|
return &ElementCounts{
|
|
Coords: c.Coords.Count(),
|
|
Nodes: c.Nodes.Count(),
|
|
Ways: c.Ways.Count(),
|
|
Relations: c.Relations.Count(),
|
|
}
|
|
}
|
|
|
|
// Duration returns the duration since start with seconds precission.
|
|
func (c *Counter) Duration() time.Duration {
|
|
return time.Duration(int64(time.Since(c.start).Seconds()) * 1000 * 1000 * 1000)
|
|
}
|
|
|
|
type Statistics struct {
|
|
counter *Counter
|
|
done chan bool
|
|
}
|
|
|
|
const (
|
|
RESET = iota
|
|
START
|
|
STOP
|
|
QUIT
|
|
)
|
|
|
|
func (s *Statistics) AddCoords(n int) { s.counter.Coords.Add(n) }
|
|
func (s *Statistics) AddNodes(n int) { s.counter.Nodes.Add(n) }
|
|
func (s *Statistics) AddWays(n int) { s.counter.Ways.Add(n) }
|
|
func (s *Statistics) AddRelations(n int) { s.counter.Relations.Add(n) }
|
|
func (s *Statistics) Stop() *ElementCounts {
|
|
s.done <- true
|
|
return s.counter.CurrentCount()
|
|
}
|
|
|
|
func NewStatsReporter() *Statistics {
|
|
s := Statistics{}
|
|
s.counter = NewCounter()
|
|
s.done = make(chan bool)
|
|
|
|
go s.loop()
|
|
return &s
|
|
}
|
|
|
|
func NewStatsReporterWithEstimate(counts *ElementCounts) *Statistics {
|
|
s := Statistics{}
|
|
if counts != nil {
|
|
s.counter = NewCounterWithEstimate(*counts)
|
|
} else {
|
|
s.counter = NewCounter()
|
|
}
|
|
s.done = make(chan bool)
|
|
|
|
go s.loop()
|
|
return &s
|
|
}
|
|
|
|
func (s *Statistics) loop() {
|
|
tick := time.NewTicker(500 * time.Millisecond)
|
|
tock := time.NewTicker(time.Minute)
|
|
for {
|
|
select {
|
|
case <-s.done:
|
|
tick.Stop()
|
|
tock.Stop()
|
|
s.counter.PrintStats()
|
|
return
|
|
case <-tock.C:
|
|
s.counter.PrintStats()
|
|
case <-tick.C:
|
|
s.counter.PrintTick()
|
|
s.counter.Tick()
|
|
}
|
|
}
|
|
}
|
|
|
|
func fmtPercentOrVal(progress float64, value int64) string {
|
|
if progress == -1.0 {
|
|
return fmt.Sprintf("%d", value)
|
|
}
|
|
return fmt.Sprintf("%4.1f%%", progress*100)
|
|
}
|
|
|
|
func roundInt(val float64, round int) int64 {
|
|
return int64(val/float64(round)) * int64(round)
|
|
}
|
|
|
|
func (c *Counter) PrintTick() {
|
|
logging.Progress(
|
|
fmt.Sprintf("[%6s] C: %7d/s %7d/s (%s) N: %7d/s %7d/s (%s) W: %7d/s %7d/s (%s) R: %6d/s %6d/s (%s)",
|
|
c.Duration(),
|
|
roundInt(c.Coords.Rps(), 1000),
|
|
roundInt(c.Coords.LastRps(), 1000),
|
|
fmtPercentOrVal(c.Coords.Progress(), c.Coords.Value()),
|
|
roundInt(c.Nodes.Rps(), 100),
|
|
roundInt(c.Nodes.LastRps(), 100),
|
|
fmtPercentOrVal(c.Nodes.Progress(), c.Nodes.Value()),
|
|
roundInt(c.Ways.Rps(), 100),
|
|
roundInt(c.Ways.LastRps(), 100),
|
|
fmtPercentOrVal(c.Ways.Progress(), c.Ways.Value()),
|
|
roundInt(c.Relations.Rps(), 10),
|
|
roundInt(c.Relations.LastRps(), 10),
|
|
fmtPercentOrVal(c.Relations.Progress(), c.Relations.Value()),
|
|
))
|
|
}
|
|
|
|
func (c *Counter) PrintStats() {
|
|
logging.Infof("[%6s] C: %7d/s (%s) N: %7d/s (%s) W: %7d/s (%s) R: %6d/s (%s)",
|
|
c.Duration(),
|
|
roundInt(c.Coords.Rps(), 1000),
|
|
fmtPercentOrVal(c.Coords.Progress(), c.Coords.Value()),
|
|
roundInt(c.Nodes.Rps(), 100),
|
|
fmtPercentOrVal(c.Nodes.Progress(), c.Nodes.Value()),
|
|
roundInt(c.Ways.Rps(), 100),
|
|
fmtPercentOrVal(c.Ways.Progress(), c.Ways.Value()),
|
|
roundInt(c.Relations.Rps(), 10),
|
|
fmtPercentOrVal(c.Relations.Progress(), c.Relations.Value()),
|
|
)
|
|
}
|