BEPUutilities2.ResourceManagement.Allocator.Allocate C# (CSharp) Метод

Allocate() публичный Метод

Attempts to allocate a range of memory.
public Allocate ( ulong id, long size, long &outputStart ) : bool
id ulong Unique id of the memory to allocate.
size long Size of the memory to allocate.
outputStart long Starting index of the allocated memory, if successful.
Результат bool
        public bool Allocate(ulong id, long size, out long outputStart)
        {
            Debug.Assert(!allocations.ContainsKey(id), "Id must not already be present.");
            if (allocations.Count == 0)
            {
                //If it's the first allocation, then the next and previous pointers should circle around.
                if (size <= memoryPoolSize)
                {
                    outputStart = 0;
                    allocations.Add(id, new Allocation { Start = 0, End = size, Next = id, Previous = id });
                    searchStartIndex = 0;
                    return true;
                }
                outputStart = 0;
                return false;
            }
            Debug.Assert(searchStartIndex >= 0 && searchStartIndex < allocations.Count, "Search start index must be within the allocation set!");
            int allocationIndex = searchStartIndex;
            var initialId = allocations.Keys[allocationIndex];
            while (true)
            {
                var allocation = allocations.Values[allocationIndex];
                int nextAllocationIndex = allocations.IndexOf(allocation.Next);
                var nextAllocation = allocations.Values[nextAllocationIndex];
                if (nextAllocation.Start < allocation.End)
                {
                    //Wrapped around, so the gap goes from here to the end of the memory block, and from the beginning of the memory block to the next allocation.
                    //But we need contiguous space so the two areas have to be tested independently.
                    if (memoryPoolSize - allocation.End >= size)
                    {
                        AddAllocation(id, outputStart = allocation.End, allocation.End + size, ref allocations.Values[allocationIndex], ref allocations.Values[nextAllocationIndex]);
                        return true;
                    }
                    else
                    {
                        if (nextAllocation.Start >= size)
                        {
                            AddAllocation(id, outputStart = 0, size, ref allocations.Values[allocationIndex], ref allocations.Values[nextAllocationIndex]);
                            return true;
                        }
                    }
                }
                else
                {
                    //The next allocation is in order.
                    if (nextAllocation.Start - allocation.End >= size)
                    {
                        AddAllocation(id, outputStart = allocation.End, allocation.End + size, ref allocations.Values[allocationIndex], ref allocations.Values[nextAllocationIndex]);
                        return true;
                    }

                }
                //If we get here, no open space was found.
                //Move on to the next spot.
                allocationIndex = nextAllocationIndex;

                //Have we already wrapped around?
                if (allocations.Keys[allocationIndex] == initialId)
                {
                    //Wrapped around without finding any space.
                    outputStart = 0;
                    return false;
                }
            }
        }

Usage Example

Пример #1
0
 public static void TestChurnStability()
 {
     var allocator = new Allocator(2048);
     var random = new Random(5);
     ulong idCounter = 0;
     var allocatedIds = new QuickList<ulong>(BufferPools<ulong>.Locking);
     var unallocatedIds = new QuickList<ulong>(BufferPools<ulong>.Locking);
     for (int i = 0; i < 512; ++i)
     {
         long start;
         var id = idCounter++;
         //allocator.ValidatePointers();
         if (allocator.Allocate(id, 1 + random.Next(5), out start))
         {
             allocatedIds.Add(id);
         }
         else
         {
             unallocatedIds.Add(id);
         }
         //allocator.ValidatePointers();
     }
     for (int timestepIndex = 0; timestepIndex < 100000; ++timestepIndex)
     {
         //First add and remove a bunch randomly.
         for (int i = random.Next(Math.Min(allocatedIds.Count, 15)); i >= 0; --i)
         {
             var indexToRemove = random.Next(allocatedIds.Count);
             //allocator.ValidatePointers();
             Assert.IsTrue(allocator.Deallocate(allocatedIds.Elements[indexToRemove]));
             //allocator.ValidatePointers();
             unallocatedIds.Add(allocatedIds.Elements[indexToRemove]);
             allocatedIds.FastRemoveAt(indexToRemove);
         }
         for (int i = random.Next(Math.Min(unallocatedIds.Count, 15)); i >= 0; --i)
         {
             var indexToAllocate = random.Next(unallocatedIds.Count);
             long start;
             //allocator.ValidatePointers();
             if (allocator.Allocate(unallocatedIds.Elements[indexToAllocate], random.Next(3), out start))
             {
                 //allocator.ValidatePointers();
                 allocatedIds.Add(unallocatedIds.Elements[indexToAllocate]);
                 unallocatedIds.FastRemoveAt(indexToAllocate);
             }
             //allocator.ValidatePointers();
         }
         //Check to ensure that everything's still coherent.
         for (int i = 0; i < allocatedIds.Count; ++i)
         {
             Assert.IsTrue(allocator.Contains(allocatedIds.Elements[i]));
         }
         for (int i = 0; i < unallocatedIds.Count; ++i)
         {
             Assert.IsFalse(allocator.Contains(unallocatedIds.Elements[i]));
         }
     }
     //Wind it down.
     for (int i = 0; i < allocatedIds.Count; ++i)
     {
         Assert.IsTrue(allocator.Deallocate(allocatedIds.Elements[i]));
     }
     //Confirm cleanup.
     for (int i = 0; i < allocatedIds.Count; ++i)
     {
         Assert.IsFalse(allocator.Contains(allocatedIds.Elements[i]));
     }
     for (int i = 0; i < unallocatedIds.Count; ++i)
     {
         Assert.IsFalse(allocator.Contains(unallocatedIds.Elements[i]));
     }
 }