diff --git a/csharp/InnovEnergy.props b/csharp/InnovEnergy.props index c6c92bd2a..5a4943931 100644 --- a/csharp/InnovEnergy.props +++ b/csharp/InnovEnergy.props @@ -9,7 +9,7 @@ net6.0 true false - $(Company).$(MSBuildProjectDirectory.Replace($(SolutionDir), "").Replace("lib/", "Lib/").Replace("app/", "App/").Replace("src/", "").Replace("/",".")) + $(Company).$(MSBuildProjectDirectory.Replace($(SolutionDir), "").Replace("src/", "").Replace("/",".")) $(Company) Team diff --git a/csharp/InnovEnergy.sln b/csharp/InnovEnergy.sln index 70c4b2f57..88f01a87d 100644 --- a/csharp/InnovEnergy.sln +++ b/csharp/InnovEnergy.sln @@ -20,10 +20,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "App", "App", "{145597B4-3E3 EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Lib", "Lib", "{AD5B98A8-AB7F-4DA2-B66D-5B4E63E7D854}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "S3", "Lib/S3/S3.csproj", "{C3639841-13F4-4F24-99C6-7D965593BF89}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "deprecated", "deprecated", "{46DE03C4-52D1-47AA-8E60-8BB15361D723}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SaliMax", "App/SaliMax/SaliMax.csproj", "{25073794-D859-4824-9984-194C7E928496}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StatusApi", "Lib/StatusApi/StatusApi.csproj", "{9D17E78C-8A70-43DB-A619-DC12D20D023D}" @@ -106,10 +102,6 @@ Global {40B45363-BE34-420B-8F87-775EE6EE3513}.Debug|Any CPU.Build.0 = Debug|Any CPU {40B45363-BE34-420B-8F87-775EE6EE3513}.Release|Any CPU.ActiveCfg = Release|Any CPU {40B45363-BE34-420B-8F87-775EE6EE3513}.Release|Any CPU.Build.0 = Release|Any CPU - {C3639841-13F4-4F24-99C6-7D965593BF89}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C3639841-13F4-4F24-99C6-7D965593BF89}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C3639841-13F4-4F24-99C6-7D965593BF89}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C3639841-13F4-4F24-99C6-7D965593BF89}.Release|Any CPU.Build.0 = Release|Any CPU {25073794-D859-4824-9984-194C7E928496}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {25073794-D859-4824-9984-194C7E928496}.Debug|Any CPU.Build.0 = Debug|Any CPU {25073794-D859-4824-9984-194C7E928496}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -187,11 +179,8 @@ Global {B2627B9F-41DF-44F7-A0D1-CA71FF4A007A} = {AD5B98A8-AB7F-4DA2-B66D-5B4E63E7D854} {F65F33B0-3522-4008-8D1E-47EF8E4C7AC7} = {145597B4-3E30-45E6-9F72-4DD43194539A} {E3A5F3A3-72A5-47CC-85C6-2D8E962A0EC1} = {145597B4-3E30-45E6-9F72-4DD43194539A} - {46DE03C4-52D1-47AA-8E60-8BB15361D723} = {AD5B98A8-AB7F-4DA2-B66D-5B4E63E7D854} - {4A67D79F-F0C9-4BBC-9601-D5948E6C05D3} = {46DE03C4-52D1-47AA-8E60-8BB15361D723} {25073794-D859-4824-9984-194C7E928496} = {145597B4-3E30-45E6-9F72-4DD43194539A} {9D17E78C-8A70-43DB-A619-DC12D20D023D} = {AD5B98A8-AB7F-4DA2-B66D-5B4E63E7D854} - {C3639841-13F4-4F24-99C6-7D965593BF89} = {46DE03C4-52D1-47AA-8E60-8BB15361D723} {4931A385-24DC-4E78-BFF4-356F8D6D5183} = {AD5B98A8-AB7F-4DA2-B66D-5B4E63E7D854} {794FD07C-93E9-4803-982E-1CA261504AB5} = {AD5B98A8-AB7F-4DA2-B66D-5B4E63E7D854} {BD8CBC5C-0B9E-48A3-BC4E-725E3FAB2348} = {AD5B98A8-AB7F-4DA2-B66D-5B4E63E7D854} @@ -211,5 +200,6 @@ Global {AF7E8DCA-8D48-498E-AB3D-208061B244DC} = {AD5B98A8-AB7F-4DA2-B66D-5B4E63E7D854} {A56F58C2-B265-435B-A985-53B4D6F49B1A} = {145597B4-3E30-45E6-9F72-4DD43194539A} {C04FB6DA-23C6-46BB-9B21-8F4FBA32FFF7} = {AD5B98A8-AB7F-4DA2-B66D-5B4E63E7D854} + {4A67D79F-F0C9-4BBC-9601-D5948E6C05D3} = {AD5B98A8-AB7F-4DA2-B66D-5B4E63E7D854} EndGlobalSection EndGlobal diff --git a/csharp/Lib/S3/DataRec.cs b/csharp/Lib/S3/DataRec.cs deleted file mode 100644 index 5ae585689..000000000 --- a/csharp/Lib/S3/DataRec.cs +++ /dev/null @@ -1,11 +0,0 @@ -using InnovEnergy.Lib.S3.Records.Fields; - -namespace InnovEnergy.Lib.S3; - -public record DataRec -{ - [Unit("V")] public Double Voltage { get; init; } - [Unit("A")] public Double Current { get; init; } - public Boolean Error { get; init; } - public String State { get; init; } -} \ No newline at end of file diff --git a/csharp/Lib/S3/Drivers/Internal/Delegates/ReadRecord.cs b/csharp/Lib/S3/Drivers/Internal/Delegates/ReadRecord.cs deleted file mode 100644 index ad088d513..000000000 --- a/csharp/Lib/S3/Drivers/Internal/Delegates/ReadRecord.cs +++ /dev/null @@ -1,6 +0,0 @@ -using InnovEnergy.Lib.S3.Metadata; -using InnovEnergy.Lib.S3.Records.Specialized; - -namespace InnovEnergy.Lib.S3.Drivers.Internal.Delegates; - -public delegate Task ReadRecord(AggregationLevel level, UInt32 index); \ No newline at end of file diff --git a/csharp/Lib/S3/Drivers/Internal/Delegates/WriteRecord.cs b/csharp/Lib/S3/Drivers/Internal/Delegates/WriteRecord.cs deleted file mode 100644 index 4bccde97d..000000000 --- a/csharp/Lib/S3/Drivers/Internal/Delegates/WriteRecord.cs +++ /dev/null @@ -1,6 +0,0 @@ -using InnovEnergy.Lib.S3.Metadata; -using InnovEnergy.Lib.S3.Records.Specialized; - -namespace InnovEnergy.Lib.S3.Drivers.Internal.Delegates; - -public delegate Task WriteRecord(TimeStampedRecord record, AggregationLevel level, UInt32 index); \ No newline at end of file diff --git a/csharp/Lib/S3/Drivers/Internal/Reader.cs b/csharp/Lib/S3/Drivers/Internal/Reader.cs deleted file mode 100644 index e5ba5c59e..000000000 --- a/csharp/Lib/S3/Drivers/Internal/Reader.cs +++ /dev/null @@ -1,50 +0,0 @@ -using InnovEnergy.Lib.S3.Drivers.Internal.Delegates; -using InnovEnergy.Lib.S3.Metadata; -using InnovEnergy.Lib.S3.Records.Specialized; -using InnovEnergy.Lib.Time.Unix; -using InnovEnergy.Lib.Utils; - -namespace InnovEnergy.Lib.S3.Drivers.Internal; - -public partial class Reader -{ - public IReadOnlyList AggregationLevels { get; } - public UnixTimeSpan SamplePeriod => AggregationLevels[0].SamplePeriod; - - private readonly ReadRecord _ReadRecord; - - internal Reader(IReadOnlyList levels, ReadRecord readRecord) - { - _ReadRecord = readRecord; - AggregationLevels = InitLevels(levels); - } - - public Task ReadRecord(AggregationLevel level, UInt32 index) - { - return _ReadRecord(level, index); - } - - private static IReadOnlyList InitLevels(IReadOnlyList levels) - { - if (!levels.Any()) - throw new ArgumentOutOfRangeException(nameof(levels)); - - levels = levels - .OrderBy(l => l.SamplePeriod.Ticks) - .ToReadOnlyList(levels.Count); - - var pairwise = levels - .Select(l => l.SamplePeriod) - .Pairwise() - .ToReadOnlyList(levels.Count - 1); - - var greater = pairwise.Any(ls => ls.right <= ls.left); - var multiple = pairwise.Any(ls => ls.right % ls.left != 0 ); - var retention = levels .Any(l => l.RetentionPeriod % l.SamplePeriod != 0); - - if (greater || multiple || retention) - throw new ArgumentException(nameof(levels)); // TODO: error messages - - return levels; - } -} \ No newline at end of file diff --git a/csharp/Lib/S3/Drivers/Internal/Reader.public.cs b/csharp/Lib/S3/Drivers/Internal/Reader.public.cs deleted file mode 100644 index 424b3ccfe..000000000 --- a/csharp/Lib/S3/Drivers/Internal/Reader.public.cs +++ /dev/null @@ -1,37 +0,0 @@ -using InnovEnergy.Lib.S3.Metadata; -using InnovEnergy.Lib.S3.Records.Specialized; -using InnovEnergy.Lib.Time.Unix; -using InnovEnergy.Lib.Utils; - -namespace InnovEnergy.Lib.S3.Drivers.Internal; - -public partial class Reader -{ - public Task> ReadRecords(UnixTime from, UnixTime to, Int32 minNumber) - { - var maxDt = (to - from) / minNumber; - return ReadRecords(from, to, maxDt); - } - - public async Task> ReadRecords(UnixTime from, UnixTime to, UnixTimeSpan maxDt) - { - if (maxDt < SamplePeriod) - maxDt = SamplePeriod; - - var level = AggregationLevels.LastOrDefault(l => l.SamplePeriod <= maxDt) ?? AggregationLevels[^1]; - - return await level - .RangeExclusive(from, to) - .Select(t => ReadRecord(level, t)) - .WhenAll(); - } - - public async Task ReadRecord(AggregationLevel level, UnixTime time) - { - var tsRecord = await ReadRecord(level, level.GetRetentionIndex(time)); - - return tsRecord.TimeStamp == time - ? tsRecord - : TimeStampedRecord.Empty(time); - } -} \ No newline at end of file diff --git a/csharp/Lib/S3/Drivers/Internal/Util/Aggregator.cs b/csharp/Lib/S3/Drivers/Internal/Util/Aggregator.cs deleted file mode 100644 index 999a2aa1a..000000000 --- a/csharp/Lib/S3/Drivers/Internal/Util/Aggregator.cs +++ /dev/null @@ -1,60 +0,0 @@ -using InnovEnergy.Lib.S3.Metadata; -using InnovEnergy.Lib.S3.Records; -using InnovEnergy.Lib.S3.Records.Operations; -using InnovEnergy.Lib.Utils; - -namespace InnovEnergy.Lib.S3.Drivers.Internal.Util; - -public class Aggregator -{ - public AggregationLevel AggregationLevel { get; } - - private Record[] Buffer { get; } - private UInt32 Index { get; set; } - - public Aggregator(AggregationLevel thisLevel, - AggregationLevel levelBelow, - IEnumerable initialRecords) - { - var ratio = thisLevel.SamplePeriod / levelBelow.SamplePeriod; - - AggregationLevel = thisLevel; - - Index = 0; - Buffer = new Record[ratio]; - - Clear(); - - foreach (var record in initialRecords) - Aggregate(record); - } - - public Record? Aggregate(Record r) - { - Buffer[Index++] = r; - - return IsFull - ? ForceAggregation() - : null; - } - - public Record? ForceAggregation() - { - if (IsEmpty) - return null; // nothing to aggregate - - var aggregated = Buffer.Aggregate(); - Clear(); - return aggregated; - } - - private void Clear() - { - Buffer.Fill(Record.Empty); - Index = 0; - } - - private Boolean IsFull => Index == Buffer.Length; - private Boolean IsEmpty => Index == 0; - -} \ No newline at end of file diff --git a/csharp/Lib/S3/Drivers/Internal/Util/Sampler.cs b/csharp/Lib/S3/Drivers/Internal/Util/Sampler.cs deleted file mode 100644 index 384b00487..000000000 --- a/csharp/Lib/S3/Drivers/Internal/Util/Sampler.cs +++ /dev/null @@ -1,43 +0,0 @@ -using InnovEnergy.Lib.S3.Metadata; -using InnovEnergy.Lib.S3.Records; -using InnovEnergy.Lib.S3.Records.Specialized; -using InnovEnergy.Lib.Time.Unix; - -namespace InnovEnergy.Lib.S3.Drivers.Internal.Util; - -internal class Sampler -{ - public Record CurrentRecord { get; set; } - public UnixTime CurrentTimeStamp { get; set; } - public AggregationLevel AggregationLevel { get; } - - private UnixTimeSpan SamplePeriod => AggregationLevel.SamplePeriod; - - public Sampler(AggregationLevel aggregationLevel, Record record, UnixTime currentTime) - { - AggregationLevel = aggregationLevel; - CurrentRecord = record; - CurrentTimeStamp = aggregationLevel.GetPeriodStartTime(currentTime); - } - - - // TODO: repeat/max age - public IEnumerable Sample(Record record, UnixTime timeStamp) - { - timeStamp = AggregationLevel.GetPeriodStartTime(timeStamp); - - if (timeStamp < CurrentTimeStamp) - yield break; //throw new IndexOutOfRangeException(nameof(index)); // TODO: log - - if (timeStamp > CurrentTimeStamp) - yield return new AggregatedRecord(CurrentRecord, AggregationLevel, CurrentTimeStamp); - - for (var t = CurrentTimeStamp + SamplePeriod; t < timeStamp; t += SamplePeriod) - yield return new AggregatedRecord(Record.Empty, AggregationLevel, t); - - CurrentTimeStamp = timeStamp; - CurrentRecord = record; - } - - -} \ No newline at end of file diff --git a/csharp/Lib/S3/Drivers/Internal/Writer.cs b/csharp/Lib/S3/Drivers/Internal/Writer.cs deleted file mode 100644 index 19156a4d3..000000000 --- a/csharp/Lib/S3/Drivers/Internal/Writer.cs +++ /dev/null @@ -1,129 +0,0 @@ -using System.Diagnostics; -using InnovEnergy.Lib.S3.Drivers.Internal.Delegates; -using InnovEnergy.Lib.S3.Drivers.Internal.Util; -using InnovEnergy.Lib.S3.Metadata; -using InnovEnergy.Lib.S3.Records; -using InnovEnergy.Lib.S3.Records.Specialized; -using InnovEnergy.Lib.Time.Unix; -using InnovEnergy.Lib.Utils; - -namespace InnovEnergy.Lib.S3.Drivers.Internal; - -using AggregationLevels = IReadOnlyList; -using Aggregators = IReadOnlyList; - -public partial class Writer : Reader, IDisposable -{ - private Sampler Sampler { get; } - private Aggregators Aggregators { get; } - - private readonly WriteRecord _WriteRecord; - - internal Writer(UnixTime startTime, - AggregationLevels levels, - ReadRecord readRecord, - WriteRecord writeRecord) : base(levels, readRecord) - { - _WriteRecord = writeRecord; - startTime = AggregationLevels.First().GetPeriodStartTime(startTime); - Sampler = InitializeSampler(startTime); - Aggregators = InitializeAggregators(startTime); - } - - private IReadOnlyList InitializeAggregators(UnixTime startTime) - { - return AggregationLevels - .Pairwise() - .SelectTuple((lo, hi) => InitializeAggregator(lo, hi, startTime)) - .ToReadOnlyList(AggregationLevels.Count - 1); - } - - private Aggregator InitializeAggregator(AggregationLevel lo, - AggregationLevel hi, - UnixTime currentTime) - { - // This was a REAL brainfuck to get right - - var loStartTime = lo.GetPeriodStartTime(currentTime); - var hiStartTime = hi.GetPeriodStartTime(currentTime); - - Debug.Assert(hiStartTime <= loStartTime); - - var initialRecords = lo - .RangeExclusive(hiStartTime, loStartTime) - .Select(t => ReadRecord(lo, t)) - .WhenAll() - .Result - .Select(r => r.Record); - - return new Aggregator(hi, lo, initialRecords); - } - - private Sampler InitializeSampler(UnixTime startTime) - { - var samplerLevel = AggregationLevels.First(); - var initialRecord = ReadRecord(samplerLevel, startTime).Result.Record; - - return new Sampler(samplerLevel, initialRecord, startTime); - } - - private IEnumerable Aggregate(Record record, UnixTime timeStamp) - { - return Sampler - .Sample(record, timeStamp) - .SelectMany(Aggregate); - } - - private IEnumerable Aggregate(AggregatedRecord r) - { - yield return r; - - var record = r.Record; - - foreach (var a in Aggregators) - { - record = a.Aggregate(record); - if (record is null) break; - - var timeStamp = a.AggregationLevel.GetPeriodStartTime(r.TimeStamp); - yield return new AggregatedRecord(record, a.AggregationLevel, timeStamp); - } - } - - private Task WriteRecord(AggregatedRecord rec) - { - var tsr = rec.ToTimeStamped(); - var level = rec.AggregationLevel; - var index = level.GetRetentionIndex(rec.TimeStamp); - - return _WriteRecord(tsr, level, index); - } - - void IDisposable.Dispose() - { - DisposeAsync().Wait(); - } - - private async Task DisposeAsync() - { - // feed the sampler an empty "next" record, so it writes and aggregates the current one. - await WriteRecord(Record.Empty, Sampler.CurrentTimeStamp + SamplePeriod); - - foreach (var a in Aggregators) - { - // force and write incomplete aggregation for each level - - var agg = a.ForceAggregation(); - if (agg is null) - continue; - - var lev = a.AggregationLevel; - var ts = lev.GetPeriodStartTime(Sampler.CurrentTimeStamp); - var tsr = agg!.TimeStamped(ts); - var idx = lev.GetRetentionIndex(ts); - - await _WriteRecord(tsr, lev, idx); - } - } - -} \ No newline at end of file diff --git a/csharp/Lib/S3/Drivers/Internal/Writer.public.cs b/csharp/Lib/S3/Drivers/Internal/Writer.public.cs deleted file mode 100644 index 15ab491cf..000000000 --- a/csharp/Lib/S3/Drivers/Internal/Writer.public.cs +++ /dev/null @@ -1,26 +0,0 @@ -using InnovEnergy.Lib.S3.Records; -using InnovEnergy.Lib.S3.Records.Specialized; -using InnovEnergy.Lib.Time.Unix; -using InnovEnergy.Lib.Utils; - -namespace InnovEnergy.Lib.S3.Drivers.Internal; - -public partial class Writer -{ - public Task WriteRecord(Record record) - { - return WriteRecord(record, UnixTime.Now); - } - - public Task WriteRecord(TimeStampedRecord tsr) - { - return WriteRecord(tsr.Record, tsr.TimeStamp); - } - - public Task WriteRecord(Record record, UnixTime time) - { - return Aggregate(record, time) - .Select(WriteRecord) - .WhenAll(); - } -} \ No newline at end of file diff --git a/csharp/Lib/S3/Drivers/MemoryDriver.cs b/csharp/Lib/S3/Drivers/MemoryDriver.cs deleted file mode 100644 index 8b70abf5e..000000000 --- a/csharp/Lib/S3/Drivers/MemoryDriver.cs +++ /dev/null @@ -1,57 +0,0 @@ -using InnovEnergy.Lib.S3.Drivers.Internal; -using InnovEnergy.Lib.S3.Drivers.Internal.Delegates; -using InnovEnergy.Lib.S3.Metadata; -using InnovEnergy.Lib.S3.Records.Specialized; -using InnovEnergy.Lib.Time.Unix; - -namespace InnovEnergy.Lib.S3.Drivers; - -using Levels = IReadOnlyList; -using Memory = Dictionary; - -public class MemoryDriver : Writer -{ - - public MemoryDriver(Levels levels, UnixTime startTime, Memory memory) : - base( - startTime, - levels, - ReadRecord(memory), - WriteRecord(memory) - ) - { - } - - private static String GetKey(AggregationLevel level, UInt32 index) - { - return $"{level}/{index}"; - } - - private static ReadRecord ReadRecord(Memory memory) - { - Task Read(AggregationLevel level, UInt32 index) - { - var key = GetKey(level, index); - - var result = memory.TryGetValue(key, out var tsRecord) - ? tsRecord - : TimeStampedRecord.Empty(); - - return Task.FromResult(result); - } - - return Read; - } - - private static WriteRecord WriteRecord(Memory memory) - { - Task Write(TimeStampedRecord record, AggregationLevel level, UInt32 index) - { - var key = GetKey(level, index); - memory[key] = record; - return Task.CompletedTask; - } - - return Write; - } -} \ No newline at end of file diff --git a/csharp/Lib/S3/Drivers/S3Config.cs b/csharp/Lib/S3/Drivers/S3Config.cs deleted file mode 100644 index 758244b3f..000000000 --- a/csharp/Lib/S3/Drivers/S3Config.cs +++ /dev/null @@ -1,83 +0,0 @@ -using System.Security.Cryptography; -using Flurl; -using Flurl.Http; -using InnovEnergy.Lib.Utils; -using static System.Text.Encoding; -using Convert = System.Convert; - -namespace InnovEnergy.Lib.S3.Drivers; - -public record S3Config -{ - public String Bucket { get; init; } = ""; - public String Region { get; init; } = ""; - public String Provider { get; init; } = ""; - public String Key { get; init; } = ""; - public String Secret { get; init; } = ""; - public String ContentType { get; init; } = ""; - - public String Host => $"{Bucket}.{Region}.{Provider}"; - public String Url => $"https://{Host}"; - - public IFlurlRequest CreatePutRequest(String s3Path) => CreateRequest("PUT", s3Path); - public IFlurlRequest CreateGetRequest(String s3Path) => CreateRequest("GET", s3Path); - - private IFlurlRequest CreateRequest(String method, String s3Path) - { - var date = DateTime.UtcNow.ToString("r"); - var auth = CreateAuthorization(method, s3Path, date); - - return Url - .AppendPathSegment(s3Path) - .WithHeader("Host", Host) - .WithHeader("Date", date) - .WithHeader("Authorization", auth) - .AllowAnyHttpStatus(); - } - - private String CreateAuthorization(String method, - String s3Path, - String date) - { - return CreateAuthorization - ( - method : method, - bucket : Bucket, - s3Path : s3Path, - date : date, - s3Key : Key, - s3Secret : Secret, - contentType: ContentType - ); - } - - - - private static String CreateAuthorization(String method, - String bucket, - String s3Path, - String date, - String s3Key, - String s3Secret, - String contentType = "", - String md5Hash = "") - { - // StringToSign = HTTP-Verb + "\n" + - // Content-MD5 + "\n" + - // Content-Type + "\n" + - // Date + "\n" + - // CanonicalizedAmzHeaders + - // CanonicalizedResource; - - var payload = $"{method}\n{md5Hash}\n{contentType}\n{date}\n/{bucket.Trim('/')}/{s3Path.Trim('/')}"; - using var hmacSha1 = new HMACSHA1(UTF8.GetBytes(s3Secret)); - - var signature = UTF8 - .GetBytes(payload) - .Apply(hmacSha1.ComputeHash) - .Apply(Convert.ToBase64String); - - return $"AWS {s3Key}:{signature}"; - } - -} \ No newline at end of file diff --git a/csharp/Lib/S3/Drivers/S3Driver.cs b/csharp/Lib/S3/Drivers/S3Driver.cs deleted file mode 100644 index 9d231e998..000000000 --- a/csharp/Lib/S3/Drivers/S3Driver.cs +++ /dev/null @@ -1,82 +0,0 @@ -using Flurl.Http; -using InnovEnergy.Lib.S3.Drivers.Internal; -using InnovEnergy.Lib.S3.Drivers.Internal.Delegates; -using InnovEnergy.Lib.S3.Metadata; -using InnovEnergy.Lib.S3.Records.Serialization; -using InnovEnergy.Lib.S3.Records.Specialized; -using InnovEnergy.Lib.Time.Unix; - -namespace InnovEnergy.Lib.S3.Drivers; - -using Levels = IReadOnlyList; - -public class S3Driver : Writer -{ - - public S3Driver(Levels levels, UnixTime startTime, S3Config config) : - base( - startTime, - levels, - ReadRecord(config), - WriteRecord(config) - ) - { - } - - private static String GetS3Path(AggregationLevel level, UInt32 index) - { - return $"/{level}/{index}"; - } - - private static ReadRecord ReadRecord(S3Config config) - { - async Task Read(AggregationLevel level, UInt32 index) - { - var s3Path = GetS3Path(level, index); - var request = config.CreateGetRequest(s3Path); - var response = await request.GetAsync(); - - if (response.StatusCode != 200) - { - Console.WriteLine("ERROR: Get " + s3Path); - var error = await response.GetStringAsync(); - Console.WriteLine(error); - return TimeStampedRecord.Empty(); - } - - var payload = await response.GetBytesAsync(); - - Console.WriteLine("GET " + s3Path); - return Parser.ParseTimeStampedRecord(payload); - } - - return Read; - } - - private static WriteRecord WriteRecord(S3Config config) - { - async Task Write(TimeStampedRecord record, AggregationLevel level, UInt32 index) - { - var payload = record.Serialize().ToArray(); - var s3Path = GetS3Path(level, index); - var request = config.CreatePutRequest(s3Path); - var response = await request.PutAsync(new ByteArrayContent(payload)); - - if (response.StatusCode == 200) - { - //Console.WriteLine("PUT " + s3Path); - } - else - { - Console.WriteLine("ERROR: PUT"); - var error = await response.GetStringAsync(); - Console.WriteLine(error); - } - } - - return Write; - } - - - -} \ No newline at end of file diff --git a/csharp/Lib/S3/Metadata/AggregationLevel.cs b/csharp/Lib/S3/Metadata/AggregationLevel.cs deleted file mode 100644 index fd1ecd184..000000000 --- a/csharp/Lib/S3/Metadata/AggregationLevel.cs +++ /dev/null @@ -1,52 +0,0 @@ -using InnovEnergy.Lib.Time.Unix; - -namespace InnovEnergy.Lib.S3.Metadata; - -public record AggregationLevel -{ - public UnixTimeSpan RetentionPeriod { get; } - public UnixTimeSpan SamplePeriod { get; } - public UInt32 RetentionBufferSize { get; } - - public AggregationLevel(UnixTimeSpan samplePeriod, UnixTimeSpan retentionPeriod) - { - SamplePeriod = samplePeriod; - RetentionPeriod = retentionPeriod; - RetentionBufferSize = retentionPeriod / samplePeriod; - } - - public IEnumerable RangeExclusive(UnixTime from, UnixTime to) - { - if (from > to) - throw new ArgumentOutOfRangeException(nameof(to)); - - for (var t = GetPeriodStartTime(from); t < to; t += SamplePeriod) - yield return t; - } - - - // TODO: - public IEnumerable RangeInclusive(UnixTime from, UnixTime to) - { - if (from >= to) - throw new ArgumentOutOfRangeException(nameof(to)); - - from = GetPeriodStartTime(from); - to = GetPeriodStartTime(to) + SamplePeriod; - - for (var t = GetPeriodStartTime(from); t < to; t += SamplePeriod) - yield return t; - } - - public UInt32 GetRetentionIndex(UnixTime t) - { - return t / SamplePeriod % RetentionBufferSize; - } - - public UnixTime GetPeriodStartTime(UnixTime t) - { - return UnixTime.Epoch + t / SamplePeriod * SamplePeriod; // integer division! - } - - public override String ToString() => SamplePeriod.ToString(); -} \ No newline at end of file diff --git a/csharp/Lib/S3/Metadata/FieldType.cs b/csharp/Lib/S3/Metadata/FieldType.cs deleted file mode 100644 index 9ca91a1af..000000000 --- a/csharp/Lib/S3/Metadata/FieldType.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace InnovEnergy.Lib.S3.Metadata; - -public enum FieldType -{ - Number, - Text, - Boolean, -} \ No newline at end of file diff --git a/csharp/Lib/S3/Program.cs b/csharp/Lib/S3/Program.cs deleted file mode 100644 index 4ba261f71..000000000 --- a/csharp/Lib/S3/Program.cs +++ /dev/null @@ -1,211 +0,0 @@ -using System.Reactive.Concurrency; -using System.Reactive.Linq; -using System.Reactive.Subjects; -using InnovEnergy.Lib.S3.Metadata; -using InnovEnergy.Lib.Time.Unix; -using InnovEnergy.Lib.Utils; -using static InnovEnergy.Lib.Time.Unix.UnixTimeSpan; - -namespace InnovEnergy.Lib.S3; - - - -public enum MyEnum -{ - Foo = 0x01, - Bar = 0x02, - Baz = 0x04 -} - - -public record Test(Double X, Double Y, Double Z); - - - - -public static class Program -{ - private static readonly Random Rng = new Random(0); - - - - - - - public static void Main(String[] args) - { - - // var x = Observable - // .Range(0, 22) - // .Select(i=> new Dictionary - // { - // {"i", i}, - // {"i*2", i * 2}, - // {"i/2", i / 2}, - // }) - // .DictObserve(o => Observable.Where(o, i=> i < 10)); - // - // x.Subscribe(ints => Console.WriteLine(String.Join(Environment.NewLine,ints) + "\n") ); - - - var src = Observable - .Interval(TimeSpan.FromSeconds(1)) - .BufferBy(i => i / 5) - .Subscribe(b => - { - var values = b.Select(e => e.ToString()).Aggregate("", (x, y) => $"{x}\n{y}"); - var average = b.Average(); - var msg = $"{values}\nAverage: {average}"; - - Console.WriteLine(msg); - }); - - - - Console.ReadLine(); - // var t = new Test(12, 2, 1); - // - // foreach (var m in typeof(Test).GetMembers().OfType()) - // { - // var parameters = m - // .GetParameters() - // .Select(p => $"{p.ParameterType.Name} {p.Name}") - // .Aggregate("", (a, b) => a + ", " + b) - // .TrimStart(", ".ToCharArray()); - // - // Console.WriteLine($"{m.ReturnType.Name} {m.Name}({parameters})"); - // } - - - return; - - var s = new Subject(); - - Observable.Interval(TimeSpan.FromSeconds(2), TaskPoolScheduler.Default) - .WithLatestFrom(s, (_, x) => x) - .Subscribe(Console.WriteLine); - - while (true) - { - var k = Console.ReadKey(true); - s.OnNext(k.KeyChar.ToString()); - } - - - - - var levels = new [] - { - new AggregationLevel( 2.Seconds(), 54.Weeks()), - new AggregationLevel(10.Seconds(), 54.Weeks()), - new AggregationLevel( 1.Minutes(), 54.Weeks()), - new AggregationLevel( 5.Minutes(), 540.Weeks()), - new AggregationLevel(15.Minutes(), 540.Weeks()), - new AggregationLevel( 1.Hours() , 540.Weeks()), - new AggregationLevel( 6.Hours() , 540.Weeks()), - new AggregationLevel( 1.Days() , 540.Weeks()), - new AggregationLevel( 1.Weeks() , Forever) - }; - - var resolution = 2.Seconds(); - - for (int i = 0; i < 10; i++) - { - var startTime = UnixTime.Epoch + Rng.Next(0, 2.Weeks().Ticks.ConvertTo()).Seconds(); - var split = Rng.Next(2, 1000); - - //Test(startTime, resolution, levels, split); - } - - - Console.WriteLine("Done"); - } - - // private static void Test(UnixTime startTime, UnixTimeSpan resolution, AggregationLevel[] aggregationLevels, Int32 split) - // { - // var times = Enumerable - // .Range(0, 2.Weeks().Ticks.ConvertTo()) - // .Select(t => startTime + t * resolution) - // .ToReadOnlyList(); - // - // var records = times - // //.Where(_ => Rng.NextDouble() > .25) // "loose" 1 in 4 - // .Select(t => ( - // record: new Record - // ( - // // new NumberField("Current", t.Ticks / 2, "A"), - // new SubRecord("Sub1", new Record(new NumberField("Current1", t.Ticks / 4, "A"))), - // new SubRecord("Sub2", new Record(new NumberField("Current2", t.Ticks / 8, "A"))) - // ), - // time: t + Rng.NextDouble().Apply(Math.Round).ConvertTo().Seconds() // add noise - // )) - // .ToList(); - // - // - // var allMemory = new Dictionary(); - // using (var driverAll = new MemoryDriver(aggregationLevels, startTime, allMemory)) - // { - // foreach (var record in records) - // driverAll.WriteRecord(record.record, record.time); - // } - // - // var list = allMemory.Where(kv => kv.Key.StartsWith("1w")).ToList(); - // - // var splitMemory = new Dictionary(); - // using (var driver1 = new MemoryDriver(aggregationLevels, startTime, splitMemory)) - // { - // foreach (var record in records.Take(split)) - // driver1.WriteRecord(record.record, record.time); - // } - // - // using (var driver2 = new MemoryDriver(aggregationLevels, records.ElementAt(split-1).time, splitMemory)) - // { - // foreach (var record in records.Skip(split-1)) - // driver2.WriteRecord(record.record, record.time); - // } - // - // - // - // var zip = Enumerable.Zip( - // allMemory.OrderBy(kv => kv.Key), - // splitMemory.OrderBy(kv => kv.Key) - // ); - // - // foreach (var (l, r) in zip) - // { - // var nl = l.Value.Record.Fields.OfType().FirstOrDefault()?.Value; - // var nr = r.Value.Record.Fields.OfType().FirstOrDefault()?.Value; - // - // if (l.Key != r.Key) - // { - // Console.WriteLine($"{l.Key} <=> {r.Key}"); - // break; - // } - // - // if (nl != nr) - // { - // Console.WriteLine($"{l.Value.TimeStamp.ToUtcDateTime()}: {nl} <=> {nr}"); - // } - // } - // } - - - public static String CreateRandomState() - { - var r = Rng.NextDouble() * 100; - - return r switch - { - >= 90 => "Heating", - >= 10 => "SelfConsumption", - _ => "CalibrationCharge" - }; - } - - - - - - - -} \ No newline at end of file diff --git a/csharp/Lib/S3/Records/Fields/Field.cs b/csharp/Lib/S3/Records/Fields/Field.cs deleted file mode 100644 index a68f29cd4..000000000 --- a/csharp/Lib/S3/Records/Fields/Field.cs +++ /dev/null @@ -1,3 +0,0 @@ -namespace InnovEnergy.Lib.S3.Records.Fields; - -public abstract record Field; \ No newline at end of file diff --git a/csharp/Lib/S3/Records/Fields/NumberField.cs b/csharp/Lib/S3/Records/Fields/NumberField.cs deleted file mode 100644 index 62aca9f6c..000000000 --- a/csharp/Lib/S3/Records/Fields/NumberField.cs +++ /dev/null @@ -1,25 +0,0 @@ -namespace InnovEnergy.Lib.S3.Records.Fields; - -public record NumberField : Field -{ - public Double Value { get; } - public Double Min { get; } - public Double Max { get; } - public String Unit { get; } - - public NumberField(Double value, Double min, Double max, String unit = "") - { - Value = value; - Min = min; - Max = max; - Unit = unit; - } - - public NumberField(Double value, String unit = "") : this(value, value, value, unit) - { - } - - public NumberField(Boolean value) : this(value?100:0, "%") - { - } -} \ No newline at end of file diff --git a/csharp/Lib/S3/Records/Fields/TextField.cs b/csharp/Lib/S3/Records/Fields/TextField.cs deleted file mode 100644 index 7b1ebd2e4..000000000 --- a/csharp/Lib/S3/Records/Fields/TextField.cs +++ /dev/null @@ -1,38 +0,0 @@ -using InnovEnergy.Lib.Utils; - -namespace InnovEnergy.Lib.S3.Records.Fields; - -public record TextField : Field -{ - public IReadOnlyList Frequencies { get; } - - public TextField(IReadOnlyList frequencies) - { - Frequencies = frequencies; - } - - public TextField(params TextFrequency[] frequencies) : this((IReadOnlyList)frequencies) - { - } - - public TextField(String text) : this(new TextFrequency(text)) - { - } - - public TextField(Enum enumValue) : this(GetEnumFlagsAsFrequencies(enumValue)) - { - } - - private static IReadOnlyList GetEnumFlagsAsFrequencies(Enum enumValue) - { - return enumValue - .ToString() - .Split(',') // debug view is '|' separated, toString() uses ',' !! - .Select(v => v.Trim()) - .Where(v => !v.IsInteger()) // filter "unknown" enum flags - .Select(f => new TextFrequency(f)) - .ToReadOnlyList(); - } - - -} \ No newline at end of file diff --git a/csharp/Lib/S3/Records/Fields/TextFrequency.cs b/csharp/Lib/S3/Records/Fields/TextFrequency.cs deleted file mode 100644 index 60974957f..000000000 --- a/csharp/Lib/S3/Records/Fields/TextFrequency.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace InnovEnergy.Lib.S3.Records.Fields; - -public record TextFrequency -{ - public TextFrequency(String text, Double percent = 100) - { - Text = text; - Percent = percent; - } - - public String Text { get; } - public Double Percent { get; } -} \ No newline at end of file diff --git a/csharp/Lib/S3/Records/Fields/UnitAttribute.cs b/csharp/Lib/S3/Records/Fields/UnitAttribute.cs deleted file mode 100644 index 1bd25600c..000000000 --- a/csharp/Lib/S3/Records/Fields/UnitAttribute.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace InnovEnergy.Lib.S3.Records.Fields; - -[AttributeUsage(AttributeTargets.Property)] -public sealed class UnitAttribute : Attribute -{ - private readonly String _Unit; - - public UnitAttribute(String unit) - { - _Unit = unit; - } - - public override String ToString() => _Unit; - - public static implicit operator String(UnitAttribute a) => a.ToString(); -} \ No newline at end of file diff --git a/csharp/Lib/S3/Records/Fields/WithUnit.cs b/csharp/Lib/S3/Records/Fields/WithUnit.cs deleted file mode 100644 index 01104d9de..000000000 --- a/csharp/Lib/S3/Records/Fields/WithUnit.cs +++ /dev/null @@ -1,30 +0,0 @@ -namespace InnovEnergy.Lib.S3.Records.Fields; - -public readonly struct WithUnit -{ - public String Unit { get; } - public Double Value { get; } - - public WithUnit(Double value, String unit) - { - Unit = unit; - Value = value; - } - - public override String ToString() => Unit; -} - -public static class UnitExtensions -{ - public static WithUnit Unit(this Double number, String unit) => new WithUnit(number, unit); - public static WithUnit Unit(this Single number, String unit) => new WithUnit(number, unit); - public static WithUnit Unit(this Half number, String unit) => new WithUnit((Double) number, unit); - public static WithUnit Unit(this SByte number, String unit) => new WithUnit(number, unit); - public static WithUnit Unit(this Byte number, String unit) => new WithUnit(number, unit); - public static WithUnit Unit(this Int16 number, String unit) => new WithUnit(number, unit); - public static WithUnit Unit(this UInt16 number, String unit) => new WithUnit(number, unit); - public static WithUnit Unit(this Int32 number, String unit) => new WithUnit(number, unit); - public static WithUnit Unit(this UInt32 number, String unit) => new WithUnit(number, unit); - public static WithUnit Unit(this Int64 number, String unit) => new WithUnit(number, unit); - public static WithUnit Unit(this UInt64 number, String unit) => new WithUnit(number, unit); -} \ No newline at end of file diff --git a/csharp/Lib/S3/Records/Operations/Aggregation.cs b/csharp/Lib/S3/Records/Operations/Aggregation.cs deleted file mode 100644 index 1b938947f..000000000 --- a/csharp/Lib/S3/Records/Operations/Aggregation.cs +++ /dev/null @@ -1,83 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using InnovEnergy.Lib.S3.Records.Fields; -using InnovEnergy.Lib.Utils; - -namespace InnovEnergy.Lib.S3.Records.Operations; - -// ReSharper disable ArgumentsStyleOther - - -public static class Aggregation -{ - - [SuppressMessage("ReSharper", "PossibleMultipleEnumeration")] - public static Record Aggregate(this IReadOnlyList records) - { - var availability = records.Sum(r => r.Availability) / records.Count; - - if (availability == 0) - return Record.Empty; - - var numbers = records.GetColumns().Select(AggregateNumbers); - var texts = records.GetColumns() .Select(AggregateTexts); - var subRecords = records.GetColumns() .Select(AggregateRecords); - - var aggregated = numbers.Concat(texts).Concat(subRecords); - - var fields = new Dictionary(aggregated); - - return new Record - ( - fields, - availability - ); - } - - private static IEnumerable<(String name, F field)> GetFields(this IEnumerable records) where F : Field - { - foreach (var record in records) - foreach (var (name, field) in record.Fields) - if (field is F f) - yield return (name, f); - } - - private static ILookup GetColumns(this IEnumerable records) where F : Field - { - return records - .GetFields() - .ToLookup(nf => nf.name, nf => nf.field); - } - - - private static KeyValuePair AggregateTexts(IGrouping column) - { - var textFrequencies = column - .SelectMany(s => s.Frequencies) - .GroupBy(f => f.Text, f => f.Percent) - .Select(g => new TextFrequency(text: g.Key, percent: g.Sum() / g.Count())) - .OrderBy(f => f.Text) - .ToReadOnlyList(); - - return new (column.Key, new TextField(textFrequencies)); - } - - private static KeyValuePair AggregateNumbers(IGrouping column) - { - var aggregated = new NumberField - ( - min: column.Min(f => f.Min), - max: column.Max(f => f.Max), - value: column.Average(f => f.Value), - unit: column.First().Unit - ); - - return new (column.Key, aggregated); - } - - private static KeyValuePair AggregateRecords(IGrouping column) - { - var aggregate = column.ToReadOnlyList().Apply(Aggregate); - - return new(column.Key, aggregate); - } -} \ No newline at end of file diff --git a/csharp/Lib/S3/Records/Operations/Conversion.cs b/csharp/Lib/S3/Records/Operations/Conversion.cs deleted file mode 100644 index cb68eb4ca..000000000 --- a/csharp/Lib/S3/Records/Operations/Conversion.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System.Reflection; -using InnovEnergy.Lib.S3.Records.Fields; -using InnovEnergy.Lib.Utils; -using static System.Reflection.BindingFlags; - -namespace InnovEnergy.Lib.S3.Records.Operations; - -public static class Conversion -{ - public static Record ToRecord(this Object t) - { - var fields = t.GetType() - .Apply(GetProperties) - .ToDictionary(p => p.Name, PropertyToField); - - return new Record(fields); - - Field PropertyToField(PropertyInfo p) => p.GetValue(t) switch - { - Double d => new NumberField(d, Unit(p)), - Boolean b => new NumberField(b), - Enum e => new TextField(e), - String s => new TextField(s), // ReSharper disable once PatternAlwaysOfType - Object o => ToRecord(o), - _ => throw new ArgumentException() - }; - } - - private static String Unit(MemberInfo member) - { - return member - .GetCustomAttributes() - .OfType() - .FirstOrDefault()? - .ToString() - ?? ""; - } - - private static IEnumerable GetProperties() => typeof(T).GetProperties(Instance | Public); - - private static IEnumerable GetProperties(Type t) => t.GetProperties(Instance | Public); - - - - -} \ No newline at end of file diff --git a/csharp/Lib/S3/Records/Record.cs b/csharp/Lib/S3/Records/Record.cs deleted file mode 100644 index 365765843..000000000 --- a/csharp/Lib/S3/Records/Record.cs +++ /dev/null @@ -1,59 +0,0 @@ -using InnovEnergy.Lib.S3.Records.Fields; -using InnovEnergy.Lib.S3.Records.Specialized; -using InnovEnergy.Lib.Time.Unix; - -namespace InnovEnergy.Lib.S3.Records; - -public record Record : Field -{ - public static Record Empty { get; } = new Record(new Dictionary(), 0); - - public IReadOnlyDictionary Fields { get; } - public Double Availability { get; } - - public Boolean IsEmpty => Fields.Count == 0; - - - public Record(IReadOnlyDictionary fields, Double availability = 1.0) - { - Fields = fields; - Availability = availability; - } - - public F GetField(String name) where F : Field - { - return (F) Fields[name]; - } - - public TimeStampedRecord TimeStamped(UnixTime unixTime) => new TimeStampedRecord(this, unixTime); - - - public static Record ParseDict(Dictionary dict, Double availability = 1.0) - { - var fields = dict.ToDictionary(kv => kv.Key, kv => ParseField(kv.Value)); - return new Record(fields, availability); - } - - private static Field ParseField(Object value) => - value switch - { - WithUnit v => new NumberField(v.Value, v.Unit), - Enum v => new TextField(v), - String v => new TextField(v), - Double v => new NumberField(v), - Field v => v, - Single v => new NumberField(v), - SByte v => new NumberField(v), - Byte v => new NumberField(v), - Int16 v => new NumberField(v), - UInt16 v => new NumberField(v), - Int32 v => new NumberField(v), - UInt32 v => new NumberField(v), - Int64 v => new NumberField(v), - UInt64 v => new NumberField(v), - Half v => new NumberField((Double)v), - _ => throw new ArgumentOutOfRangeException(nameof(value)) - }; - - -} \ No newline at end of file diff --git a/csharp/Lib/S3/Records/Serialization/FieldTag.cs b/csharp/Lib/S3/Records/Serialization/FieldTag.cs deleted file mode 100644 index 8dff3261b..000000000 --- a/csharp/Lib/S3/Records/Serialization/FieldTag.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace InnovEnergy.Lib.S3.Records.Serialization; - -public enum FieldTag : Byte -{ - NumberField = 0, - TextField = 1, - RecordField = 2, -} \ No newline at end of file diff --git a/csharp/Lib/S3/Records/Serialization/Parser.cs b/csharp/Lib/S3/Records/Serialization/Parser.cs deleted file mode 100644 index 76319a31a..000000000 --- a/csharp/Lib/S3/Records/Serialization/Parser.cs +++ /dev/null @@ -1,134 +0,0 @@ -using System.Text; -using InnovEnergy.Lib.S3.Records.Fields; -using InnovEnergy.Lib.S3.Records.Specialized; -using InnovEnergy.Lib.Time.Unix; -using InnovEnergy.Lib.Utils; - -namespace InnovEnergy.Lib.S3.Records.Serialization; - -public class Parser -{ - private Int32 Position { get; set; } - private Byte[] Data { get; } - - private Parser(Byte[] data, Int32 position = 0) - { - Data = data; - Position = position; - } - - public Boolean IsPastEnd => Position >= Data.Length; - - public static TimeStampedRecord ParseTimeStampedRecord(Byte[] data) - { - var parser = new Parser(data); - - var timeStamp = parser.ParseUnixTime(); - var record = parser.ParseRecord(); - - return new TimeStampedRecord(record, timeStamp); - } - - - private UnixTime ParseUnixTime() - { - var span = new ReadOnlySpan(Data, Position, sizeof(UInt32)); - var ticks = BitConverter.ToUInt32(span); - - Position += span.Length; - - return UnixTime.FromTicks(ticks); - } - - private Single ParseFloat() - { - var span = new ReadOnlySpan(Data, Position, sizeof(Single)); - Position += span.Length; - return BitConverter.ToSingle(span); - } - - private String ParseString() - { - var len = GetByte(); - var span = new ReadOnlySpan(Data, Position, len); - - Position += span.Length; - - return Encoding.UTF8.GetString(span); - } - - private NumberField ParseNumberField() - { - var value = ParseFloat(); - var min = ParseFloat(); - var max = ParseFloat(); - var unit = ParseString(); - - return new NumberField(value, min, max, unit); - } - - private TextFrequency ParseTextFrequency() - { - var txt = ParseString(); - var frq = ParseFloat(); - - return new TextFrequency(txt, frq); - } - - private Record ParseRecord() - { - var availability = ParseFloat(); - var fields = ParseFields(); - - return new Record(fields, availability); - } - - private IReadOnlyDictionary ParseFields() - { - var len = GetByte(); - - var fields = Enumerable - .Range(0, len) - .Select(_ => ParseNamedField()); - - return new Dictionary(fields); - } - - private Field ParseField() - { - var tag = ParseFieldTag(); - - return tag switch - { - FieldTag.NumberField => ParseNumberField(), - FieldTag.TextField => ParseTextField(), - FieldTag.RecordField => ParseRecord(), - _ => throw new ArgumentOutOfRangeException(nameof(FieldTag)) - }; - } - - private KeyValuePair ParseNamedField() - { - var name = ParseString(); - var field = ParseField(); - - return new KeyValuePair(name, field); - } - - - private TextField ParseTextField() - { - var len = GetByte(); - - var fqs = Enumerable - .Range(0, len) - .Select(_ => ParseTextFrequency()) - .ToReadOnlyList(len); - - return new TextField(fqs); - } - - private Byte GetByte() => Data[Position++]; - - private FieldTag ParseFieldTag() => (FieldTag) GetByte(); -} \ No newline at end of file diff --git a/csharp/Lib/S3/Records/Serialization/Serializer.cs b/csharp/Lib/S3/Records/Serialization/Serializer.cs deleted file mode 100644 index d7766df8d..000000000 --- a/csharp/Lib/S3/Records/Serialization/Serializer.cs +++ /dev/null @@ -1,121 +0,0 @@ -using InnovEnergy.Lib.S3.Records.Fields; -using InnovEnergy.Lib.S3.Records.Specialized; -using InnovEnergy.Lib.Time.Unix; -using InnovEnergy.Lib.Utils; -using static System.Text.Encoding; - -namespace InnovEnergy.Lib.S3.Records.Serialization; - -public static class Serializer -{ - public static IEnumerable Serialize(this TimeStampedRecord tsr) - { - if (!BitConverter.IsLittleEndian) - throw new ArgumentException(nameof(BitConverter)); - - var timeStamp = tsr.TimeStamp.Serialize(); - var record = tsr.Record.Serialize(); - return timeStamp.Concat(record); - } - - private static IEnumerable Serialize(this UnixTime t) - { - return BitConverter.GetBytes(t.Ticks); - } - - private static IEnumerable Serialize(this Record r) - { - var availability = r.Availability.Serialize(); - var fields = r.Fields.Serialize(); - - return availability.Concat(fields); - } - - private static IEnumerable Serialize(this IReadOnlyDictionary fields) - { - var len = fields.GetLength(); - - return fields - .SelectMany(Serialize) - .Prepend(len); - } - - private static IEnumerable Serialize(this KeyValuePair kv) - { - var name = kv.Key.Serialize(); - var field = kv.Value.Serialize(); - - return name.Concat(field); - } - - - public static IEnumerable Serialize(this Field f) - { - return f switch - { - NumberField nf => Serialize(nf).PrependTag(FieldTag.NumberField), - TextField tf => Serialize(tf).PrependTag(FieldTag.TextField), - Record r => Serialize(r).PrependTag(FieldTag.RecordField), - _ => throw new ArgumentException(nameof(f)) - }; - } - - public static IEnumerable Serialize(NumberField nf) - { - var value = nf.Value.Serialize(); - var min = nf.Min .Serialize(); - var max = nf.Max .Serialize(); - var unit = nf.Unit .Serialize(); - - return value - .Concat(min) - .Concat(max) - .Concat(unit); - } - - public static IEnumerable Serialize(this TextField tf) - { - var len = tf.Frequencies.GetLength(); - return tf - .Frequencies - .SelectMany(Serialize) - .Prepend(len); - } - - public static IEnumerable Serialize(this TextFrequency tf) - { - var txt = tf.Text.Serialize(); - var frq = tf.Percent.Serialize(); - - return txt.Concat(frq); - } - - public static IEnumerable Serialize(this Double d) - { - return BitConverter.GetBytes((Single) d); // use float to save space - } - - - public static IEnumerable Serialize(this String s) - { - return UTF8 - .GetBytes(s) - .Apply(PrependLength); - } - - private static IEnumerable PrependTag(this IEnumerable data, FieldTag fieldTag) - { - return data.Prepend((Byte) fieldTag); - } - - private static IEnumerable PrependLength(IReadOnlyCollection data) - { - var len = (Byte) data.Count; - return data.Prepend(len); - } - - private static Byte GetLength(this IReadOnlyCollection data) - { - return (Byte) data.Count; - } -} \ No newline at end of file diff --git a/csharp/Lib/S3/Records/Specialized/AggregatedRecord.cs b/csharp/Lib/S3/Records/Specialized/AggregatedRecord.cs deleted file mode 100644 index e4b9a2283..000000000 --- a/csharp/Lib/S3/Records/Specialized/AggregatedRecord.cs +++ /dev/null @@ -1,23 +0,0 @@ -using InnovEnergy.Lib.S3.Metadata; -using InnovEnergy.Lib.Time.Unix; - -namespace InnovEnergy.Lib.S3.Records.Specialized; - -public readonly struct AggregatedRecord -{ - public UnixTime TimeStamp { get; } - public Record Record { get; } - public AggregationLevel AggregationLevel { get; } - - public AggregatedRecord(Record record, AggregationLevel level, UnixTime timeStamp) - { - AggregationLevel = level; - TimeStamp = timeStamp; - Record = record; - } - - public TimeStampedRecord ToTimeStamped() - { - return new TimeStampedRecord(Record, TimeStamp); - } -} \ No newline at end of file diff --git a/csharp/Lib/S3/Records/Specialized/TimeStampedRecord.cs b/csharp/Lib/S3/Records/Specialized/TimeStampedRecord.cs deleted file mode 100644 index 57dc56aed..000000000 --- a/csharp/Lib/S3/Records/Specialized/TimeStampedRecord.cs +++ /dev/null @@ -1,27 +0,0 @@ -using InnovEnergy.Lib.Time.Unix; - -namespace InnovEnergy.Lib.S3.Records.Specialized; - -public readonly struct TimeStampedRecord -{ - public UnixTime TimeStamp { get; } - public Record Record { get; } - - public TimeStampedRecord(Record record, UnixTime timeStamp) - { - Record = record; - TimeStamp = timeStamp; - } - - public Boolean IsEmpty => Record.IsEmpty; - - public static TimeStampedRecord Empty() - { - return Empty(UnixTime.Epoch); - } - - public static TimeStampedRecord Empty(UnixTime timeStamp) - { - return new TimeStampedRecord(Record.Empty, timeStamp); - } -} \ No newline at end of file diff --git a/csharp/Lib/S3/S3.csproj b/csharp/Lib/S3/S3.csproj deleted file mode 100644 index 946c4841f..000000000 --- a/csharp/Lib/S3/S3.csproj +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/csharp/Lib/S3/Serialization/JsonConverters.cs b/csharp/Lib/S3/Serialization/JsonConverters.cs deleted file mode 100644 index aa2de6bb2..000000000 --- a/csharp/Lib/S3/Serialization/JsonConverters.cs +++ /dev/null @@ -1,167 +0,0 @@ -// using System; -// using System.Text.Json; -// using System.Text.Json.Serialization; -// using InnovEnergy.S3.Records; -// using InnovEnergy.S3.Records.Fields; -// -// namespace InnovEnergy.S3.Serialization -// { -// public class SubClassConverterFactory : JsonConverterFactory -// { -// public override Boolean CanConvert(Type t) -// { -// return t.IsAbstract && t.IsClass; -// } -// -// public override JsonConverter CreateConverter(Type type, JsonSerializerOptions options) -// { -// var converterType = typeof(SubClassConverter<>).MakeGenericType(type); -// return (JsonConverter) Activator.CreateInstance(converterType)!; -// } -// -// public class SubClassConverter : JsonConverter -// { -// public override Boolean CanConvert(Type type) -// { -// return type == typeof(T); -// } -// -// public override T Read(ref Utf8JsonReader r, Type t, JsonSerializerOptions o) -// { -// throw new NotImplementedException(); -// } -// -// public override void Write(Utf8JsonWriter writer, T obj, JsonSerializerOptions options) -// { -// JsonSerializer.Serialize(writer, obj, obj!.GetType()); -// } -// } -// } -// -// public class DataRecordConverter : JsonConverter -// { -// public override Boolean CanConvert(Type type) -// { -// return typeof(Record).IsAssignableFrom(type); -// } -// -// public override Record Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) -// { -// throw new NotImplementedException(); -// } -// -// public override void Write(Utf8JsonWriter writer, Record @record, JsonSerializerOptions options) -// { -// writer.WriteStartObject(); -// -// foreach (var field in record.Fields) -// { -// writer.WritePropertyName(field.Name); -// -// if (field is NumberField an) -// { -// writer.WriteStartObject(); -// writer.WriteNumber("Min", an.Min); -// writer.WriteNumber("Max", an.Max); -// writer.WriteNumber("Mean", an.Value); -// writer.WriteEndObject(); -// } -// else if (field is TextField at) -// { -// writer.WriteStartObject(); -// foreach (var f in at.Frequencies) -// { -// writer.WriteNumber(f.Text, f.Percent); -// } -// writer.WriteEndObject(); -// } -// else if (field is BooleanField ab) -// { -// writer.WriteStartObject(); -// writer.WriteNumber("PercentTrue", ab.PercentTrue); -// writer.WriteEndObject(); -// } -// else -// throw new NotSupportedException(); -// } -// -// writer.WriteNumber("Time", record.TimeStamp.Ticks); -// writer.WriteNumber("Availability", record.Availability); -// -// writer.WriteEndObject(); -// } -// } -// -// // public class AggregatedRecordConverter : JsonConverter -// // { -// // public override Boolean CanConvert(Type type) -// // { -// // return typeof(AggregatedRecord).IsAssignableFrom(type); -// // } -// // -// // public override AggregatedRecord Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => throw new NotImplementedException(); -// // -// // public override void Write(Utf8JsonWriter writer, AggregatedRecord dataRecord, JsonSerializerOptions options) -// // { -// // writer.WriteStartObject(); -// // -// // foreach (var field in dataRecord.Fields) -// // { -// // if (field is AggregatedNumber n) -// // { -// // writer.WritePropertyName(n.Name); -// // writer.WriteStartObject(); -// // writer.WritePropertyName("Mean"); -// // writer.WriteNumberValue(n.Mean); -// // -// // writer.WritePropertyName("Min"); -// // writer.WriteNumberValue(n.Min); -// // -// // writer.WritePropertyName("Max"); -// // writer.WriteNumberValue(n.Max); -// // -// // writer.WriteEndObject(); -// // } -// // else if (field is AggregatedText t) -// // { -// // writer.WritePropertyName(t.Name); -// // JsonSerializer.Serialize(writer, t); -// // } -// // else if (field is AggregatedBoolean b) -// // { -// // writer.WritePropertyName(b.Name); -// // JsonSerializer.Serialize(writer, b); -// // } -// // -// // else throw new NotSupportedException(); -// // } -// // -// // writer.WriteEndObject(); -// // } -// // -// // -// // -// // -// // } -// -// // public class TextFrequencyConverter : JsonConverter -// // { -// // public override Boolean CanConvert(Type type) -// // { -// // return typeof(TextFrequency).IsAssignableFrom(type); -// // } -// // -// // public override TextFrequency Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => throw new NotImplementedException(); -// // -// // public override void Write(Utf8JsonWriter writer, TextFrequency textFrequency, JsonSerializerOptions options) -// // { -// // writer.WriteStartObject(); -// // writer.WritePropertyName(textFrequency.Text); -// // writer.WriteNumberValue(textFrequency.Percent); -// // writer.WriteEndObject(); -// // } -// // } -// -// -// -// } \ No newline at end of file diff --git a/csharp/Lib/SysTools/Edges/StringToCommand.cs b/csharp/Lib/SysTools/Edges/StringToCommand.cs index 1dc691b7f..62c595f75 100644 --- a/csharp/Lib/SysTools/Edges/StringToCommand.cs +++ b/csharp/Lib/SysTools/Edges/StringToCommand.cs @@ -7,50 +7,50 @@ public static class StringToCommand public static SysCommand Opt1(this String cmd, String option) { return cmd - .ToCommand() - .Opt1(option); + .ToCommand() + .Opt1(option); } public static SysCommand Opt1(this String cmd, String option, Object value, String separator = " ") { return cmd - .ToCommand() - .Opt1(option, value, separator); + .ToCommand() + .Opt1(option, value, separator); } public static SysCommand Opt2(this String cmd, String option) { return cmd - .ToCommand() - .Opt2(option); + .ToCommand() + .Opt2(option); } public static SysCommand Opt2(this String cmd, String option, Object value, String separator = "=") { return cmd - .ToCommand() - .Opt2(option, value, separator); + .ToCommand() + .Opt2(option, value, separator); } public static SysCommand Opt(this String cmd, String option) { return cmd - .ToCommand() - .Opt(option); + .ToCommand() + .Opt(option); } public static SysCommand Opt(this String cmd, String option, Object value) { return cmd - .ToCommand() - .Opt(option, value); + .ToCommand() + .Opt(option, value); } public static SysCommand Arg(this String cmd, Object argument) { return cmd - .ToCommand() - .Arg(argument); + .ToCommand() + .Arg(argument); } } \ No newline at end of file diff --git a/csharp/Lib/SysTools/FileIo.cs b/csharp/Lib/SysTools/FileIo.cs index 7328bd324..bec888e56 100644 --- a/csharp/Lib/SysTools/FileIo.cs +++ b/csharp/Lib/SysTools/FileIo.cs @@ -1,8 +1,9 @@ using System.Text; -using InnovEnergy.Lib.SysTools.Utils; +using InnovEnergy.Lib.Utils; namespace InnovEnergy.Lib.SysTools; +[Obsolete("Needs rework before use")] public static class FileIo { public static Boolean Exists (this SysPath path) => path.FileExists() || path.DirectoryExists(); @@ -14,12 +15,12 @@ public static class FileIo public static IEnumerable Directories(this SysPath sysPath) => Directory - .GetDirectories(sysPath) - .Select(SysPath.FromString); + .GetDirectories(sysPath) + .Select(SysPath.FromString); public static IEnumerable Files(this SysPath sysPath) => Directory - .GetFiles(sysPath) - .Select(SysPath.FromString); + .GetFiles(sysPath) + .Select(SysPath.FromString); public static SysPath CreateDirectory(this SysPath path) @@ -91,10 +92,10 @@ public static class FileIo SysPath Target(SysPath path) => targetDir.Append(path.RelativeTo(sourceDir)); - Utils.Utils.Traverse(sourceDir, Directories) - .Do(d => Target(d).CreateDirectory()) - .SelectMany(Files) - .ForEach(f => f.CopyFileTo(Target(f))); + sourceDir.Traverse(Directories) + .Do(d => Target(d).CreateDirectory()) + .SelectMany(Files) + .ForEach(f => f.CopyFileTo(Target(f))); return sourceDir; } @@ -115,14 +116,14 @@ public static class FileIo public static IEnumerable DescendantDirectories(this SysPath path) { - return Utils.Utils.Traverse(path, Directories); + return path.Traverse(Directories); } public static IEnumerable DescendantFiles(this SysPath path) { return path - .DescendantDirectories() - .SelectMany(Files); + .DescendantDirectories() + .SelectMany(Files); } public static IEnumerable Descendants(this SysPath path) @@ -140,13 +141,11 @@ public static class FileIo { var buf = new Byte[4096]; - using (var fs = File.OpenRead(path)) - { - var n = fs.Read(buf, 0, buf.Length); + using var fs = File.OpenRead(path); + var n = fs.Read(buf, 0, buf.Length); - foreach (var b in buf.Take(Math.Max(0, n))) - yield return b; - } + foreach (var b in buf.Take(Math.Max(0, n))) + yield return b; } @@ -154,29 +153,29 @@ public static class FileIo public static IEnumerable ReadLines(this SysPath path, Encoding encoding) { - using (var sr = new StreamReader(path, encoding)) - while (true) - { - var str = sr.ReadLine(); - if (str == null) - yield break; + using var sr = new StreamReader(path, encoding); + while (true) + { + var str = sr.ReadLine(); + if (str == null) + yield break; - yield return str; - } + yield return str; + } } public static String ReadText(this SysPath path) => path.ReadText(Encoding.UTF8); public static String ReadText(this SysPath path, Encoding encoding) { - using (var sr = new StreamReader(path, encoding)) - return sr.ReadToEnd(); + using var sr = new StreamReader(path, encoding); + return sr.ReadToEnd(); } public static SysPath WriteText(this SysPath filePath, String text) { - using (var sw = new StreamWriter(filePath, append: false)) - sw.Write(text); + using var sw = new StreamWriter(filePath, append: false); + sw.Write(text); return filePath; } @@ -189,17 +188,17 @@ public static class FileIo public static SysPath WriteLines(this SysPath filePath, IEnumerable lines) { - using (var sw = new StreamWriter(filePath, append: false)) - foreach (var line in lines) - sw.WriteLine(line); + using var sw = new StreamWriter(filePath, append: false); + foreach (var line in lines) + sw.WriteLine(line); return filePath; } public static SysPath AppendText(this SysPath filePath, String text) { - using (var sw = new StreamWriter(filePath, append: true)) - sw.Write(text); + using var sw = new StreamWriter(filePath, append: true); + sw.Write(text); return filePath; } @@ -212,9 +211,9 @@ public static class FileIo public static SysPath AppendLines(this SysPath filePath, IEnumerable lines) { - using (var sw = new StreamWriter(filePath, append: true)) - foreach (var line in lines) - sw.WriteLine(line); + using var sw = new StreamWriter(filePath, append: true); + foreach (var line in lines) + sw.WriteLine(line); return filePath; } diff --git a/csharp/Lib/SysTools/Process/AsyncProcess.cs b/csharp/Lib/SysTools/Process/AsyncProcess.cs index 3fb9e967f..ee0137482 100644 --- a/csharp/Lib/SysTools/Process/AsyncProcess.cs +++ b/csharp/Lib/SysTools/Process/AsyncProcess.cs @@ -9,6 +9,7 @@ namespace InnovEnergy.Lib.SysTools.Process; using Env = Dictionary; +[Obsolete("Use CliWrap instead")] public class AsyncProcess { private readonly Subject _StandardIn; diff --git a/csharp/Lib/SysTools/Process/ProcessResult.cs b/csharp/Lib/SysTools/Process/ProcessResult.cs index 162a2280d..e8af589b3 100644 --- a/csharp/Lib/SysTools/Process/ProcessResult.cs +++ b/csharp/Lib/SysTools/Process/ProcessResult.cs @@ -2,6 +2,7 @@ using InnovEnergy.Lib.SysTools.Utils; namespace InnovEnergy.Lib.SysTools.Process; +[Obsolete("Use CliWrap instead")] public readonly struct ProcessResult { public ProcessResult(Int32 exitCode, diff --git a/csharp/Lib/SysTools/Process/SyncProcess.cs b/csharp/Lib/SysTools/Process/SyncProcess.cs index 36caedf3a..7d47f447f 100644 --- a/csharp/Lib/SysTools/Process/SyncProcess.cs +++ b/csharp/Lib/SysTools/Process/SyncProcess.cs @@ -7,7 +7,7 @@ namespace InnovEnergy.Lib.SysTools.Process; using Env = Dictionary; - +[Obsolete("Use CliWrap instead")] public class SyncProcess { public SysCommand Command { get; } diff --git a/csharp/Lib/SysTools/Remote/RemoteCommand.cs b/csharp/Lib/SysTools/Remote/RemoteCommand.cs index 69e59d571..fa80d2671 100644 --- a/csharp/Lib/SysTools/Remote/RemoteCommand.cs +++ b/csharp/Lib/SysTools/Remote/RemoteCommand.cs @@ -2,6 +2,7 @@ using InnovEnergy.Lib.SysTools.Utils; namespace InnovEnergy.Lib.SysTools.Remote; +[Obsolete("Use CliWrap instead")] public readonly struct RemoteCommand { public SshHost Host { get; } diff --git a/csharp/Lib/SysTools/Remote/RemoteFileIo.cs b/csharp/Lib/SysTools/Remote/RemoteFileIo.cs index 1444b5539..e317d7227 100644 --- a/csharp/Lib/SysTools/Remote/RemoteFileIo.cs +++ b/csharp/Lib/SysTools/Remote/RemoteFileIo.cs @@ -3,6 +3,7 @@ using InnovEnergy.Lib.SysTools.Utils; namespace InnovEnergy.Lib.SysTools.Remote; +[Obsolete("Needs rework before use")] public static class RemoteFileIo { diff --git a/csharp/Lib/SysTools/Remote/RemotePath.cs b/csharp/Lib/SysTools/Remote/RemotePath.cs index 97b21da39..dcb75adb3 100644 --- a/csharp/Lib/SysTools/Remote/RemotePath.cs +++ b/csharp/Lib/SysTools/Remote/RemotePath.cs @@ -1,5 +1,6 @@ namespace InnovEnergy.Lib.SysTools.Remote; +[Obsolete] public readonly struct RemotePath { public SysPath Path { get; } diff --git a/csharp/Lib/SysTools/Remote/SshHost.cs b/csharp/Lib/SysTools/Remote/SshHost.cs index 5afade016..a957f2887 100644 --- a/csharp/Lib/SysTools/Remote/SshHost.cs +++ b/csharp/Lib/SysTools/Remote/SshHost.cs @@ -3,6 +3,7 @@ using InnovEnergy.Lib.SysTools.Utils; namespace InnovEnergy.Lib.SysTools.Remote; +[Obsolete("Needs rework before use")] public readonly struct SshHost { public const Int32 DefaultPort = 22; diff --git a/csharp/Lib/SysTools/SysCommand.cs b/csharp/Lib/SysTools/SysCommand.cs index 9d264c27d..50237a5d8 100644 --- a/csharp/Lib/SysTools/SysCommand.cs +++ b/csharp/Lib/SysTools/SysCommand.cs @@ -2,6 +2,7 @@ using InnovEnergy.Lib.SysTools.Utils; namespace InnovEnergy.Lib.SysTools; +[Obsolete("Use CliWrap instead")] public readonly struct SysCommand { public SysPath Path { get; } diff --git a/csharp/Lib/SysTools/SysDirs.cs b/csharp/Lib/SysTools/SysDirs.cs index 5c3c5bc68..c65d4e7b7 100644 --- a/csharp/Lib/SysTools/SysDirs.cs +++ b/csharp/Lib/SysTools/SysDirs.cs @@ -3,6 +3,7 @@ using static System.Environment.SpecialFolder; namespace InnovEnergy.Lib.SysTools; +[Obsolete] public static class SysDirs { diff --git a/csharp/Lib/SysTools/SysPath.cs b/csharp/Lib/SysTools/SysPath.cs index 383460ab8..b5ff40c36 100644 --- a/csharp/Lib/SysTools/SysPath.cs +++ b/csharp/Lib/SysTools/SysPath.cs @@ -5,6 +5,7 @@ using static System.IO.Path; namespace InnovEnergy.Lib.SysTools; +[Obsolete("Needs rework before use")] public readonly struct SysPath { private readonly String _Path; diff --git a/csharp/Lib/SysTools/SysTools.csproj b/csharp/Lib/SysTools/SysTools.csproj index 9fd38651b..629608dc6 100644 --- a/csharp/Lib/SysTools/SysTools.csproj +++ b/csharp/Lib/SysTools/SysTools.csproj @@ -5,4 +5,8 @@ + + + + diff --git a/csharp/Lib/SysTools/Utils/EnumerableUtils.cs b/csharp/Lib/SysTools/Utils/EnumerableUtils.cs index 16d6c8671..9f02caacf 100644 --- a/csharp/Lib/SysTools/Utils/EnumerableUtils.cs +++ b/csharp/Lib/SysTools/Utils/EnumerableUtils.cs @@ -5,14 +5,12 @@ internal static class EnumerableUtils public static IEnumerable Pad(this IEnumerable src, Int32 length, T padding) { - using (var enumerator = src.GetEnumerator()) - { - while (enumerator.MoveNext() && length-- > 0) - yield return enumerator.Current; + using var enumerator = src.GetEnumerator(); + while (enumerator.MoveNext() && length-- > 0) + yield return enumerator.Current; - while (length-- > 0) - yield return padding; - } + while (length-- > 0) + yield return padding; } public static Dictionary> IndexColumn(this IEnumerable> src, UInt16 index) @@ -33,10 +31,10 @@ internal static class EnumerableUtils public static IEnumerable<(TLeft left, TRight right)> Zip(IEnumerable left, IEnumerable right) { - using (var l = left.GetEnumerator()) - using (var r = right.GetEnumerator()) - while (l.MoveNext() && r.MoveNext()) - yield return (l.Current, r.Current); + using var l = left.GetEnumerator(); + using var r = right.GetEnumerator(); + while (l.MoveNext() && r.MoveNext()) + yield return (l.Current, r.Current); } public static IEnumerator Enumerator(this T t) @@ -57,20 +55,6 @@ internal static class EnumerableUtils action(e); } - public static IEnumerable Do(this IEnumerable enumerable, Action action) - { - return enumerable.Select(e => - { - action(e); - return e; - }); - } - - public static void ForEach(this IEnumerable enumerable, Func func) - { - foreach (var e in enumerable) - func(e); - } public static IEnumerable WhereNot(this IEnumerable enumerable, Func predicate) diff --git a/csharp/Lib/SysTools/Utils/Utils.cs b/csharp/Lib/SysTools/Utils/Utils.cs index 73e37198e..026c63e8c 100644 --- a/csharp/Lib/SysTools/Utils/Utils.cs +++ b/csharp/Lib/SysTools/Utils/Utils.cs @@ -2,55 +2,6 @@ namespace InnovEnergy.Lib.SysTools.Utils; public static class Utils { - public static IEnumerable Traverse(T root, Func> getChildren) - { - var stack = new Stack>(); - var it = root.Enumerator(); - it.MoveNext(); - - while (true) - { - //////// going down //////// - - while (true) - { - var cit = getChildren(it.Current).GetEnumerator(); - - if (cit.MoveNext()) // node has children, must be a branch - { - yield return it.Current; - - stack.Push(it); - it = cit; - } - else // no children, hence a leaf - { - var node = it.Current; - - yield return node; - - if (!it.MoveNext()) - break; // no more siblings: goto parent - } - } - - //////// going up //////// - - while (true) - { - it.Dispose(); - if (stack.Count == 0) yield break; // we got to the bottom of the stack, were done - - it = stack.Pop(); - - if (it.MoveNext()) - break; - } - } - - - } - private static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); @@ -59,7 +10,6 @@ public static class Utils return Epoch.AddSeconds(unixTime); } - public static R ValueOrDefault(this Dictionary dict, T key) { return ValueOrDefault(dict, key, default); diff --git a/csharp/Lib/Utils/Utils.cs b/csharp/Lib/Utils/Utils.cs index b07ab7111..f4e5deb88 100644 --- a/csharp/Lib/Utils/Utils.cs +++ b/csharp/Lib/Utils/Utils.cs @@ -76,8 +76,8 @@ public static class Utils var res = index % length; return res >= 0 - ? res - : res + length; + ? res + : res + length; } public static IEnumerable Traverse(this T root, Func> getChildren)