73 lines
1.7 KiB
C#
73 lines
1.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using LeafWeb.Core.Entities;
|
|
using MathNet.Numerics;
|
|
|
|
namespace LeafWeb.Core.Utility
|
|
{
|
|
public class TimeInProgressEstimater
|
|
{
|
|
private readonly double[] _xData;
|
|
private readonly double[] _yData;
|
|
|
|
public TimeInProgressEstimater(IEnumerable<ILeafInput> leafInputs)
|
|
{
|
|
var xData = new List<double>();
|
|
var yData = new List<double>();
|
|
foreach (var leafInput in leafInputs)
|
|
{
|
|
xData.Add(leafInput.InputFiles.Count);
|
|
yData.Add(ConvertFromTimeSpan(leafInput.TimeInProgress));
|
|
}
|
|
_xData = xData.ToArray();
|
|
_yData = yData.ToArray();
|
|
}
|
|
|
|
private static Func<double, double> Positivize => i => i <= 0 ? 1 : i;
|
|
|
|
private IEnumerable<double> Div => _xData.Zip(_yData, (x, y) => y/x);
|
|
|
|
private Func<double, double> AverageFitFunc => i => Div.Average()*i;
|
|
|
|
private Func<double, double> LineFitFunc => Fit.LineFunc(_xData, _yData);
|
|
|
|
private Func<double, double> FitFunc => i => (Positivize(LineFitFunc(i)) + AverageFitFunc(i))/2;
|
|
|
|
public TimeSpan EstimateTimeInProgress(ILeafInput leafInput)
|
|
{
|
|
return EstimateTimeInProgress(leafInput.InputFiles.Count);
|
|
}
|
|
|
|
public TimeSpan EstimateTimeInProgress(int inputFileCount)
|
|
{
|
|
var estimate = FitFunc(inputFileCount);
|
|
if (estimate <= 0)
|
|
estimate = 1;
|
|
return ConvertToTimeSpan(estimate);
|
|
}
|
|
|
|
private static double ConvertFromTimeSpan(TimeSpan timeSpan)
|
|
{
|
|
return timeSpan.TotalSeconds;
|
|
}
|
|
|
|
private static TimeSpan ConvertToTimeSpan(double estimate)
|
|
{
|
|
return TimeSpan.FromSeconds(ConvertToInt32Guarded(estimate));
|
|
}
|
|
|
|
private static Func<double, int> ConvertToInt32Guarded => d =>
|
|
{
|
|
try
|
|
{
|
|
return Convert.ToInt32(d);
|
|
}
|
|
catch (OverflowException)
|
|
{
|
|
return int.MaxValue;
|
|
}
|
|
};
|
|
}
|
|
}
|