public static ulong ComputeDataBackingPageNumber(XvdType type, ulong numHashLevels, ulong hashPageCount, ulong dataPageNumber) { if (type > XvdType.Dynamic) // Invalid Xvd Type! { return(dataPageNumber); } return(dataPageNumber + hashPageCount); }
public void TestCalculateHashBlockNumForBlockNum(XvdType xvdType, ulong hashTreeLevels, ulong xvdDataBlockCount, ulong blockNum, uint index, ulong expectedEntryNum, ulong expectedResult) { ulong result = XvdMath.CalculateHashBlockNumForBlockNum(xvdType, hashTreeLevels, xvdDataBlockCount, blockNum, index, out ulong entryNumInBlock); Assert.Equal(expectedEntryNum, entryNumInBlock); Assert.Equal(expectedResult, result); }
public static ulong CalculateHashBlockNumForBlockNum(XvdType type, ulong hashTreeLevels, ulong numberOfHashedPages, ulong blockNum, uint hashLevel, out ulong entryNumInBlock, bool resilient = false, bool unknown = false) { ulong HashBlockExponent(ulong blockCount) { return((ulong)Math.Pow(0xAA, blockCount)); } ulong result = 0xFFFF; entryNumInBlock = 0; if ((uint)type > 1 || hashLevel > 3) { return(result); // Invalid data } if (hashLevel == 0) { entryNumInBlock = blockNum % 0xAA; } else { entryNumInBlock = blockNum / HashBlockExponent(hashLevel) % 0xAA; } if (hashLevel == 3) { return(0); } result = blockNum / HashBlockExponent(hashLevel + 1); hashTreeLevels -= hashLevel + 1; if (hashLevel == 0 && hashTreeLevels > 0) { result += (numberOfHashedPages + HashBlockExponent(2) - 1) / HashBlockExponent(2); hashTreeLevels--; } if ((hashLevel == 0 || hashLevel == 1) && hashTreeLevels > 0) { result += (numberOfHashedPages + HashBlockExponent(3) - 1) / HashBlockExponent(3); hashTreeLevels--; } if (hashTreeLevels > 0) { result += (numberOfHashedPages + HashBlockExponent(4) - 1) / HashBlockExponent(4); } if (resilient) { result *= 2; } if (unknown) { result++; } return(result); }