103 lines
2.6 KiB
Go

package solver
import (
"strconv"
"time"
)
// Keep track and output progress.
// Calculate rates, display percentages, estimate the ETA till completion.
func (solver *Solver) Tracker() {
// Add time tracking
defer solver.timeTrack(time.Now(), "Validated solutions")
solver.Outp.Println("Validating solutions")
// Determine if the main-loop is done
var done bool
// Tracking progress in percentages
var percentage float32
// Tracking progress in validated solutions
var track int
// Tracking the rate, starting point
var rateStart uint64
// Tracking the rate, difference between previous iterations
var rateDiff uint64
// Tracking duration
var timerStart = time.Now()
// Estimation how long it will take
var est_fin string
// While not needed for rateDiff anymore, it makes estimation calculations more accurate. ☹️
time.Sleep(time.Second)
// for solver.Iter != solver.counter { // Start for-loop
for !done {
// Determine how far we are.
percentage = (float32(solver.counter.Load()) / (float32(solver.Iter) / 100))
// Reset the loop
rateDiff = solver.counter.Load() - rateStart
if track <= int(percentage) || rateDiff == 0 { // Start if-statement
// Make sure something happened, making rateStart the only reliable variable
if solver.Iter == solver.counter.Load() {
percentage = 100
solver.counter.Store(solver.Iter)
done = true
}
timer_elapsed := time.Since(timerStart)
solver.rates = append(solver.rates, rateDiff)
rate_avg := solver.calcAVG()
// Estimate when this is finished
if rateDiff == 0 {
est_fin = "N/A"
} else {
duration_int := (solver.Iter - solver.counter.Load()) / rate_avg
duration_string := strconv.Itoa(int(duration_int)) + "s"
est, err := time.ParseDuration(duration_string)
if err != nil {
est_fin = "parse error"
} else {
est_fin = est.String()
}
}
// Printing the progress
solver.Outp.Println("Processing: " + strconv.Itoa(int(percentage)) + "% (" + strconv.FormatUint(solver.counter.Load(), 10) + "/" + strconv.Itoa(int(solver.Iter)) + "); Rate: " + strconv.FormatUint(rateDiff, 10) + "/sec for " + timer_elapsed.String() + "; Time left (est.): " + est_fin)
// After we are done printing, exit this for-loop
if percentage == 100 {
break
}
// Wrap up the loop or break
if int(percentage) > track {
track = int(percentage)
} else {
track = track + 1
}
timerStart = time.Now()
}
// Resert the rate counter
rateStart = solver.counter.Load()
// Sleep for a second
if solver.Iter != solver.counter.Load() {
time.Sleep(1 * time.Second)
}
} // End for-loop
}