Example #1
0
        private int[] AllocateBlocks(int count)
        {
            if (count <= 0)
            {
                return(new int[0]);
            }

            var freeCount = UnallocatedHashEntries.Count > count ? count : UnallocatedHashEntries.Count;
            var res       = new List <int>();

            if (freeCount > 0)
            {
                res.AddRange(UnallocatedHashEntries.Take(freeCount));
                UnallocatedHashEntries.RemoveRange(0, freeCount);

                var lastTable = TopLevel == 0 ? TopTable : TopTable.Tables[TopTable.EntryCount - 1];
                var lastEntry = lastTable.Entries.FirstOrDefault(e => e.Block == res.Last());
                if (lastEntry != null)
                {
                    var index = lastTable.Entries.ToList().IndexOf(lastEntry);
                    lastTable.EntryCount = index + 1;
                    if (res.Last() + 1 > VolumeDescriptor.AllocatedBlockCount)
                    {
                        VolumeDescriptor.AllocatedBlockCount = res.Last() + 1;
                        Binary.EnsureBinarySize(GetRealAddressOfBlock(VolumeDescriptor.AllocatedBlockCount));
                    }
                }
            }
            var toAlloc = count - freeCount;

            if (toAlloc > 0)
            {
                switch (TopLevel)
                {
                case 0:
                    throw new NotImplementedException("Table upgrade from lvl 0 to 1 needed!");

                case 1:
                    if (TopTable.EntryCount == 0xAA)
                    {
                        throw new NotImplementedException("Table upgrade from lvl 1 to 2 needed!");
                    }

                    //allocate a new table
                    var table      = GetLevelNHashTable(TopTable.EntryCount, 0);
                    var tableEntry = TopTable.Entries[TopTable.EntryCount++];
                    tableEntry.RealBlock = table.Block;
                    tableEntry.Status    = BlockStatus.Allocated;
                    TopTable.Tables.Add(table);

                    res.AddRange(AllocateBlocks(toAlloc));
                    break;

                default:
                    throw new NotSupportedException("Unsupported level" + TopLevel);
                }
            }
            return(res.ToArray());
        }