From be6dc557a3b819248b014992eb96c1cb21f8112b Mon Sep 17 00:00:00 2001 From: vnugent Date: Sun, 8 Jan 2023 14:44:01 -0500 Subject: Initial commit --- Plugins.Essentials/src/TimestampedCounter.cs | 117 +++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 Plugins.Essentials/src/TimestampedCounter.cs (limited to 'Plugins.Essentials/src/TimestampedCounter.cs') diff --git a/Plugins.Essentials/src/TimestampedCounter.cs b/Plugins.Essentials/src/TimestampedCounter.cs new file mode 100644 index 0000000..19cb8ec --- /dev/null +++ b/Plugins.Essentials/src/TimestampedCounter.cs @@ -0,0 +1,117 @@ +/* +* Copyright (c) 2022 Vaughn Nugent +* +* Library: VNLib +* Package: VNLib.Plugins.Essentials +* File: TimestampedCounter.cs +* +* TimestampedCounter.cs is part of VNLib.Plugins.Essentials which is part of the larger +* VNLib collection of libraries and utilities. +* +* VNLib.Plugins.Essentials is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License as +* published by the Free Software Foundation, either version 3 of the +* License, or (at your option) any later version. +* +* VNLib.Plugins.Essentials is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Affero General Public License for more details. +* +* You should have received a copy of the GNU Affero General Public License +* along with this program. If not, see https://www.gnu.org/licenses/. +*/ + +using System; + + +#nullable enable + +namespace VNLib.Plugins.Essentials +{ + /// + /// Stucture that allows for convient storage of a counter value + /// and a second precision timestamp into a 64-bit unsigned integer + /// + public readonly struct TimestampedCounter : IEquatable + { + /// + /// The time the count was last modifed + /// + public readonly DateTimeOffset LastModified; + /// + /// The last failed login attempt count value + /// + public readonly uint Count; + + /// + /// Initalizes a new flc structure with the current UTC date + /// and the specified count value + /// + /// FLC current count + public TimestampedCounter(uint count) : this(DateTimeOffset.UtcNow, count) + { } + + private TimestampedCounter(DateTimeOffset dto, uint count) + { + Count = count; + LastModified = dto; + } + + /// + /// Compacts and converts the counter value and timestamp into + /// a 64bit unsigned integer + /// + /// The counter to convert + public static explicit operator ulong(TimestampedCounter count) => count.ToUInt64(); + + /// + /// Compacts and converts the counter value and timestamp into + /// a 64bit unsigned integer + /// + /// The uint64 compacted value + public ulong ToUInt64() + { + //Upper 32 bits time, lower 32 bits count + ulong value = (ulong)LastModified.ToUnixTimeSeconds() << 32; + value |= Count; + return value; + } + + /// + /// The previously compacted + /// value to cast back to a counter + /// + /// + public static explicit operator TimestampedCounter(ulong value) => FromUInt64(value); + + /// + public override bool Equals(object? obj) => obj is TimestampedCounter counter && Equals(counter); + /// + public override int GetHashCode() => this.ToUInt64().GetHashCode(); + /// + public static bool operator ==(TimestampedCounter left, TimestampedCounter right) => left.Equals(right); + /// + public static bool operator !=(TimestampedCounter left, TimestampedCounter right) => !(left == right); + /// + public bool Equals(TimestampedCounter other) => ToUInt64() == other.ToUInt64(); + + /// + /// The previously compacted + /// value to cast back to a counter + /// + /// The uint64 encoded + /// + /// The decoded from its + /// compatcted representation + /// + public static TimestampedCounter FromUInt64(ulong value) + { + //Upper 32 bits time, lower 32 bits count + long time = (long)(value >> 32); + uint count = (uint)(value & uint.MaxValue); + //Init dto struct + return new(DateTimeOffset.FromUnixTimeSeconds(time), count); + } + } +} \ No newline at end of file -- cgit