first commit
This commit is contained in:
122
DCIT.Core/Services/BatchExecutionPlanner.cs
Normal file
122
DCIT.Core/Services/BatchExecutionPlanner.cs
Normal file
@@ -0,0 +1,122 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using DCIT.Core.Models;
|
||||
|
||||
namespace DCIT.Core.Services
|
||||
{
|
||||
public sealed class BatchExecutionPlanner
|
||||
{
|
||||
public BatchExecutionPlan CreatePlan(IList<FileScanItem> selectedItems, int processorCount)
|
||||
{
|
||||
var executionItems = new List<FileScanItem>();
|
||||
var skippedItems = new List<BatchExecutionSkipItem>();
|
||||
var sourcePaths = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
var outputPaths = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
var diffPaths = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
if (selectedItems != null)
|
||||
{
|
||||
foreach (var item in selectedItems)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var sourcePath = NormalizePath(item.SourcePath);
|
||||
var outputPath = NormalizePath(item.OutputPath);
|
||||
var diffPath = NormalizePath(item.DiffPath);
|
||||
|
||||
var collision = GetCollision(sourcePath, sourcePaths, BatchExecutionSkipReason.DuplicateSourcePath);
|
||||
if (collision == null)
|
||||
{
|
||||
collision = GetCollision(outputPath, outputPaths, BatchExecutionSkipReason.DuplicateOutputPath);
|
||||
}
|
||||
|
||||
if (collision == null && !string.IsNullOrWhiteSpace(diffPath))
|
||||
{
|
||||
collision = GetCollision(diffPath, diffPaths, BatchExecutionSkipReason.DuplicateDiffPath);
|
||||
}
|
||||
|
||||
if (collision != null)
|
||||
{
|
||||
collision.Item = item;
|
||||
skippedItems.Add(collision);
|
||||
continue;
|
||||
}
|
||||
|
||||
AddIfPresent(sourcePaths, sourcePath);
|
||||
AddIfPresent(outputPaths, outputPath);
|
||||
AddIfPresent(diffPaths, diffPath);
|
||||
executionItems.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
var requiresSerialExecution = executionItems.Any(item => Path.GetExtension(item.SourcePath).Equals(".doc", StringComparison.OrdinalIgnoreCase));
|
||||
var degreeOfParallelism = DetermineDegreeOfParallelism(executionItems.Count, processorCount, requiresSerialExecution);
|
||||
|
||||
return new BatchExecutionPlan
|
||||
{
|
||||
ExecutionItems = executionItems,
|
||||
SkippedItems = skippedItems,
|
||||
DegreeOfParallelism = degreeOfParallelism,
|
||||
RequiresSerialExecution = requiresSerialExecution,
|
||||
};
|
||||
}
|
||||
|
||||
private static BatchExecutionSkipItem GetCollision(string path, HashSet<string> existingPaths, BatchExecutionSkipReason reason)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(path) || !existingPaths.Contains(path))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new BatchExecutionSkipItem
|
||||
{
|
||||
Reason = reason,
|
||||
ConflictingPath = path,
|
||||
ExistingPath = path,
|
||||
};
|
||||
}
|
||||
|
||||
private static void AddIfPresent(HashSet<string> set, string path)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(path))
|
||||
{
|
||||
set.Add(path);
|
||||
}
|
||||
}
|
||||
|
||||
private static int DetermineDegreeOfParallelism(int itemCount, int processorCount, bool requiresSerialExecution)
|
||||
{
|
||||
if (itemCount <= 0 || requiresSerialExecution)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
var normalizedProcessorCount = processorCount > 0 ? processorCount : Environment.ProcessorCount;
|
||||
normalizedProcessorCount = Math.Max(1, normalizedProcessorCount);
|
||||
return Math.Max(1, Math.Min(itemCount, normalizedProcessorCount));
|
||||
}
|
||||
|
||||
private static string NormalizePath(string path)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return Path.GetFullPath(path)
|
||||
.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return path.Trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user