Skip to content

Commit a891389

Browse files
committed
Increase performance
On large operations, the whole DB was in memory. Like 0.5 GB of data sorted with LINQ. This commit makes the pagination happen on the DB. Yippe!
1 parent 1917124 commit a891389

File tree

2 files changed

+58
-43
lines changed

2 files changed

+58
-43
lines changed

Server/Api/ReplayController.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,17 +96,16 @@ public async Task<ActionResult> SearchReplays(
9696
return BadRequest("The page number cannot be negative.");
9797
}
9898

99-
var found = ReplayParser.SearchReplays(searchMode, query, _context);
99+
var found = ReplayParser.SearchReplays(searchMode, query, _context, page, Constants.ReplaysPerPage);
100+
100101
// Order found replays by date
101102
found = found.OrderByDescending(r => r.Date ?? DateTime.MinValue).Take(Constants.SearchLimit).ToList();
102103

103104
var pageCount = Paginator.GetPageCount(found.Count, Constants.ReplaysPerPage);
104-
var offset = Paginator.GetOffset(page, Constants.ReplaysPerPage);
105-
var paginated = found.Skip(offset).Take(Constants.ReplaysPerPage).ToList();
106105

107106
return Ok(new SearchResult()
108107
{
109-
Replays = paginated,
108+
Replays = found,
110109
PageCount = pageCount,
111110
CurrentPage = page,
112111
TotalReplays = found.Count

Server/ReplayParser.cs

Lines changed: 55 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -294,46 +294,62 @@ public static HttpClient CreateHttpClient()
294294
/// <exception cref="NotImplementedException">
295295
/// Thrown when the search mode is not implemented.
296296
/// </exception>
297-
public static List<Replay> SearchReplays(SearchMode mode, string query, ReplayDbContext context)
297+
public static List<Replay> SearchReplays(SearchMode mode, string query, ReplayDbContext context, int page, int pageSize)
298+
{
299+
var queryable = context.Replays.AsQueryable();
300+
301+
IIncludableQueryable<Player, Replay?>? players;
302+
IQueryable<int?>? replayIds;
303+
switch (mode)
298304
{
299-
var queryable = context.Replays.AsQueryable();
305+
case SearchMode.Map:
306+
queryable = queryable.Where(x => x.Map.ToLower().Contains(query.ToLower()));
307+
break;
308+
case SearchMode.Gamemode:
309+
queryable = queryable.Where(x => x.Gamemode.ToLower().Contains(query.ToLower()));
310+
break;
311+
case SearchMode.ServerId:
312+
queryable = queryable.Where(x => x.ServerId.ToLower().Contains(query.ToLower()));
313+
break;
314+
case SearchMode.Guid:
315+
players = context.Players
316+
.Where(p => p.PlayerGuid.ToString().ToLower().Contains(query.ToLower()))
317+
.Include(p => p.Replay);
318+
replayIds = players.Select(p => p.ReplayId).Distinct();
319+
queryable = context.Replays.Where(r => replayIds.Contains(r.Id));
320+
break;
321+
case SearchMode.PlayerIcName:
322+
players = context.Players
323+
.Where(p => p.PlayerIcName.ToLower().Contains(query.ToLower()))
324+
.Include(p => p.Replay);
325+
replayIds = players.Select(p => p.ReplayId).Distinct();
326+
queryable = context.Replays.Where(r => replayIds.Contains(r.Id));
327+
break;
328+
case SearchMode.PlayerOocName:
329+
players = Context.Players
330+
.Where(p => p.PlayerOocName.ToLower().Contains(query.ToLower()))
331+
.Include(p => p.Replay);
332+
replayIds = players.Select(p => p.ReplayId).Distinct();
333+
queryable = Context.Replays.Where(r => replayIds.Contains(r.Id));
334+
break;
335+
case SearchMode.RoundEndText:
336+
queryable = queryable.Where(x => x.RoundEndText != null && x.RoundEndText.ToLower().Contains(query.ToLower()));
337+
break;
338+
case SearchMode.ServerName:
339+
queryable = queryable.Where(x => x.ServerName != null && x.ServerName.ToLower().Contains(query.ToLower()));
340+
break;
341+
case SearchMode.RoundId:
342+
queryable = queryable.Where(x => x.RoundId != null && x.RoundId.ToString().Contains(query));
343+
break;
344+
default:
345+
throw new NotImplementedException();
346+
}
300347

301-
IIncludableQueryable<Player, Replay?>? players;
302-
IQueryable<int?>? replayIds;
303-
switch (mode)
304-
{
305-
case SearchMode.Map:
306-
return queryable.Where(x => x.Map.ToLower().Contains(query.ToLower())).Include(r => r.RoundEndPlayers).ToList();
307-
case SearchMode.Gamemode:
308-
return queryable.Where(x => x.Gamemode.ToLower().Contains(query.ToLower())).Include(r => r.RoundEndPlayers).ToList();
309-
case SearchMode.ServerId:
310-
return queryable.Where(x => x.ServerId.ToLower().Contains(query.ToLower())).Include(r => r.RoundEndPlayers).ToList();
311-
case SearchMode.Guid:
312-
players = context.Players
313-
.Where(p => p.PlayerGuid.ToString().ToLower().Contains(query.ToLower()))
314-
.Include(p => p.Replay);
315-
replayIds = players.Select(p => p.ReplayId).Distinct();
316-
return context.Replays.Where(r => replayIds.Contains(r.Id)).Include(r => r.RoundEndPlayers).ToList();
317-
case SearchMode.PlayerIcName:
318-
players = context.Players
319-
.Where(p => p.PlayerIcName.ToLower().Contains(query.ToLower()))
320-
.Include(p => p.Replay);
321-
replayIds = players.Select(p => p.ReplayId).Distinct();
322-
return context.Replays.Where(r => replayIds.Contains(r.Id)).Include(r => r.RoundEndPlayers).ToList();
323-
case SearchMode.PlayerOocName:
324-
players = Context.Players
325-
.Where(p => p.PlayerOocName.ToLower().Contains(query.ToLower()))
326-
.Include(p => p.Replay);
327-
replayIds = players.Select(p => p.ReplayId).Distinct();
328-
return Context.Replays.Where(r => replayIds.Contains(r.Id)).Include(r => r.RoundEndPlayers).ToList();
329-
case SearchMode.RoundEndText:
330-
return queryable.Where(x => x.RoundEndText != null && x.RoundEndText.ToLower().Contains(query.ToLower())).Include(r => r.RoundEndPlayers).ToList();
331-
case SearchMode.ServerName:
332-
return queryable.Where(x => x.ServerName != null && x.ServerName.ToLower().Contains(query.ToLower())).Include(r => r.RoundEndPlayers).ToList();
333-
case SearchMode.RoundId:
334-
return queryable.Where(x => x.RoundId != null && x.RoundId.ToString().Contains(query)).Include(r => r.RoundEndPlayers).ToList();
335-
default:
336-
throw new NotImplementedException();
337-
}
348+
// Apply pagination on the database query
349+
return queryable
350+
.Skip(page * pageSize)
351+
.Take(pageSize)
352+
.Include(r => r.RoundEndPlayers)
353+
.ToList();
338354
}
339355
}

0 commit comments

Comments
 (0)