Ejemplo n.º 1
0
            private static long CalcSize(SparseStream content, ServerSparseExtentHeader header)
            {
                long numDataGrains     = StreamExtent.BlockCount(content.Extents, header.GrainSize * Sizes.Sector);
                long grainTableSectors = Utilities.Ceil(header.NumGTEsPerGT * 4, Sizes.Sector);

                return((grainTableSectors + (numDataGrains * header.GrainSize)) * Sizes.Sector);
            }
Ejemplo n.º 2
0
        public bool TryAllocate(long length, out long start)
        {
            if (length % Sizes.OneMiB != 0)
            {
                throw new ArgumentException("VHDX free space must be managed on 1MB boundaries", nameof(length));
            }

            for (int i = 0; i < _freeExtents.Count; ++i)
            {
                StreamExtent extent = _freeExtents[i];
                if (extent.Length == length)
                {
                    _freeExtents.RemoveAt(i);
                    start = extent.Start;
                    return(true);
                }
                if (extent.Length > length)
                {
                    _freeExtents[i] = new StreamExtent(extent.Start + length, extent.Length - length);
                    start           = extent.Start;
                    return(true);
                }
            }

            start = 0;
            return(false);
        }
Ejemplo n.º 3
0
        internal override List <BuilderExtent> FixExtents(out long totalLength)
        {
            List <BuilderExtent> extents = new List <BuilderExtent>();

            ServerSparseExtentHeader header   = DiskImageFile.CreateServerSparseExtentHeader(_content.Length);
            GlobalDirectoryExtent    gdExtent = new GlobalDirectoryExtent(header);

            long grainTableStart    = (header.GdOffset * Sizes.Sector) + gdExtent.Length;
            long grainTableCoverage = header.NumGTEsPerGT * header.GrainSize * Sizes.Sector;

            foreach (var grainTableRange in StreamExtent.Blocks(_content.Extents, grainTableCoverage))
            {
                for (int i = 0; i < grainTableRange.Count; ++i)
                {
                    long             grainTable = grainTableRange.Offset + i;
                    long             dataStart  = grainTable * grainTableCoverage;
                    GrainTableExtent gtExtent   = new GrainTableExtent(grainTableStart, new SubStream(_content, dataStart, Math.Min(grainTableCoverage, _content.Length - dataStart)), header);
                    extents.Add(gtExtent);
                    gdExtent.SetEntry((int)grainTable, (uint)(grainTableStart / Sizes.Sector));

                    grainTableStart += gtExtent.Length;
                }
            }

            extents.Insert(0, gdExtent);

            header.FreeSector = (uint)(grainTableStart / Sizes.Sector);

            byte[] buffer = header.GetBytes();
            extents.Insert(0, new BuilderBufferExtent(0, buffer));

            totalLength = grainTableStart;

            return(extents);
        }
Ejemplo n.º 4
0
        public override IEnumerable <StreamExtent> GetExtentsInRange(long start, long count)
        {
            CheckDisposed();

            return
                (StreamExtent.Intersect(
                     StreamExtent.Union(GetExtentsRaw(start, count), _parentStream.GetExtentsInRange(start, count)),
                     new StreamExtent(start, count)));
        }
