Weighted Shortest Job First Hub
This commit is contained in:
@ -1,38 +1,192 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Adaptation.FileHandlers.Priority;
|
||||
|
||||
#nullable enable
|
||||
|
||||
public class Aggregation
|
||||
{
|
||||
|
||||
[JsonConstructor]
|
||||
public Aggregation(
|
||||
string average,
|
||||
int count,
|
||||
int? inverse,
|
||||
int maximum,
|
||||
int minimum,
|
||||
ReadOnlyCollection<Record> records,
|
||||
int sum
|
||||
)
|
||||
public Aggregation(double inverseAverage,
|
||||
int valueCount,
|
||||
double fibonacciAverage,
|
||||
int? inverseValue,
|
||||
int valueMaximum,
|
||||
int valueMinimum,
|
||||
Notification[] notifications,
|
||||
int valueSum)
|
||||
{
|
||||
Average = average;
|
||||
Count = count;
|
||||
Inverse = inverse;
|
||||
Maximum = maximum;
|
||||
Minimum = minimum;
|
||||
Records = records;
|
||||
Sum = sum;
|
||||
InverseAverage = inverseAverage;
|
||||
ValueCount = valueCount;
|
||||
FibonacciAverage = fibonacciAverage;
|
||||
InverseValue = inverseValue;
|
||||
ValueMaximum = valueMaximum;
|
||||
ValueMinimum = valueMinimum;
|
||||
Notifications = notifications;
|
||||
ValueSum = valueSum;
|
||||
}
|
||||
|
||||
[JsonPropertyName("Average")] public string Average { get; }
|
||||
[JsonPropertyName("Count")] public int Count { get; }
|
||||
[JsonPropertyName("Inverse")] public int? Inverse { get; }
|
||||
[JsonPropertyName("Maximum")] public int Maximum { get; }
|
||||
[JsonPropertyName("Minimum")] public int Minimum { get; }
|
||||
[JsonPropertyName("Records")] public ReadOnlyCollection<Record> Records { get; }
|
||||
[JsonPropertyName("Sum")] public int Sum { get; }
|
||||
public double InverseAverage { get; } // [JsonPropertyName("InverseAverage")]
|
||||
public int ValueCount { get; } // [JsonPropertyName("ValueCount")]
|
||||
public double FibonacciAverage { get; } // [JsonPropertyName("Fibonacci")]
|
||||
public int? InverseValue { get; } // [JsonPropertyName("InverseValue")]
|
||||
public int ValueMaximum { get; } // [JsonPropertyName("ValueMaximum")]
|
||||
public int ValueMinimum { get; } // [JsonPropertyName("ValueMinimum")]
|
||||
public Notification[] Notifications { get; } // [JsonPropertyName("Notifications")]
|
||||
public int ValueSum { get; } // [JsonPropertyName("ValueSum")]
|
||||
|
||||
private static ReadOnlyDictionary<int, Aggregation> GetKeyValuePairs(Settings settings, Dictionary<int, List<Notification>> keyValuePairs)
|
||||
{
|
||||
Dictionary<int, Aggregation> results = new();
|
||||
int? inverseValue;
|
||||
double inverseAverage;
|
||||
Aggregation aggregation;
|
||||
double fibonacciAverage;
|
||||
List<int> collection = new();
|
||||
int averageFromInverseCeiling;
|
||||
List<int> inverseCollection = new();
|
||||
List<int> fibonacciCollection = new();
|
||||
foreach (KeyValuePair<int, List<Notification>> keyValuePair in keyValuePairs)
|
||||
{
|
||||
collection.Clear();
|
||||
inverseCollection.Clear();
|
||||
fibonacciCollection.Clear();
|
||||
foreach (Notification notification in keyValuePair.Value)
|
||||
{
|
||||
collection.Add(notification.Value);
|
||||
if (notification.Inverse is null)
|
||||
continue;
|
||||
inverseCollection.Add(notification.Inverse.Value);
|
||||
if (notification.Fibonacci is null)
|
||||
continue;
|
||||
fibonacciCollection.Add(notification.Fibonacci.Value);
|
||||
}
|
||||
if (inverseCollection.Count == 0 || fibonacciCollection.Count == 0)
|
||||
continue;
|
||||
inverseAverage = Math.Round(inverseCollection.Average(), settings.Digits);
|
||||
averageFromInverseCeiling = (int)Math.Ceiling(inverseAverage);
|
||||
inverseValue = Notification.GetInverse(averageFromInverseCeiling);
|
||||
fibonacciAverage = Math.Round(fibonacciCollection.Average(), settings.Digits);
|
||||
aggregation = new(inverseAverage: inverseAverage,
|
||||
valueCount: collection.Count,
|
||||
fibonacciAverage: fibonacciAverage,
|
||||
inverseValue: inverseValue,
|
||||
valueMaximum: collection.Max(),
|
||||
valueMinimum: collection.Min(),
|
||||
notifications: keyValuePair.Value.ToArray(),
|
||||
valueSum: collection.Sum());
|
||||
results.Add(keyValuePair.Key, aggregation);
|
||||
}
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Notification> GetNotifications(Settings settings, string directory)
|
||||
{
|
||||
List<Notification> results = new();
|
||||
string text;
|
||||
string[] files;
|
||||
Notification? notification;
|
||||
List<Notification>? collection;
|
||||
Dictionary<string, List<Notification>> keyValuePairs = new();
|
||||
string[] directories = Directory.GetDirectories(directory, "*", SearchOption.TopDirectoryOnly);
|
||||
foreach (string subDirectory in directories)
|
||||
{
|
||||
keyValuePairs.Clear();
|
||||
files = Directory.GetFiles(subDirectory, settings.SourceFileFilter, SearchOption.TopDirectoryOnly);
|
||||
foreach (string file in files)
|
||||
{
|
||||
text = File.ReadAllText(file);
|
||||
if (string.IsNullOrEmpty(text) || text[0] == '[')
|
||||
continue;
|
||||
notification = JsonSerializer.Deserialize(text, NotificationSourceGenerationContext.Default.Notification);
|
||||
if (notification is null || notification.Id == 0)
|
||||
continue;
|
||||
if (string.IsNullOrEmpty(notification.RemoteIpAddress))
|
||||
continue;
|
||||
if (!keyValuePairs.TryGetValue(notification.RemoteIpAddress, out collection))
|
||||
{
|
||||
keyValuePairs.Add(notification.RemoteIpAddress, new());
|
||||
if (!keyValuePairs.TryGetValue(notification.RemoteIpAddress, out collection))
|
||||
throw new Exception();
|
||||
}
|
||||
collection.Add(notification);
|
||||
}
|
||||
foreach (KeyValuePair<string, List<Notification>> keyValuePair in keyValuePairs)
|
||||
{
|
||||
if (keyValuePair.Value.Count == 1)
|
||||
results.Add(keyValuePair.Value[0]);
|
||||
else
|
||||
{
|
||||
notification = keyValuePair.Value.Select(record => new KeyValuePair<long, Notification>(record.Time, record)).OrderBy(pair => pair.Key).Last().Value;
|
||||
results.Add(notification);
|
||||
}
|
||||
}
|
||||
}
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static ReadOnlyDictionary<int, Aggregation> GetKeyValuePairs(Settings settings, string directory)
|
||||
{
|
||||
ReadOnlyDictionary<int, Aggregation> results;
|
||||
List<Notification>? collection;
|
||||
Dictionary<int, List<Notification>> keyValuePairs = new();
|
||||
ReadOnlyCollection<Notification> notifications = GetNotifications(settings, directory);
|
||||
foreach (Notification notification in notifications)
|
||||
{
|
||||
if (!keyValuePairs.TryGetValue(notification.Id, out collection))
|
||||
{
|
||||
keyValuePairs.Add(notification.Id, new());
|
||||
if (!keyValuePairs.TryGetValue(notification.Id, out collection))
|
||||
throw new Exception();
|
||||
}
|
||||
collection.Add(notification);
|
||||
}
|
||||
results = GetKeyValuePairs(settings, keyValuePairs);
|
||||
return results;
|
||||
}
|
||||
|
||||
internal static ReadOnlyDictionary<string, ReadOnlyDictionary<int, Aggregation>> GetKeyValuePairsAndWriteFiles(Settings settings)
|
||||
{
|
||||
Dictionary<string, ReadOnlyDictionary<int, Aggregation>> results = new();
|
||||
string json;
|
||||
string jsonOld;
|
||||
string jsonFile;
|
||||
string directoryName;
|
||||
ReadOnlyDictionary<int, Aggregation> keyValuePairs;
|
||||
if (!Directory.Exists(settings.SourceFileLocation))
|
||||
_ = Directory.CreateDirectory(settings.SourceFileLocation);
|
||||
if (!Directory.Exists(settings.TargetFileLocation))
|
||||
_ = Directory.CreateDirectory(settings.TargetFileLocation);
|
||||
string[] directories = Directory.GetDirectories(settings.SourceFileLocation, "*", SearchOption.TopDirectoryOnly);
|
||||
foreach (string directory in directories)
|
||||
{
|
||||
directoryName = Path.GetFileName(directory);
|
||||
keyValuePairs = GetKeyValuePairs(settings, directory);
|
||||
jsonFile = Path.Combine(settings.TargetFileLocation, $"{directoryName}.json");
|
||||
json = JsonSerializer.Serialize(keyValuePairs, AggregationReadOnlyDictionarySourceGenerationContext.Default.ReadOnlyDictionaryInt32Aggregation);
|
||||
// keyValuePairs = JsonSerializer.Deserialize(json, AggregationReadOnlyDictionarySourceGenerationContext.Default.ReadOnlyDictionaryInt32Aggregation);
|
||||
jsonOld = File.Exists(jsonFile) ? File.ReadAllText(jsonFile) : string.Empty;
|
||||
if (json != jsonOld)
|
||||
File.WriteAllText(jsonFile, json);
|
||||
results.Add(directoryName, keyValuePairs);
|
||||
}
|
||||
return new(results);
|
||||
}
|
||||
|
||||
internal static ReadOnlyDictionary<int, Aggregation> GetKeyValuePairs(Settings settings, Notification notification)
|
||||
{
|
||||
ReadOnlyDictionary<int, Aggregation> results;
|
||||
Dictionary<int, List<Notification>> keyValuePairs = new() { { notification.Id, new Notification[] { notification }.ToList() } };
|
||||
results = GetKeyValuePairs(settings, keyValuePairs);
|
||||
return results;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -46,4 +200,10 @@ internal partial class AggregationSourceGenerationContext : JsonSerializerContex
|
||||
[JsonSerializable(typeof(Aggregation[]))]
|
||||
internal partial class AggregationCollectionSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(ReadOnlyDictionary<int, Aggregation>))]
|
||||
internal partial class AggregationReadOnlyDictionarySourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
Reference in New Issue
Block a user