68 lines
2.1 KiB
C#

using NUnit.Framework;
using Utils;
namespace CodexReleaseTests.Utils
{
public class PurchaseParams
{
private readonly ByteSize blockSize = 64.KB();
public PurchaseParams(int nodes, int tolerance, ByteSize uploadFilesize)
{
Nodes = nodes;
Tolerance = tolerance;
UploadFilesize = uploadFilesize;
EncodedDatasetSize = CalculateEncodedDatasetSize();
SlotSize = CalculateSlotSize();
Assert.That(IsPowerOfTwo(SlotSize));
}
public int Nodes { get; }
public int Tolerance { get; }
public ByteSize UploadFilesize { get; }
public ByteSize EncodedDatasetSize { get; }
public ByteSize SlotSize { get; }
private ByteSize CalculateSlotSize()
{
// encoded dataset is divided over the nodes.
// then each slot is rounded up to the nearest power-of-two blocks.
var numBlocks = EncodedDatasetSize.DivUp(blockSize);
var numSlotBlocks = 1 + ((numBlocks - 1) / Nodes); // round-up div.
// Next power of two:
var numSlotBlocksPow2 = NextPowerOf2(numSlotBlocks);
return new ByteSize(blockSize.SizeInBytes * numSlotBlocksPow2);
}
private ByteSize CalculateEncodedDatasetSize()
{
var numBlocks = UploadFilesize.DivUp(blockSize);
var ecK = Nodes - Tolerance;
var ecM = Tolerance;
// for each K blocks, we generate M parity blocks
var numParityBlocks = (numBlocks / ecK) * ecM;
var totalBlocks = numBlocks + numParityBlocks;
return new ByteSize(blockSize.SizeInBytes * totalBlocks);
}
private int NextPowerOf2(int n)
{
n = n - 1;
var lg = Convert.ToInt32(Math.Round(Math.Log2(Convert.ToDouble(n))));
return 1 << (lg + 1);
}
private static bool IsPowerOfTwo(ByteSize size)
{
var x = size.SizeInBytes;
return (x != 0) && ((x & (x - 1)) == 0);
}
}
}