From 7e8a9d1e29d943802a20db9bdf6ba8dd7ee57a3c Mon Sep 17 00:00:00 2001
From: Andy Pack <andy@sarsoo.xyz>
Date: Mon, 31 Mar 2025 21:34:30 +0100
Subject: [PATCH] moving resampler

---
 Selector/Listen/Resampler.cs   | 130 +++++++++++++++++++++++++++++++++
 Selector/Scrobble/Resampler.cs | 130 ---------------------------------
 2 files changed, 130 insertions(+), 130 deletions(-)
 create mode 100644 Selector/Listen/Resampler.cs
 delete mode 100644 Selector/Scrobble/Resampler.cs

diff --git a/Selector/Listen/Resampler.cs b/Selector/Listen/Resampler.cs
new file mode 100644
index 0000000..1a4db69
--- /dev/null
+++ b/Selector/Listen/Resampler.cs
@@ -0,0 +1,130 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Selector
+{
+    public record struct CountSample
+    {
+        public DateTime TimeStamp { get; set; }
+        public int Value { get; set; }
+    }
+
+    public static class Resampler
+    {
+        public static IEnumerable<CountSample> Resample(this IEnumerable<IListen> scrobbles, TimeSpan window)
+        {
+            var sortedScrobbles = scrobbles.OrderBy(s => s.Timestamp).ToList();
+
+            if (!sortedScrobbles.Any())
+            {
+                yield break;
+            }
+
+            var sortedScrobblesIter = sortedScrobbles.GetEnumerator();
+            sortedScrobblesIter.MoveNext();
+
+            var earliest = sortedScrobbles.First().Timestamp;
+            var latest = sortedScrobbles.Last().Timestamp;
+
+            yield return new CountSample()
+            {
+                TimeStamp = earliest - (window / 2),
+                Value = 0
+            };
+
+            var enumeratorExhausted = false;
+
+            for (var windowStart = earliest; windowStart <= latest; windowStart += window)
+            {
+                var windowEnd = windowStart + window;
+
+                var count = 0;
+                var windowOverran = false;
+
+                while (!windowOverran && !enumeratorExhausted)
+                {
+                    if (windowStart <= sortedScrobblesIter.Current.Timestamp)
+                    {
+                        if (sortedScrobblesIter.Current.Timestamp < windowEnd)
+                        {
+                            count++;
+                            if (!sortedScrobblesIter.MoveNext())
+                            {
+                                enumeratorExhausted = true;
+                            }
+                        }
+                        else
+                        {
+                            windowOverran = true;
+                        }
+                    }
+                }
+
+                yield return new CountSample()
+                {
+                    TimeStamp = windowStart + (window / 2),
+                    Value = count
+                };
+            }
+        }
+
+        public static IEnumerable<CountSample> ResampleByMonth(this IEnumerable<IListen> scrobbles)
+        {
+            var sortedScrobbles = scrobbles.OrderBy(s => s.Timestamp).ToList();
+
+            if (!sortedScrobbles.Any())
+            {
+                yield break;
+            }
+
+            var sortedScrobblesIter = sortedScrobbles.GetEnumerator();
+            sortedScrobblesIter.MoveNext();
+
+            var earliest = sortedScrobbles.First().Timestamp;
+            var latest = sortedScrobbles.Last().Timestamp;
+            var latestPlusMonth = latest.AddMonths(1);
+
+            var periodStart = new DateTime(earliest.Year, earliest.Month, 1);
+            var periodEnd = new DateTime(latestPlusMonth.Year, latestPlusMonth.Month, 1);
+
+            for (var counter = periodStart; counter <= periodEnd; counter = counter.AddMonths(1))
+            {
+                var count = 0;
+
+                if (sortedScrobblesIter.Current is not null)
+                {
+                    count++;
+                }
+
+                while (sortedScrobblesIter.MoveNext()
+                       && sortedScrobblesIter.Current.Timestamp.Year == counter.Year
+                       && sortedScrobblesIter.Current.Timestamp.Month == counter.Month)
+                {
+                    count++;
+                }
+
+                yield return new CountSample()
+                {
+                    TimeStamp = counter,
+                    Value = count
+                };
+            }
+        }
+
+        public static IEnumerable<CountSample> CumulativeSum(this IEnumerable<CountSample> samples)
+        {
+            var sum = 0;
+            foreach (var sample in samples)
+            {
+                sum += sample.Value;
+
+                yield return new CountSample
+                {
+                    TimeStamp = sample.TimeStamp,
+                    Value = sum
+                };
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/Selector/Scrobble/Resampler.cs b/Selector/Scrobble/Resampler.cs
deleted file mode 100644
index 7289d15..0000000
--- a/Selector/Scrobble/Resampler.cs
+++ /dev/null
@@ -1,130 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Selector
-{
-	public record struct CountSample {
-		public DateTime TimeStamp { get; set; }
-		public int Value { get; set; }
-	}
-
-	public static class Resampler
-	{
-		public static IEnumerable<CountSample> Resample(this IEnumerable<IListen> scrobbles, TimeSpan window)
-		{
-			var sortedScrobbles = scrobbles.OrderBy(s => s.Timestamp).ToList();
-
-			if (!sortedScrobbles.Any())
-			{
-				yield break;
-			}
-
-            var sortedScrobblesIter = sortedScrobbles.GetEnumerator();
-			sortedScrobblesIter.MoveNext();
-
-			var earliest = sortedScrobbles.First().Timestamp;
-			var latest = sortedScrobbles.Last().Timestamp;
-
-            yield return new CountSample()
-            {
-                TimeStamp = earliest - (window / 2),
-                Value = 0
-            };
-
-            var enumeratorExhausted = false;
-
-			for (var windowStart = earliest; windowStart <= latest; windowStart += window)
-			{
-				var windowEnd = windowStart + window;
-
-				var count = 0;
-				var windowOverran = false;
-
-				while(!windowOverran && !enumeratorExhausted)
-                {
-					if (windowStart <= sortedScrobblesIter.Current.Timestamp)
-					{
-						if(sortedScrobblesIter.Current.Timestamp < windowEnd)
-                        {
-							count++;
-							if (!sortedScrobblesIter.MoveNext())
-                            {
-								enumeratorExhausted = true;
-							}
-						}
-						else
-                        {
-							windowOverran = true;
-                        }
-					}
-				}
-
-				yield return new CountSample()
-				{
-					TimeStamp = windowStart + (window / 2),
-					Value = count
-				};
-			}
-		}
-
-		public static IEnumerable<CountSample> ResampleByMonth(this IEnumerable<IListen> scrobbles)
-		{
-			var sortedScrobbles = scrobbles.OrderBy(s => s.Timestamp).ToList();
-
-			if (!sortedScrobbles.Any())
-			{
-				yield break;
-			}
-
-			var sortedScrobblesIter = sortedScrobbles.GetEnumerator();
-			sortedScrobblesIter.MoveNext();
-
-			var earliest = sortedScrobbles.First().Timestamp;
-			var latest = sortedScrobbles.Last().Timestamp;
-			var latestPlusMonth = latest.AddMonths(1);
-
-			var periodStart = new DateTime(earliest.Year, earliest.Month, 1);
-			var periodEnd = new DateTime(latestPlusMonth.Year, latestPlusMonth.Month, 1);
-
-			for (var counter = periodStart; counter <= periodEnd; counter = counter.AddMonths(1))
-			{
-				var count = 0;
-
-				if (sortedScrobblesIter.Current is not null)
-				{
-					count++;
-				}
-
-				while (sortedScrobblesIter.MoveNext()
-					&& sortedScrobblesIter.Current.Timestamp.Year == counter.Year
-					&& sortedScrobblesIter.Current.Timestamp.Month == counter.Month)
-				{
-					count++;
-				}
-
-				yield return new CountSample()
-				{
-					TimeStamp = counter,
-					Value = count
-				};
-			}
-		}
-
-		public static IEnumerable<CountSample> CumulativeSum(this IEnumerable<CountSample> samples)
-		{
-			var sum = 0;
-			foreach(var sample in samples)
-            {
-				sum += sample.Value;
-
-				yield return new CountSample
-				{
-					TimeStamp = sample.TimeStamp,
-					Value = sum
-                };
-            }
-		}
-	}
-}
-