Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 124 additions & 4 deletions src/SnapDB/Snap/Services/Writer/ArchiveInitializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}

Expand Down
40 changes: 40 additions & 0 deletions src/SnapDB/Snap/Services/Writer/ArchiveInitializerSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,30 @@

namespace SnapDB.Snap.Services.Writer;

public enum BalancingMethod
{
/// <summary>
/// Fills the path to meet the desired free space, prioritizing paths with the most available space
/// </summary>
FillToDesired,
/// <summary>
/// Fills the path with the least available space
/// </summary>
FillSmallestAvailable,
/// <summary>
/// Fills the path with the most available space
/// </summary>
FillLargestAvailable,
/// <summary>
/// Fills the path with the most space, available or not, as long as there is room
/// </summary>
FillLargestTotal,
/// <summary>
/// Fills each path to the same amount across the board
/// </summary>
FillToMatchingPercentage
}

/// <summary>
/// Settings for <see cref="ArchiveInitializer{TKey,TValue}"/>.
/// </summary>
Expand All @@ -39,6 +63,7 @@ public class ArchiveInitializerSettings : SettingsBase<ArchiveInitializerSetting
#region [ Members ]

private long m_desiredRemainingSpace;
private BalancingMethod m_balancingMethod;
private ArchiveDirectoryMethod m_directoryMethod;
private EncodingDefinition m_encodingMethod;
private string m_fileExtension;
Expand Down Expand Up @@ -85,6 +110,20 @@ public long DesiredRemainingSpace
}
}

/// <summary>
/// The method used to balance file share load.
/// </summary>
public BalancingMethod BalancingMethod
{
get => m_balancingMethod;
set
{
TestForEditable();

m_balancingMethod = value;
}
}

/// <summary>
/// Gets the method that the directory structure will follow when writing a new file.
/// </summary>
Expand Down Expand Up @@ -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<string>(x =>
{
PathHelpers.ValidatePathName(x);
Expand Down