Files
LeafWeb/Core/Utility/TimeInProgressEstimater.cs
2017-02-07 12:02:22 -05:00

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;
}
};
}
}