Refactor SplitIntoPartitions

pull/123/head
Oleksii Holub 6 years ago
parent 0b14952346
commit 8bc29c4928

@ -1,6 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
namespace DiscordChatExporter.Core.Models namespace DiscordChatExporter.Core.Models
{ {
@ -33,45 +31,5 @@ namespace DiscordChatExporter.Core.Models
throw new ArgumentOutOfRangeException(nameof(format)); throw new ArgumentOutOfRangeException(nameof(format));
} }
public static IReadOnlyList<ChatLog> SplitIntoPartitions(this ChatLog chatLog, int partitionLimit)
{
// If chat log has fewer messages than the limit - just return chat log in a list
if (chatLog.Messages.Count <= partitionLimit)
return new[] {chatLog};
var result = new List<ChatLog>();
// Loop through messages
var buffer = new List<Message>();
foreach (var message in chatLog.Messages)
{
// Add message to buffer
buffer.Add(message);
// If reached the limit - split and reset buffer
if (buffer.Count >= partitionLimit)
{
// Add to result
var chatLogPartition = new ChatLog(chatLog.Guild, chatLog.Channel, chatLog.From, chatLog.To, buffer,
chatLog.Mentionables);
result.Add(chatLogPartition);
// Reset the buffer instead of clearing to avoid mutations on existing references
buffer = new List<Message>();
}
}
// Add what's remaining in buffer
if (buffer.Any())
{
// Add to result
var chatLogPartition = new ChatLog(chatLog.Guild, chatLog.Channel, chatLog.From, chatLog.To, buffer,
chatLog.Mentionables);
result.Add(chatLogPartition);
}
return result;
}
} }
} }

@ -83,6 +83,34 @@ namespace DiscordChatExporter.Core.Services
} }
} }
private IReadOnlyList<ChatLog> SplitIntoPartitions(ChatLog chatLog, int partitionLimit)
{
var result = new List<ChatLog>();
// Loop through all messages with an increment of partition limit
for (var i = 0; i < chatLog.Messages.Count; i += partitionLimit)
{
// Calculate how many messages left in total
var remainingMessageCount = chatLog.Messages.Count - i;
// Decide how many messages are going into this partition
// Each partition will have the same number of messages except the last one that might have fewer (all remaining messages)
var partitionMessageCount = partitionLimit.ClampMax(remainingMessageCount);
// Get messages that belong to this partition
var partitionMessages = new List<Message>();
for (var j = i; j < i + partitionMessageCount; j++)
partitionMessages.Add(chatLog.Messages[j]);
// Create a partition and add to list
var partition = new ChatLog(chatLog.Guild, chatLog.Channel, chatLog.From, chatLog.To, partitionMessages,
chatLog.Mentionables);
result.Add(partition);
}
return result;
}
public void ExportChatLog(ChatLog chatLog, string filePath, ExportFormat format, public void ExportChatLog(ChatLog chatLog, string filePath, ExportFormat format,
int? partitionLimit = null) int? partitionLimit = null)
{ {
@ -94,7 +122,7 @@ namespace DiscordChatExporter.Core.Services
// Otherwise split into partitions and export separately // Otherwise split into partitions and export separately
else else
{ {
var partitions = chatLog.SplitIntoPartitions(partitionLimit.Value); var partitions = SplitIntoPartitions(chatLog, partitionLimit.Value);
ExportChatLogPartitions(partitions, filePath, format); ExportChatLogPartitions(partitions, filePath, format);
} }
} }

Loading…
Cancel
Save