Ejemplo n.º 5
0
        public override IEnumerable <StreamExtent> GetExtentsInRange(long start, long count)
        {
            StreamExtent lastRun = null;

            foreach (CompressedBlock block in Blocks)
            {
                if ((block.FirstSector + block.SectorCount) * Sizes.Sector < start)
                {
                    // Skip blocks before start of range
                    continue;
                }

                if (block.FirstSector * Sizes.Sector > start + count)
                {
                    // Skip blocks after end of range
                    continue;
                }

                foreach (CompressedRun run in block.Runs)
                {
                    if (run.SectorCount > 0 && run.Type != RunType.Zeros)
                    {
                        long thisRunStart = (block.FirstSector + run.SectorStart) * Sizes.Sector;
                        long thisRunEnd   = thisRunStart + run.SectorCount * Sizes.Sector;

                        thisRunStart = Math.Max(thisRunStart, start);
                        thisRunEnd   = Math.Min(thisRunEnd, start + count);

                        long thisRunLength = thisRunEnd - thisRunStart;

                        if (thisRunLength > 0)
                        {
                            if (lastRun != null && lastRun.Start + lastRun.Length == thisRunStart)
                            {
                                lastRun = new StreamExtent(lastRun.Start, lastRun.Length + thisRunLength);
                            }
                            else
                            {
                                if (lastRun != null)
                                {
                                    yield return(lastRun);
                                }

                                lastRun = new StreamExtent(thisRunStart, thisRunLength);
                            }
                        }
                    }
                }
            }

            if (lastRun != null)
            {
                yield return(lastRun);
            }
        }
Ejemplo n.º 6
0
            private static long SectorsPresent(SparseStream content, long grainSize)
            {
                long total = 0;

                foreach (Range <long, long> grainRange in StreamExtent.Blocks(content.Extents, grainSize * Sizes.Sector))
                {
                    total += grainRange.Count * grainSize;
                }

                return(total);
            }
Ejemplo n.º 7
0
        public void TestIntersect1()
        {
            StreamExtent[] s1 = new StreamExtent[] {
                new StreamExtent(0, 4)
            };
            StreamExtent[] s2 = new StreamExtent[] {
                new StreamExtent(4, 8)
            };
            StreamExtent[] r = new StreamExtent[] { };

            Compare(r, StreamExtent.Intersect(s1, s2));
        }
Ejemplo n.º 8
0
        public void TestUnion4()
        {
            StreamExtent[] s1 = new StreamExtent[] {
                new StreamExtent(0, 4),
                new StreamExtent(4, 4)
            };
            StreamExtent[] r = new StreamExtent[] {
                new StreamExtent(0, 8)
            };

            Compare(r, StreamExtent.Union(s1));
        }
Ejemplo n.º 9
0
        protected override List <BuilderExtent> FixExtents(out long totalLength)
        {
            const int FooterSize    = 512;
            const int DynHeaderSize = 1024;

            List <BuilderExtent> extents = new List <BuilderExtent>();

            _footer.DataOffset = FooterSize;

            DynamicHeader dynHeader = new DynamicHeader(-1, FooterSize + DynHeaderSize, _blockSize, _footer.CurrentSize);

            BlockAllocationTableExtent batExtent = new BlockAllocationTableExtent(FooterSize + DynHeaderSize,
                                                                                  dynHeader.MaxTableEntries);

            long streamPos = batExtent.Start + batExtent.Length;

            foreach (Range <long, long> blockRange in StreamExtent.Blocks(_content.Extents, _blockSize))
            {
                for (int i = 0; i < blockRange.Count; ++i)
                {
                    long            block      = blockRange.Offset + i;
                    long            blockStart = block * _blockSize;
                    DataBlockExtent dataExtent = new DataBlockExtent(streamPos,
                                                                     new SubStream(_content, blockStart, Math.Min(_blockSize, _content.Length - blockStart)));
                    extents.Add(dataExtent);

                    batExtent.SetEntry((int)block, (uint)(streamPos / Sizes.Sector));

                    streamPos += dataExtent.Length;
                }
            }

            _footer.UpdateChecksum();
            dynHeader.UpdateChecksum();

            byte[] footerBuffer = new byte[FooterSize];
            _footer.ToBytes(footerBuffer, 0);

            byte[] dynHeaderBuffer = new byte[DynHeaderSize];
            dynHeader.ToBytes(dynHeaderBuffer, 0);

            // Add footer (to end)
            extents.Add(new BuilderBufferExtent(streamPos, footerBuffer));
            totalLength = streamPos + FooterSize;

            extents.Insert(0, batExtent);
            extents.Insert(0, new BuilderBufferExtent(FooterSize, dynHeaderBuffer));
            extents.Insert(0, new BuilderBufferExtent(0, footerBuffer));

            return(extents);
        }
