Beispiel #1
0
        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();
        }
Beispiel #2
0
        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();
        }
Beispiel #3
0
        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();
        }
Beispiel #4
0
        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();
        }
Beispiel #5
0
        /// <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;
        }