diff --git a/src/SnapDB/Snap/Services/Writer/ArchiveInitializer.cs b/src/SnapDB/Snap/Services/Writer/ArchiveInitializer.cs
index 8d33fe6d..e7b8ebc3 100644
--- a/src/SnapDB/Snap/Services/Writer/ArchiveInitializer.cs
+++ b/src/SnapDB/Snap/Services/Writer/ArchiveInitializer.cs
@@ -211,14 +211,134 @@ private string GetPathWithEnoughSpace(long estimatedSize)
long remainingSpace = Settings.DesiredRemainingSpace;
- foreach (string path in Settings.WritePath)
+ if (Settings.BalancingMethod == BalancingMethod.FillToDesired)
{
- FilePath.GetAvailableFreeSpace(path, out long freeSpace, out _);
+ foreach (string path in Settings.WritePath)
+ {
+ FilePath.GetAvailableFreeSpace(path, out long freeSpace, out _);
+
+ //If there is space, fill it.
+ if (freeSpace - estimatedSize > remainingSpace)
+ return path;
+
+ }
+ }
+
+ if (Settings.BalancingMethod == BalancingMethod.FillSmallestAvailable)
+ {
+ long current = 0;
+ string smallest = null;
+
+ foreach (string path in Settings.WritePath)
+ {
+ FilePath.GetAvailableFreeSpace(path, out long freeSpace, out _);
+
+ // Checks to ensure that this path has enough available space to write to
+ if (freeSpace - estimatedSize < remainingSpace)
+ continue;
+
+ // If the path we are checking has less free space than the previous path, that becomes the path with the least available space.
+ if (freeSpace < current)
+ {
+ smallest = path;
+ current = freeSpace;
+ }
+ }
+
+ if (!string.IsNullOrEmpty(smallest))
+ return smallest;
+ }
+
+ if (Settings.BalancingMethod == BalancingMethod.FillLargestAvailable)
+ {
+ long current = 0;
+ string largest = null;
+
+ foreach (string path in Settings.WritePath)
+ {
+ FilePath.GetAvailableFreeSpace(path, out long freeSpace, out _);
+
+ if (freeSpace - estimatedSize < remainingSpace)
+ continue;
+
+ // If the path we are checking has more free space than the previous path, that becomes the path with the most available space.
+ if (freeSpace > current)
+ {
+ largest = path;
+ current = freeSpace;
+ }
+ }
+
+ if(!string.IsNullOrEmpty(largest))
+ return largest;
- if (freeSpace - estimatedSize > remainingSpace)
- return path;
}
+ if (Settings.BalancingMethod == BalancingMethod.FillLargestTotal)
+ {
+ long current = 0;
+
+ string largestTotal = null;
+
+ foreach (string path in Settings.WritePath)
+ {
+ FilePath.GetAvailableFreeSpace(path, out long freeSpace, out long totalSize);
+
+ if (freeSpace - estimatedSize < remainingSpace)
+ continue;
+
+ // If the path we are looking at has a greater total size than the previous one, it becomes the largestTotal.
+ if (totalSize > current)
+ {
+ largestTotal = path;
+ current = freeSpace;
+ }
+
+ }
+
+ if (!string.IsNullOrEmpty(largestTotal))
+ return largestTotal;
+ }
+
+ if (Settings.BalancingMethod == BalancingMethod.FillToMatchingPercentage)
+ {
+ // what percentage of the current path is left free
+ long currentRemainingPercentage;
+ // the occupancy percentage of the most empty space
+ long fullestPercentage = 0;
+ // the location that needs to be filled, i.e. the location with the emptiestPercentage
+ string toFill = null;
+
+ foreach (string path in Settings.WritePath)
+ {
+ FilePath.GetAvailableFreeSpace(path, out long freeSpace, out long totalSize);
+
+ if (freeSpace - estimatedSize < remainingSpace)
+ continue;
+
+ currentRemainingPercentage = freeSpace / totalSize;
+
+ // Compares the percentage that is free to the fullestPercentage
+ if (currentRemainingPercentage == fullestPercentage)
+ continue;
+
+ // If the remaining percentage of available space for this path is greater than the remaining percentage of the
+ // previous one, this occupancy percentage becomes the standard for the rest to be compared to.
+ if (currentRemainingPercentage > fullestPercentage)
+ fullestPercentage = currentRemainingPercentage;
+
+ // If the remaining percentage of available space for this path is smaller than the remaining percentage of the
+ // fullest path, this path must be filled to that standard.
+ if (currentRemainingPercentage < fullestPercentage)
+ toFill = path;
+ }
+
+ if (!string.IsNullOrEmpty(toFill))
+ return toFill;
+ }
+
+ //for pct, calculate percentage as freespace/totalspace then pick the largest to fill to a point
+
throw new InvalidOperationException("Out of free space");
}
diff --git a/src/SnapDB/Snap/Services/Writer/ArchiveInitializerSettings.cs b/src/SnapDB/Snap/Services/Writer/ArchiveInitializerSettings.cs
index ccb3b826..7aac922e 100644
--- a/src/SnapDB/Snap/Services/Writer/ArchiveInitializerSettings.cs
+++ b/src/SnapDB/Snap/Services/Writer/ArchiveInitializerSettings.cs
@@ -31,6 +31,30 @@
namespace SnapDB.Snap.Services.Writer;
+public enum BalancingMethod
+{
+ ///
+ /// Fills the path to meet the desired free space, prioritizing paths with the most available space
+ ///
+ FillToDesired,
+ ///
+ /// Fills the path with the least available space
+ ///
+ FillSmallestAvailable,
+ ///
+ /// Fills the path with the most available space
+ ///
+ FillLargestAvailable,
+ ///
+ /// Fills the path with the most space, available or not, as long as there is room
+ ///
+ FillLargestTotal,
+ ///
+ /// Fills each path to the same amount across the board
+ ///
+ FillToMatchingPercentage
+}
+
///
/// Settings for .
///
@@ -39,6 +63,7 @@ public class ArchiveInitializerSettings : SettingsBase
+ /// The method used to balance file share load.
+ ///
+ public BalancingMethod BalancingMethod
+ {
+ get => m_balancingMethod;
+ set
+ {
+ TestForEditable();
+
+ m_balancingMethod = value;
+ }
+ }
+
///
/// Gets the method that the directory structure will follow when writing a new file.
///
@@ -316,6 +355,7 @@ private void Initialize()
m_fileExtension = ".d2i";
m_desiredRemainingSpace = 5 * 1024 * 1024 * 1024L; //5GB
m_encodingMethod = EncodingDefinition.FixedSizeCombinedEncoding;
+ m_balancingMethod = BalancingMethod.FillToDesired;
WritePath = new ImmutableList(x =>
{
PathHelpers.ValidatePathName(x);