public void TestHeadAndBodyFitInBlockMargin() { var repo = new MockRepository(); var diskAccessMock = repo.DynamicMock<IDirectDiskAccess>(); var data = new byte[8192]; ulong addr1 = 0; ulong addr2 = 4096; diskAccessMock.WriteBytes(ref addr1, data, 0, 4096); diskAccessMock.WriteBytes(ref addr2, data, 4096, 4096); repo.ReplayAll(); var writer = new SparseWriter(diskAccessMock); Assert.AreEqual(2, SparseWriter.GetNumberOfBlocksRequired(8192, 0)); var dest = new[] { new Address(0), new Address(4096) }; writer.WriteData(data, dest, 0); repo.VerifyAll(); }
public void TestHeadBodyAndTailTakeOneBlockEach() { var repo = new MockRepository(); var diskAccessMock = repo.DynamicMock<IDirectDiskAccess>(); var data = new byte[4096 * 3]; ulong addr1 = 0; ulong addr2 = 4096; ulong addr3 = 8192; diskAccessMock.WriteBytes(ref addr1, data, 0, 4096); diskAccessMock.WriteBytes(ref addr2, data, 4096, 4096); diskAccessMock.WriteBytes(ref addr3, data, 8192, 4096); repo.ReplayAll(); var writer = new SparseWriter(diskAccessMock); Assert.AreEqual(3, SparseWriter.GetNumberOfBlocksRequired(4096 * 3, 0)); var dest = new[] { new Address(0), new Address(4096), new Address(8192) }; writer.WriteData(data, dest, 0); repo.VerifyAll(); }
public void TestHeadAndTailNoBody() { // test case when there is no body, just head and tail in two blocks. var repo = new MockRepository(); var diskAccessMock = repo.StrictMock<IDirectDiskAccess>(); const uint size = 15; var data = new byte[size]; ulong addr1 = 4095; ulong addr2 = 4096; diskAccessMock.WriteBytes(ref addr1, data, 0, 1); diskAccessMock.WriteBytes(ref addr2, data, 1, size - 1); repo.ReplayAll(); var writer = new SparseWriter(diskAccessMock); Assert.AreEqual(2, SparseWriter.GetNumberOfBlocksRequired(size, 4095)); var dest = new[] { new Address(0), new Address(4096) }; writer.WriteData(data, dest, 4095); repo.VerifyAll(); }
public void TestTailFitsIntoBody() { // test case when tail completely fits into last block var repo = new MockRepository(); var diskAccessMock = repo.DynamicMock<IDirectDiskAccess>(); var data = new byte[10000]; uint delta = 4096 - 2288; ulong addr1 = 2288; ulong addr2 = 4096; ulong addr3 = 8192; diskAccessMock.WriteBytes(ref addr1, data, 0, delta); diskAccessMock.WriteBytes(ref addr2, data, delta, 4096); diskAccessMock.WriteBytes(ref addr3, data, delta + 4096, 4096); repo.ReplayAll(); var writer = new SparseWriter(diskAccessMock); Assert.AreEqual(3, SparseWriter.GetNumberOfBlocksRequired(10000, 2288)); var dest = new [] { new Address(0), new Address(4096), new Address(8192) }; writer.WriteData(data, dest, 2288); repo.VerifyAll(); }
/// <summary> /// Writes the data into file, resizing as needed. /// </summary> public ulong WriteData(ulong position, [NotNull] byte[] data) { Validate.ArgumentNotNull(data, "data"); ulong newSize = position + (uint)data.Length; if (newSize > FileSize) { SetFileSize(newSize); // force allocation of new space. will throw if not enough memory. } var startBlockIndex = (uint)(position / Constants.BlockSizeBytes); var offset = (uint)(position % Constants.BlockSizeBytes); var sparseWriter = new SparseWriter(DiskAccess); var requiredNumberOfBlocks = SparseWriter.GetNumberOfBlocksRequired((uint)data.Length, offset); var blocks = new List<Address>(); for (uint i = 0; i < requiredNumberOfBlocks; ++i) { blocks.Add(Storage.GetBlockStartAddress(startBlockIndex + i)); } sparseWriter.WriteData(data, blocks.ToArray(), offset); UpdateModifiedDate(); return newSize; }