summaryrefslogtreecommitdiff
path: root/Services/FeedService.cs
diff options
context:
space:
mode:
authorJake Mannens <jake@asger.xyz>2023-10-20 14:26:02 +1100
committerJake Mannens <jake@asger.xyz>2023-10-20 14:26:02 +1100
commit02670870b2711db0984f492d452a90477c67608a (patch)
treea6c15f627535dd962042d2e000c093cf2ae63956 /Services/FeedService.cs
parent07728d1048f34e1d048da63684b341ab30bc1d06 (diff)
Gallery
Diffstat (limited to 'Services/FeedService.cs')
-rw-r--r--Services/FeedService.cs117
1 files changed, 74 insertions, 43 deletions
diff --git a/Services/FeedService.cs b/Services/FeedService.cs
index c66b9ee..b664d62 100644
--- a/Services/FeedService.cs
+++ b/Services/FeedService.cs
@@ -1,78 +1,109 @@
using Microsoft.EntityFrameworkCore;
-using System.Data.Common;
+using Microsoft.EntityFrameworkCore.Query;
namespace HyperBooru.Services;
-public enum FeedOrder {
+public enum FeedSortOrder {
+ Ascending,
+ Descending
+}
+
+public enum FeedSortType {
Chronological,
Rating
}
+public record FeedOptions {
+ public FeedSortType SortType { get; set; }
+ public FeedSortOrder SortOrder { get; set; }
+ public bool RandomPosition { get; set; }
+
+ public Func<IQueryable<Media>, IQueryable<Media>>? IncludeProperties { get; set; }
+}
+
public interface IFeedService {
public IEnumerable<Media> Feed { get; }
-
- public void InitializeFeed(
- FeedOrder order = FeedOrder.Chronological,
- bool descending = true,
- bool randomPosition = false);
+ public void InitializeFeed(FeedOptions feedOptions);
+ public Media[] Next(int count);
}
public class FeedService : IFeedService {
- private FeedConfiguration? feedConfig;
+ private const int FeedChunkSize = 50;
+
+ private FeedOptions? feedOptions;
+ private Media? last;
private IDbContextFactory<HBContext> dbFactory;
public FeedService(IDbContextFactory<HBContext> dbFactory) =>
this.dbFactory = dbFactory;
- public void InitializeFeed(
- FeedOrder order,
- bool descending,
- bool randomPosition) {
-
- feedConfig = new() {
- Order = order,
- Descending = descending,
- RandomPosition = randomPosition
- };
+ public void InitializeFeed(FeedOptions feedOptions) {
+ this.feedOptions = feedOptions;
+ last = null;
}
public IEnumerable<Media> Feed {
get {
- if(feedConfig is null)
- throw new InvalidOperationException("Feed must be initialized first");
-
+ last = null;
while(true) {
- var db = dbFactory.CreateDbContext();
+ var media = Next(FeedChunkSize);
+ if(media.Count() == 0)
+ break;
+ foreach(var m in media)
+ yield return m;
+ }
+ }
+ }
- IOrderedQueryable<Media> media;
+ public Media[] Next(int count) =>
+ NextDbChunk(Math.Abs(count), count < 0);
- switch(feedConfig.Order) {
- default:
- case FeedOrder.Chronological:
- if(feedConfig.Descending)
- media = db.Media.OrderByDescending(m => m.ObjectId);
+ private Media[] NextDbChunk(int chunkSize, bool reverse = false) {
+ if(feedOptions is null)
+ throw new InvalidOperationException("Feed must be initialized first");
+
+ while(true) {
+ var db = dbFactory.CreateDbContext();
+
+ IQueryable<Media> media = db.Media;
+
+ if(feedOptions.IncludeProperties is not null)
+ media = feedOptions.IncludeProperties(media);
+
+ var sortOrder = feedOptions.SortOrder;
+ if(reverse)
+ sortOrder = sortOrder == FeedSortOrder.Ascending
+ ? FeedSortOrder.Descending
+ : FeedSortOrder.Ascending;
+
+ if(last is not null) {
+ switch(feedOptions.SortType) {
+ case FeedSortType.Chronological:
+ if(sortOrder == FeedSortOrder.Descending)
+ media = media.Where(m => m.ObjectId < last.ObjectId);
else
- media = db.Media.OrderBy(m => m.ObjectId);
+ media = media.Where(m => m.ObjectId > last.ObjectId);
break;
}
+ media = media.Where(m => m.ObjectId != last.ObjectId);
+ }
- Media[] mediaArray = media.Take(50).ToArray();
-
- db.Dispose();
-
- if(mediaArray.Count() == 0)
+ switch(feedOptions.SortType) {
+ case FeedSortType.Chronological:
+ if(sortOrder == FeedSortOrder.Descending)
+ media = media.OrderByDescending(m => m.ObjectId);
+ else
+ media = media.OrderBy(m => m.ObjectId);
break;
-
- foreach(var m in mediaArray)
- yield return m;
}
- }
- }
- private record FeedConfiguration {
- public FeedOrder Order { get; set; }
- public bool Descending { get; set; }
- public bool RandomPosition { get; set; }
+ Media[] mediaArray = media
+ .Take(chunkSize)
+ .ToArray();
+
+ if(mediaArray.Count() != 0)
+ last = mediaArray.Last();
+ }
}
}