From 02b80a1a2ae3bca0009030907c8b5a6b27bc7e7b Mon Sep 17 00:00:00 2001 From: Laura Hausmann Date: Tue, 26 Mar 2024 20:07:30 +0100 Subject: [PATCH] [backend/core] Skip database queries for 0 member collections --- .../Mastodon/Renderers/NoteRenderer.cs | 31 +++++++++++++------ .../Renderers/NotificationRenderer.cs | 4 ++- .../Mastodon/Renderers/UserRenderer.cs | 1 + .../Controllers/Renderers/NoteRenderer.cs | 10 ++++-- 4 files changed, 32 insertions(+), 14 deletions(-) diff --git a/Iceshrimp.Backend/Controllers/Mastodon/Renderers/NoteRenderer.cs b/Iceshrimp.Backend/Controllers/Mastodon/Renderers/NoteRenderer.cs index 294b4533..63564ed5 100644 --- a/Iceshrimp.Backend/Controllers/Mastodon/Renderers/NoteRenderer.cs +++ b/Iceshrimp.Backend/Controllers/Mastodon/Renderers/NoteRenderer.cs @@ -119,8 +119,9 @@ public class NoteRenderer( return res; } - private async Task> GetMentions(IEnumerable notes) + private async Task> GetMentions(List notes) { + if (notes.Count == 0) return []; var ids = notes.SelectMany(n => n.Mentions).Distinct(); return await db.Users.IncludeCommonProperties() .Where(p => ids.Contains(p.Id)) @@ -128,8 +129,9 @@ public class NoteRenderer( .ToListAsync(); } - private async Task> GetAttachments(IEnumerable notes) + private async Task> GetAttachments(List notes) { + if (notes.Count == 0) return []; var ids = notes.SelectMany(n => n.FileIds).Distinct(); return await db.DriveFiles.Where(p => ids.Contains(p.Id)) .Select(f => new AttachmentEntity @@ -146,14 +148,16 @@ public class NoteRenderer( .ToListAsync(); } - internal async Task> GetAccounts(IEnumerable users) + internal async Task> GetAccounts(List users) { + if (users.Count == 0) return []; return (await userRenderer.RenderManyAsync(users.DistinctBy(p => p.Id))).ToList(); } - private async Task> GetLikedNotes(IEnumerable notes, User? user) + private async Task> GetLikedNotes(List notes, User? user) { if (user == null) return []; + if (notes.Count == 0) return []; return await db.NoteLikes.Where(p => p.User == user && notes.Contains(p.Note)) .Select(p => p.NoteId) .ToListAsync(); @@ -162,6 +166,7 @@ public class NoteRenderer( private async Task> GetReactions(List notes, User? user) { if (user == null) return []; + if (notes.Count == 0) return []; var counts = notes.ToDictionary(p => p.Id, p => p.Reactions); var res = await db.NoteReactions .Where(p => notes.Contains(p.Note)) @@ -190,26 +195,29 @@ public class NoteRenderer( return res; } - private async Task> GetBookmarkedNotes(IEnumerable notes, User? user) + private async Task> GetBookmarkedNotes(List notes, User? user) { if (user == null) return []; + if (notes.Count == 0) return []; return await db.NoteBookmarks.Where(p => p.User == user && notes.Contains(p.Note)) .Select(p => p.NoteId) .ToListAsync(); } - private async Task> GetPinnedNotes(IEnumerable notes, User? user) + private async Task> GetPinnedNotes(List notes, User? user) { if (user == null) return []; + if (notes.Count == 0) return []; return await db.UserNotePins.Where(p => p.User == user && notes.Contains(p.Note)) .Select(p => p.NoteId) .ToListAsync(); } - private async Task> GetRenotes(IEnumerable notes, User? user) + private async Task> GetRenotes(List notes, User? user) { if (user == null) return []; - return await db.Notes.Where(p => p.User == user && p.IsPureRenote && notes.Contains(p.Renote)) + if (notes.Count == 0) return []; + return await db.Notes.Where(p => p.User == user && p.IsPureRenote && notes.Contains(p.Renote!)) .Select(p => p.RenoteId) .Where(p => p != null) .Distinct() @@ -217,8 +225,9 @@ public class NoteRenderer( .ToListAsync(); } - private async Task> GetPolls(IEnumerable notes, User? user) + private async Task> GetPolls(List notes, User? user) { + if (notes.Count == 0) return []; var polls = await db.Polls.Where(p => notes.Contains(p.Note)) .ToListAsync(); @@ -252,10 +261,12 @@ public class NoteRenderer( .Cast() .DistinctBy(p => p.Id) .ToList(); + + if (noteList.Count == 0) return []; var data = new NoteRendererDto { - Accounts = accounts ?? await GetAccounts(noteList.Select(p => p.User)), + Accounts = accounts ?? await GetAccounts(noteList.Select(p => p.User).ToList()), Mentions = await GetMentions(noteList), Attachments = await GetAttachments(noteList), Polls = await GetPolls(noteList, user), diff --git a/Iceshrimp.Backend/Controllers/Mastodon/Renderers/NotificationRenderer.cs b/Iceshrimp.Backend/Controllers/Mastodon/Renderers/NotificationRenderer.cs index 170575ec..9a7f36d4 100644 --- a/Iceshrimp.Backend/Controllers/Mastodon/Renderers/NotificationRenderer.cs +++ b/Iceshrimp.Backend/Controllers/Mastodon/Renderers/NotificationRenderer.cs @@ -41,6 +41,7 @@ public class NotificationRenderer(NoteRenderer noteRenderer, UserRenderer userRe ) { var notificationList = notifications.ToList(); + if (notificationList.Count == 0) return []; var accounts = await noteRenderer.GetAccounts(notificationList.Where(p => p.Notifier != null) .Select(p => p.Notifier) @@ -49,7 +50,8 @@ public class NotificationRenderer(NoteRenderer noteRenderer, UserRenderer userRe .Select(p => p.Note?.Renote?.User) .Where(p => p != null)) .Cast() - .DistinctBy(p => p.Id)); + .DistinctBy(p => p.Id) + .ToList()); var notes = await noteRenderer.RenderManyAsync(notificationList.Where(p => p.Note != null) .Select(p => p.Note) diff --git a/Iceshrimp.Backend/Controllers/Mastodon/Renderers/UserRenderer.cs b/Iceshrimp.Backend/Controllers/Mastodon/Renderers/UserRenderer.cs index a3c51f82..cc0a0d27 100644 --- a/Iceshrimp.Backend/Controllers/Mastodon/Renderers/UserRenderer.cs +++ b/Iceshrimp.Backend/Controllers/Mastodon/Renderers/UserRenderer.cs @@ -104,6 +104,7 @@ public class UserRenderer(IOptions config, MfmConverter public async Task> RenderManyAsync(IEnumerable users) { var userList = users.ToList(); + if (userList.Count == 0) return []; var emoji = await GetEmoji(userList); return await userList.Select(p => RenderAsync(p, emoji)).AwaitAllAsync(); } diff --git a/Iceshrimp.Backend/Controllers/Renderers/NoteRenderer.cs b/Iceshrimp.Backend/Controllers/Renderers/NoteRenderer.cs index f5e03524..5f4c9fcb 100644 --- a/Iceshrimp.Backend/Controllers/Renderers/NoteRenderer.cs +++ b/Iceshrimp.Backend/Controllers/Renderers/NoteRenderer.cs @@ -1,4 +1,4 @@ -using Iceshrimp.Backend.Controllers.Schemas; + using Iceshrimp.Backend.Controllers.Schemas; using Iceshrimp.Backend.Core.Database; using Iceshrimp.Backend.Core.Database.Tables; using Iceshrimp.Backend.Core.Extensions; @@ -69,14 +69,16 @@ public class NoteRenderer(UserRenderer userRenderer, DatabaseContext db, EmojiSe _ => throw new ArgumentOutOfRangeException(nameof(visibility), visibility, null) }; - private async Task> GetUsers(IEnumerable notesList) + private async Task> GetUsers(List notesList) { + if (notesList.Count == 0) return []; var users = notesList.Select(p => p.User).DistinctBy(p => p.Id); return await userRenderer.RenderMany(users).ToListAsync(); } - private async Task> GetAttachments(IEnumerable notesList) + private async Task> GetAttachments(List notesList) { + if (notesList.Count == 0) return []; var ids = notesList.SelectMany(p => p.FileIds).Distinct(); var files = await db.DriveFiles.Where(p => ids.Contains(p.Id)).ToListAsync(); return files.Select(p => new NoteAttachment @@ -93,6 +95,7 @@ public class NoteRenderer(UserRenderer userRenderer, DatabaseContext db, EmojiSe private async Task> GetReactions(List notes, User? user) { if (user == null) return []; + if (notes.Count == 0) return []; var counts = notes.ToDictionary(p => p.Id, p => p.Reactions); var res = await db.NoteReactions .Where(p => notes.Contains(p.Note)) @@ -130,6 +133,7 @@ public class NoteRenderer(UserRenderer userRenderer, DatabaseContext db, EmojiSe public async Task> RenderMany(IEnumerable notes, User? user) { var notesList = notes.ToList(); + if (notesList.Count == 0) return []; var allNotes = GetAllNotes(notesList); var data = new NoteRendererDto {