Ejemplo n.º 10
0
        public void TestUnion3()
        {
            StreamExtent[] s1 = new StreamExtent[] {
                new StreamExtent(0, 4)
            };
            StreamExtent[] s2 = new StreamExtent[] {
                new StreamExtent(2, 8)
            };
            StreamExtent[] r = new StreamExtent[] {
                new StreamExtent(0, 10)
            };

            Compare(r, StreamExtent.Union(s1, s2));
        }
Ejemplo n.º 11
0
        public void TestIntersect5()
        {
            StreamExtent[] s1 = new StreamExtent[] {
                new StreamExtent(0, 10)
            };
            StreamExtent[] s2 = new StreamExtent[] {
                new StreamExtent(3, 5)
            };
            StreamExtent[] r = new StreamExtent[] {
                new StreamExtent(3, 5)
            };

            Compare(r, StreamExtent.Intersect(s1, s2));
        }
Ejemplo n.º 12
0
            internal override void PrepareForRead()
            {
                byte[] bitmap = new byte[Utilities.RoundUp(Utilities.Ceil(_content.Length, Sizes.Sector) / 8, Sizes.Sector)];

                foreach (var range in StreamExtent.Blocks(_content.Extents, Sizes.Sector))
                {
                    for (int i = 0; i < range.Count; ++i)
                    {
                        byte mask = (byte)(1 << (7 - ((int)(range.Offset + i) % 8)));
                        bitmap[(range.Offset + i) / 8] |= mask;
                    }
                }

                _bitmapStream = new MemoryStream(bitmap, false);
            }
Ejemplo n.º 13
0
            internal override void PrepareForRead()
            {
                long outputGrain = 0;

                _grainMapOffsets = new int[Length / (_grainSize * Sizes.Sector)];
                _grainMapRanges  = new Range <long, long> [_grainMapOffsets.Length];
                foreach (Range <long, long> grainRange in StreamExtent.Blocks(_content.Extents, _grainSize * Sizes.Sector))
                {
                    for (int i = 0; i < grainRange.Count; ++i)
                    {
                        _grainMapOffsets[outputGrain] = i;
                        _grainMapRanges[outputGrain]  = grainRange;
                        outputGrain++;
                    }
                }
            }
Ejemplo n.º 14
0
        public void TestIntersect4()
        {
            StreamExtent[] s1 = new StreamExtent[] {
                new StreamExtent(0, 4)
            };
            StreamExtent[] s2 = new StreamExtent[] {
                new StreamExtent(3, 8)
            };
            StreamExtent[] s3 = new StreamExtent[] {
                new StreamExtent(10, 10)
            };
            StreamExtent[] r = new StreamExtent[] {
            };

            Compare(r, StreamExtent.Intersect(s1, s2, s3));
        }
            internal override void PrepareForRead()
            {
                _data = new byte[_gtesPerGt * 4];

                long gtSpan           = _gtesPerGt * _grainSize * Sizes.Sector;
                long sectorsAllocated = 0;

                foreach (var block in StreamExtent.Blocks(_content.Extents, _grainSize * Sizes.Sector))
                {
                    for (int i = 0; i < block.Count; ++i)
                    {
                        Utilities.WriteBytesLittleEndian((uint)(_dataStart + sectorsAllocated), _data, (int)((block.Offset + i) * 4));
                        sectorsAllocated += _grainSize;
                    }
                }
            }
