From 12eaa5814ef20b0910e8d64a753378b6f6797989 Mon Sep 17 00:00:00 2001 From: Jake Mannens Date: Fri, 22 May 2026 00:52:16 +1000 Subject: Initial commit --- Util.cs | 120 ---------------------------------------------------------------- 1 file changed, 120 deletions(-) delete mode 100644 Util.cs (limited to 'Util.cs') diff --git a/Util.cs b/Util.cs deleted file mode 100644 index 6af6c81..0000000 --- a/Util.cs +++ /dev/null @@ -1,120 +0,0 @@ -namespace HyperBooru.Util; - -public static class Extensions { - public static readonly string[] MagnitudeOrders = new[] { - "K", "M", "G", "T", "P", "E", "Z", "Y", "R", "Q" - }; - - public static DateTime? TryParseDateTimeUtc(this string s) { - bool success = DateTime.TryParse(s, out var dateTime); - return success ? DateTime.SpecifyKind(dateTime, DateTimeKind.Utc) : null; - } - - public static string ToBytesSI(this long x) { - var exp = (int) Math.Log10(x); - var suffix = MagnitudeOrders.ElementAtOrDefault(exp / 3 - 1); - if(suffix is null) - return x.ToString(); - double n = x / Math.Pow(10, exp / 3 * 3); - return $"{Math.Round(n, 2 - (exp % 3))} {suffix}B"; - } - - public static string ToStringHumanReadable(this TimeSpan t) { - if(t.TotalMilliseconds < 1000) - return string.Format("{0:0}ms", t.TotalMilliseconds); - if(t.TotalSeconds < 60) - return string.Format("{0:0.00}s", t.TotalSeconds); - if(t.TotalMinutes < 60) - return string.Format("{0:0}m{0:0}s", t.TotalMinutes, t.Seconds); - if(t.TotalHours < 24) - return string.Format("{0:0}h{0:0}m", t.TotalHours, t.Minutes); - return string.Format("{0:0.00}d", t.TotalDays); - } -} - -public class LimitedConcurrencyTaskScheduler : TaskScheduler { - public sealed override int MaximumConcurrencyLevel => - maxConcurrency; - - private int maxConcurrency; - - [ThreadStatic] - private static bool threadIsProcessingItems; - - private readonly LinkedList tasks = new(); - - private int delegatesQueuedOrRunning = 0; - - public LimitedConcurrencyTaskScheduler() { - maxConcurrency = Environment.ProcessorCount; - } - - public LimitedConcurrencyTaskScheduler(int maxConcurrency) { - if(maxConcurrency < 1) - throw new ArgumentOutOfRangeException("maxConcurrency must be greater than 0"); - this.maxConcurrency = (int) maxConcurrency; - } - - protected sealed override void QueueTask(Task task) { - lock(tasks) { - tasks.AddLast(task); - if(delegatesQueuedOrRunning < maxConcurrency) { - delegatesQueuedOrRunning++; - NotifyThreadPoolOfPendingWork(); - } - } - } - - private void NotifyThreadPoolOfPendingWork() { - ThreadPool.UnsafeQueueUserWorkItem(_ => { - threadIsProcessingItems = true; - try { - while(true) { - Task item; - lock(tasks) { - if(tasks.Count == 0) { - delegatesQueuedOrRunning--; - break; - } else { - item = tasks.First.Value; - tasks.RemoveFirst(); - } - } - TryExecuteTask(item); - } - } finally { - threadIsProcessingItems = false; - } - }, null); - } - - protected sealed override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued) { - if(!threadIsProcessingItems) - return false; - - if(taskWasPreviouslyQueued) - return TryDequeue(task) ? TryExecuteTask(task) : false; - else - return TryExecuteTask(task); - } - - protected sealed override bool TryDequeue(Task task) { - lock(tasks) { - return tasks.Remove(task); - } - } - - protected sealed override IEnumerable GetScheduledTasks() { - bool lockTaken = false; - try { - Monitor.TryEnter(tasks, ref lockTaken); - if(lockTaken) - return tasks; - else - throw new NotSupportedException(); - } finally { - if(lockTaken) - Monitor.Exit(tasks); - } - } -} -- cgit v1.3