Ejemplo n.º 16
0
        public void TestIntersect3()
        {
            StreamExtent[] s1 = new StreamExtent[] {
                new StreamExtent(0, 4),
                new StreamExtent(10, 10)
            };
            StreamExtent[] s2 = new StreamExtent[] {
                new StreamExtent(3, 8)
            };
            StreamExtent[] r = new StreamExtent[] {
                new StreamExtent(3, 1),
                new StreamExtent(10, 1)
            };

            Compare(r, StreamExtent.Intersect(s1, s2));
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Indicates if a stream contains a valid partition table.
        /// </summary>
        /// <param name="disk">The stream to inspect</param>
        /// <returns><c>true</c> if the partition table is valid, else <c>false</c>.</returns>
        public static bool IsValid(Stream disk)
        {
            if (disk.Length < Utilities.SectorSize)
            {
                return(false);
            }

            disk.Position = 0;
            byte[] bootSector = Utilities.ReadFully(disk, Utilities.SectorSize);

            // Check for the 'bootable sector' marker
            if (bootSector[510] != 0x55 || bootSector[511] != 0xAA)
            {
                return(false);
            }

            bool foundPartition = false;

            List <StreamExtent> knownPartitions = new List <StreamExtent>();

            foreach (var record in ReadPrimaryRecords(bootSector))
            {
                // If the partition extends beyond the end of the disk, this is probably an invalid partition table
                if (record.LBALength != 0xFFFFFFFF && (record.LBAStart + (long)record.LBALength) * Sizes.Sector > disk.Length)
                {
                    return(false);
                }

                if (record.LBALength > 0)
                {
                    foundPartition = true;
                }

                StreamExtent[] thisPartitionExtents = new StreamExtent[] { new StreamExtent(record.LBAStart, record.LBALength) };

                // If the partition intersects another partition, this is probably an invalid partition table
                foreach (var overlap in StreamExtent.Intersect(knownPartitions, thisPartitionExtents))
                {
                    return(false);
                }

                knownPartitions = new List <StreamExtent>(StreamExtent.Union(knownPartitions, thisPartitionExtents));
            }

            return(foundPartition);
        }
Ejemplo n.º 18
0
        public override IEnumerable <StreamExtent> GetExtentsInRange(long start, long count)
        {
            CheckDisposed();

            long maxCount = Math.Min(Length, start + count) - start;

            if (maxCount < 0)
            {
                return(new StreamExtent[0]);
            }

            IEnumerable <StreamExtent> parentExtents = _parentStream.GetExtentsInRange(start, maxCount);

            IEnumerable <StreamExtent> result = StreamExtent.Union(LayerExtents(start, maxCount), parentExtents);

            result = StreamExtent.Intersect(result, new[] { new StreamExtent(start, maxCount) });
            return(result);
        }
Ejemplo n.º 19
0
        public void ExtendTo(long fileSize, bool isFree)
        {
            if (fileSize % Sizes.OneMiB != 0)
            {
                throw new ArgumentException("VHDX space must be allocated on 1MB boundaries", "fileSize");
            }

            if (fileSize < _fileSize)
            {
                throw new ArgumentOutOfRangeException("fileSize", "Attempt to extend file to smaller size", fileSize.ToString(CultureInfo.InvariantCulture));
            }

            _fileSize = fileSize;

            if (isFree)
            {
                _freeExtents = new List <StreamExtent>(StreamExtent.Union(_freeExtents, new StreamExtent(_fileSize, fileSize - _fileSize)));
            }
        }
Ejemplo n.º 20
0
            internal override void PrepareForRead()
            {
                byte[] grainTable = new byte[Utilities.RoundUp(_header.NumGTEsPerGT * 4, Sizes.Sector)];

                long dataSector = (Start + grainTable.Length) / Sizes.Sector;

                _grainMapping = new List <long>();
                _grainContiguousRangeMapping = new List <long>();
                foreach (var grainRange in StreamExtent.Blocks(_content.Extents, _header.GrainSize * Sizes.Sector))
                {
                    for (int i = 0; i < grainRange.Count; ++i)
                    {
                        Utilities.WriteBytesLittleEndian((uint)dataSector, grainTable, (int)(4 * (grainRange.Offset + i)));
                        dataSector += _header.GrainSize;
                        _grainMapping.Add(grainRange.Offset + i);
                        _grainContiguousRangeMapping.Add(grainRange.Count - i);
                    }
                }

                _grainTableStream = new MemoryStream(grainTable, 0, grainTable.Length, false);
            }
Ejemplo n.º 21
0
        private void StreamExtentSample()
        {
            // intro message
            Editor editor = GetEditor();

            editor.WriteMessage("* StreamExtent *\n");
            editor.WriteMessage("StreamExtent detects the extents of all the objects in the stream.\n");
            editor.WriteMessage("Pick some objects in the current drawing and the extents will be highlighted.\n");

            // pick multiple objects
            ObjectIdCollection ids = PickObjectSet();

            if (ids.Count == 0)
            {
                editor.WriteMessage("No object is picked\n");
                return;
            }

            Database     db     = GetDatabase();
            StreamExtent stream = new StreamExtent(db);

            TransactionManager tm = db.TransactionManager;

            using (Transaction trans = tm.StartTransaction())
            {
                stream.PushDisplayParameters(DictionaryDisplayConfiguration.GetStandardDisplayConfiguration(db), trans);

                foreach (ObjectId id in ids)
                {
                    Entity ent = trans.GetObject(id, OpenMode.ForRead) as Entity;
                    stream.Stream(ent);
                }

                stream.PopDisplayParameters();
                trans.Commit();
            }

            HighlightBoundBox3d(stream.Extents);
        }
Ejemplo n.º 22
0
        public void TestBlocks()
        {
            StreamExtent[] s = new StreamExtent[] {
                new StreamExtent(0, 8),
                new StreamExtent(11, 4)
            };

            List <Range <long, long> > ranges = new List <Range <long, long> >(StreamExtent.Blocks(s, 10));

            Assert.Equal(1, ranges.Count);
            Assert.Equal(0, ranges[0].Offset);
            Assert.Equal(2, ranges[0].Count);

            s = new StreamExtent[] {
                new StreamExtent(0, 8),
                new StreamExtent(9, 8)
            };

            ranges = new List <Range <long, long> >(StreamExtent.Blocks(s, 10));

            Assert.Equal(1, ranges.Count);
            Assert.Equal(0, ranges[0].Offset);
            Assert.Equal(2, ranges[0].Count);

            s = new StreamExtent[] {
                new StreamExtent(3, 4),
                new StreamExtent(19, 4),
                new StreamExtent(44, 4)
            };

            ranges = new List <Range <long, long> >(StreamExtent.Blocks(s, 10));

            Assert.Equal(2, ranges.Count);
            Assert.Equal(0, ranges[0].Offset);
            Assert.Equal(3, ranges[0].Count);
            Assert.Equal(4, ranges[1].Offset);
            Assert.Equal(1, ranges[1].Count);
        }
Ejemplo n.º 23
0
        public void TestBlockCount()
        {
            StreamExtent[] s = new StreamExtent[] {
                new StreamExtent(0, 8),
                new StreamExtent(11, 4)
            };

            Assert.Equal(2, StreamExtent.BlockCount(s, 10));

            s = new StreamExtent[] {
                new StreamExtent(0, 8),
                new StreamExtent(9, 8)
            };

            Assert.Equal(2, StreamExtent.BlockCount(s, 10));

            s = new StreamExtent[] {
                new StreamExtent(3, 4),
                new StreamExtent(19, 4),
                new StreamExtent(44, 4)
            };

            Assert.Equal(4, StreamExtent.BlockCount(s, 10));
        }
Ejemplo n.º 24
0
        /// <summary>
        /// Creates a hex dump from a stream.
        /// </summary>
        /// <param name="stream">The stream to generate the hex dump from.</param>
        /// <param name="output">The destination for the hex dump.</param>
        public static void Generate(SparseStream stream, TextWriter output)
        {
            stream.Position = 0;
            byte[] buffer = new byte[1024 * 1024];

            foreach (var block in StreamExtent.Blocks(stream.Extents, buffer.Length))
            {
                long startPos = block.Offset * (long)buffer.Length;
                long endPos   = Math.Min((block.Offset + block.Count) * (long)buffer.Length, stream.Length);
                stream.Position = startPos;

                while (stream.Position < endPos)
                {
                    int  numLoaded = 0;
                    long readStart = stream.Position;
                    while (numLoaded < buffer.Length)
                    {
                        int bytesRead = stream.Read(buffer, numLoaded, buffer.Length - numLoaded);
                        if (bytesRead == 0)
                        {
                            break;
                        }
                        numLoaded += bytesRead;
                    }

                    for (int i = 0; i < numLoaded; i += 16)
                    {
                        bool foundVal = false;
                        if (i > 0)
                        {
                            for (int j = 0; j < 16; j++)
                            {
                                if (buffer[i + j] != buffer[i + j - 16])
                                {
                                    foundVal = true;
                                    break;
                                }
                            }
                        }
                        else
                        {
                            foundVal = true;
                        }

                        if (foundVal)
                        {
                            output.Write("{0:x8}", i + readStart);

                            for (int j = 0; j < 16; j++)
                            {
                                if (j % 8 == 0)
                                {
                                    output.Write(" ");
                                }
                                output.Write(" {0:x2}", buffer[i + j]);
                            }

                            output.Write("  |");
                            for (int j = 0; j < 16; j++)
                            {
                                if (j % 8 == 0 && j != 0)
                                {
                                    output.Write(" ");
                                }
                                output.Write("{0}", (buffer[i + j] >= 32 && buffer[i + j] < 127) ? (char)buffer[i + j] : '.');
                            }
                            output.Write("|");

                            output.WriteLine();
                        }
                    }
                }
            }
        }
Ejemplo n.º 25
0
        public void TestIntersect1()
        {
            StreamExtent[] s1 = new StreamExtent[] {
                new StreamExtent(0,4)};
            StreamExtent[] s2 = new StreamExtent[] {
                new StreamExtent(4,8)};
            StreamExtent[] r = new StreamExtent[] { };

            Compare(r, StreamExtent.Intersect(s1, s2));
        }
Ejemplo n.º 26
0
 public override IEnumerable <StreamExtent> GetExtentsInRange(long start, long count)
 {
     return(StreamExtent.Intersect(
                new[] { new StreamExtent(0, Capacity) },
                new StreamExtent(start, count)));
 }
Ejemplo n.º 27
0
        public void TestIntersect3()
        {
            StreamExtent[] s1 = new StreamExtent[] {
                new StreamExtent(0,4),
                new StreamExtent(10, 10)};
            StreamExtent[] s2 = new StreamExtent[] {
                new StreamExtent(3,8)};
            StreamExtent[] r = new StreamExtent[] {
                new StreamExtent(3,1),
                new StreamExtent(10,1)};

            Compare(r, StreamExtent.Intersect(s1, s2));
        }
Ejemplo n.º 28
0
        public void TestUnion5()
        {
            StreamExtent[] r = new StreamExtent[] { };

            Compare(r, StreamExtent.Union());
        }
Ejemplo n.º 29
0
        /// <summary>
        /// Indicates if a stream contains a valid partition table.
        /// </summary>
        /// <param name="disk">The stream to inspect</param>
        /// <returns><c>true</c> if the partition table is valid, else <c>false</c>.</returns>
        public static bool IsValid(Stream disk)
        {
            if (disk.Length < Utilities.SectorSize)
            {
                return false;
            }

            disk.Position = 0;
            byte[] bootSector = Utilities.ReadFully(disk, Utilities.SectorSize);

            // Check for the 'bootable sector' marker
            if (bootSector[510] != 0x55 || bootSector[511] != 0xAA)
            {
                return false;
            }

            List<StreamExtent> knownPartitions = new List<StreamExtent>();
            foreach (var record in ReadPrimaryRecords(bootSector))
            {
                // If the partition extends beyond the end of the disk, this is probably an invalid partition table
                if (record.LBALength != 0xFFFFFFFF && (record.LBAStart + (long)record.LBALength) * Sizes.Sector > disk.Length)
                {
                    return false;
                }

                if (record.LBALength > 0)
                {
                    StreamExtent[] thisPartitionExtents = new StreamExtent[] { new StreamExtent(record.LBAStart, record.LBALength) };

                    // If the partition intersects another partition, this is probably an invalid partition table
                    foreach (var overlap in StreamExtent.Intersect(knownPartitions, thisPartitionExtents))
                    {
                        return false;
                    }

                    knownPartitions = new List<StreamExtent>(StreamExtent.Union(knownPartitions, thisPartitionExtents));
                }
            }

            return true;
        }
Ejemplo n.º 30
0
 public void Reserve(IEnumerable <StreamExtent> extents)
 {
     _freeExtents = new List <StreamExtent>(StreamExtent.Subtract(_freeExtents, extents));
 }
Ejemplo n.º 31
0
 public void Reserve(long start, long length)
 {
     ValidateRange(start, length, "reserve");
     _freeExtents = new List <StreamExtent>(StreamExtent.Subtract(_freeExtents, new StreamExtent(start, length)));
 }
Ejemplo n.º 32
0
 public void Release(long start, long length)
 {
     ValidateRange(start, length, "release");
     _freeExtents = new List <StreamExtent>(StreamExtent.Union(_freeExtents, new StreamExtent(start, length)));
 }
Ejemplo n.º 33
0
 public IEnumerable <StreamExtent> GetExtentsInRange(long start, long count)
 {
     return(StreamExtent.Intersect(Extents, new StreamExtent(start, count)));
 }
Ejemplo n.º 34
0
        public void TestIntersect5()
        {
            StreamExtent[] s1 = new StreamExtent[] {
                new StreamExtent(0,10)};
            StreamExtent[] s2 = new StreamExtent[] {
                new StreamExtent(3,5)};
            StreamExtent[] r = new StreamExtent[] {
                new StreamExtent(3,5)};

            Compare(r, StreamExtent.Intersect(s1, s2));
        }
Ejemplo n.º 35
0
        public void TestBlockCount()
        {
            StreamExtent[] s = new StreamExtent[] {
                new StreamExtent(0,8),
                new StreamExtent(11, 4)
            };

            Assert.AreEqual(2, StreamExtent.BlockCount(s, 10));

            s = new StreamExtent[] {
                new StreamExtent(0,8),
                new StreamExtent(9, 8)
            };

            Assert.AreEqual(2, StreamExtent.BlockCount(s, 10));

            s = new StreamExtent[] {
                new StreamExtent(3, 4),
                new StreamExtent(19, 4),
                new StreamExtent(44, 4)
            };

            Assert.AreEqual(4, StreamExtent.BlockCount(s, 10));
        }
Ejemplo n.º 36
0
        public void TestBlocks()
        {
            StreamExtent[] s = new StreamExtent[] {
                new StreamExtent(0,8),
                new StreamExtent(11, 4)
            };

            List<Range<long,long>> ranges = new List<Range<long,long>>(StreamExtent.Blocks(s, 10));

            Assert.AreEqual(1, ranges.Count);
            Assert.AreEqual(0, ranges[0].Offset);
            Assert.AreEqual(2, ranges[0].Count);

            s = new StreamExtent[] {
                new StreamExtent(0,8),
                new StreamExtent(9, 8)
            };

            ranges = new List<Range<long, long>>(StreamExtent.Blocks(s, 10));

            Assert.AreEqual(1, ranges.Count);
            Assert.AreEqual(0, ranges[0].Offset);
            Assert.AreEqual(2, ranges[0].Count);

            s = new StreamExtent[] {
                new StreamExtent(3, 4),
                new StreamExtent(19, 4),
                new StreamExtent(44, 4)
            };

            ranges = new List<Range<long, long>>(StreamExtent.Blocks(s, 10));

            Assert.AreEqual(2, ranges.Count);
            Assert.AreEqual(0, ranges[0].Offset);
            Assert.AreEqual(3, ranges[0].Count);
            Assert.AreEqual(4, ranges[1].Offset);
            Assert.AreEqual(1, ranges[1].Count);
        }
Ejemplo n.º 37
0
        public bool TryAllocate(long length, out long start)
        {
            if (length % Sizes.OneMiB != 0)
            {
                throw new ArgumentException("VHDX free space must be managed on 1MB boundaries", "length");
            }

            for (int i = 0; i < _freeExtents.Count; ++i)
            {
                StreamExtent extent = _freeExtents[i];
                if (extent.Length == length)
                {
                    _freeExtents.RemoveAt(i);
                    start = extent.Start;
                    return true;
                }
                else if (extent.Length > length)
                {
                    _freeExtents[i] = new StreamExtent(extent.Start + length, extent.Length - length);
                    start = extent.Start;
                    return true;
                }
            }

            start = 0;
            return false;
        }
Ejemplo n.º 38
0
        public void TestIntersect4()
        {
            StreamExtent[] s1 = new StreamExtent[] {
                new StreamExtent(0,4)};
            StreamExtent[] s2 = new StreamExtent[] {
                new StreamExtent(3,8)};
            StreamExtent[] s3 = new StreamExtent[] {
                new StreamExtent(10,10)};
            StreamExtent[] r = new StreamExtent[] {
                };

            Compare(r, StreamExtent.Intersect(s1, s2, s3));
        }
Ejemplo n.º 39
0
        public override IEnumerable<StreamExtent> GetExtentsInRange(long start, long count)
        {
            StreamExtent lastRun = null;

            foreach (var block in _blocks)
            {
                if ((block.FirstSector + block.SectorCount) * Sizes.Sector < start)
                {
                    // Skip blocks before start of range
                    continue;
                }

                if (block.FirstSector * Sizes.Sector > start + count)
                {
                    // Skip blocks after end of range
                    continue;
                }

                foreach (var run in block.Runs)
                {
                    if (run.SectorCount > 0 && run.Type != RunType.Zeros)
                    {
                        long thisRunStart = (block.FirstSector + run.SectorStart) * Sizes.Sector;
                        long thisRunEnd = thisRunStart + (run.SectorCount * Sizes.Sector);

                        thisRunStart = Math.Max(thisRunStart, start);
                        thisRunEnd = Math.Min(thisRunEnd, start + count);

                        long thisRunLength = thisRunEnd - thisRunStart;

                        if (thisRunLength > 0)
                        {
                            if (lastRun != null && lastRun.Start + lastRun.Length == thisRunStart)
                            {
                                lastRun = new StreamExtent(lastRun.Start, lastRun.Length + thisRunLength);
                            }
                            else
                            {
                                if (lastRun != null)
                                {
                                    yield return lastRun;
                                }

                                lastRun = new StreamExtent(thisRunStart, thisRunLength);
                            }
                        }
                    }
                }
            }

            if (lastRun != null)
            {
                yield return lastRun;
            }
        }
 public override IEnumerable <StreamExtent> GetExtentsInRange(long start, long count)
 {
     return(StreamExtent.Intersect(_attribute.RawBuffer.GetExtentsInRange(start, count), new StreamExtent(0, Capacity)));
 }
Ejemplo n.º 41
0
        public void TestUnion4()
        {
            StreamExtent[] s1 = new StreamExtent[] {
                new StreamExtent(0,4),
                new StreamExtent(4,4)};
            StreamExtent[] r = new StreamExtent[] {
                new StreamExtent(0,8)};

            Compare(r, StreamExtent.Union(s1));
        }
Ejemplo n.º 42
0
        public void TestUnion3()
        {
            StreamExtent[] s1 = new StreamExtent[] {
                new StreamExtent(0,4)};
            StreamExtent[] s2 = new StreamExtent[] {
                new StreamExtent(2,8)};
            StreamExtent[] r = new StreamExtent[] {
                new StreamExtent(0,10)};

            Compare(r, StreamExtent.Union(s1, s2));
        }