Exemple #1
0
        /// <summary>
        /// Finds the first free memarea with enough required contigous space.
        /// </summary>
        /// <param name="memRequirements">space requirements</param>
        /// <returns>null if no such area exists, i.e view is full</returns>
        private MemArena FindFirstFreeArena(uint memRequirements)
        {
            memRequirements += (uint)MemArena.Header.Size;
            MemArena arena = FirstArena();

            if (arena.OffsetNext != 0)
            {
                arena.Capacity = (uint)(arena.OffsetNext - (arena.Offset + MemArena.Header.Size));
            }

            if (_lastFreeArena != null) //save time .This improves performance by many times.. I am saving the last free arena, to be used for next instert. This eliminates list traversal for every add operation.
            {
                if (_lastFreeArena.IsFree && _lastFreeArena.Capacity >= memRequirements)
                {
                    return(_lastFreeArena);
                }
            }

            while (arena != null)
            {
                if (arena.IsFree && arena.Capacity >= memRequirements)
                {
                    return(arena);
                }

                arena = arena.NextArena();
            }
            return(null);
        }
Exemple #2
0
            bool IEnumerator.MoveNext()
            {
                if (_view == null)
                {
                    return(false);
                }

                _storage._viewManager.OpenView(_view);
                if (_arena == null)
                {
                    _arena = _view.FirstArena();
                }
                else
                {
                    _arena = _arena.NextArena();
                    if (_arena == null)
                    {
                        _view = _storage._viewManager.GetViewByID(_view.ID + 1);
                        if (_view != null)
                        {
                            _storage._viewManager.OpenView(_view);
                            _arena = _view.FirstArena();
                        }
                    }
                }

                return(_arena != null);
            }
Exemple #3
0
        /// <summary>
        /// Splits an arena into two adjacent arenas. Size of the first arena is equal
        /// to the size parameter. The second arenas occupies rest of the size of the
        /// parent arena.
        /// </summary>
        internal static MemArena SplitArena(MemArena arena, uint size)
        {
            uint sizeWithHeader = (uint)(size + Header.Size);

            if (arena.OffsetNext != 0) //Quick and dirty...
            {
                arena.Capacity = (uint)(arena.OffsetNext - (arena.Offset + Header.Size));
            }

            if (sizeWithHeader > arena.Capacity) //size is replaced by sizeWithHeader...
            {
                return(null);
            }

            uint remainingCapacity = (uint)(arena.Capacity - size - Header.Size); //if value is negative .uint gived garbage. Reason for above change.


            // Check if the remaining space will be useful at all!
            // if not then there is no need to split and use the whole
            // arena instead.
            if (remainingCapacity < MemArena.SPLIT_THRESHOLD)
            {
                arena.View.MyFreeSpace -= (uint)(arena.Capacity + Header.Size);
                return(arena);
            }

            // Reduce parent arena's capacity.
            arena.Capacity = size;

            MemArena newArena = arena.View.ArenaAtOffset(arena.Offset + arena.TotalLength);

            newArena.Capacity       = remainingCapacity;
            arena.View.MyFreeSpace -= (sizeWithHeader);

            // Fix up links!

            MemArena tempArena = arena.NextArena();

            SetNextArena(newArena, GetActualArena(tempArena));
            SetNextArena(arena, newArena);
            return(newArena);
        }
Exemple #4
0
        public override string ToString()
        {
            StringBuilder b = new StringBuilder();

            b.Append("View, ID=").Append(ID)
            .Append(", maxFree=").Append(MaxFreeSpace)
            .Append(", Free=").Append(FreeSpace)
            .Append("\r\n");

            if (IsOpen)
            {
                MemArena next = FirstArena();
                while (next != null)
                {
                    b.Append(next.ToString()).Append("\r\n");
                    next = next.NextArena();
                }
            }
            return(b.ToString());
        }
Exemple #5
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public MemArena DeFragment()
        {
            MemArena lastArena = FirstArena();

            do
            {
                MemArena current = lastArena.NextArena();
                if (current == null)
                {
                    break;
                }

                // If the last arena is used we dont need to swap it down.
                if (!lastArena.IsFree)
                {
                    lastArena = current;
                    continue;
                }

                // Two consecutive free arenas, rare, but taken care of!
                if (current.IsFree)
                {
                    lastArena = MemArena.CoalesceAdjacent(current);
                }
                else
                {
                    // A free arena followed by a used one so we swap down the free one.
                    MemArena.SwapAdjacent(current, lastArena);
                    lastArena = current;
                }
            }while (true);

            this.FreeSpace    = lastArena.Capacity;
            this.MaxFreeSpace = lastArena.Capacity;
            CalculateArenaMemoryUsage(); //may be we need it here.. very low frequency of this to be called..
            return(lastArena);
        }
Exemple #6
0
        private void CalculateArenaMemoryUsage()
        {
            MemArena arena      = FirstArena();
            MemArena firstArena = FirstArena(); //need to keep the first ..for avoiding circular linkages..
            uint     maxFree    = 0;
            uint     totalFree  = 0;

            while (arena != null)
            {
                try
                {
                    if (arena.IsFree)
                    {
                        totalFree += arena.Capacity;
                        if (arena.Capacity >= maxFree)
                        {
                            maxFree = arena.Capacity;
                        }
                    }
                    arena = arena.NextArena();
                    if (arena != null)
                    {
                        if (arena.OffsetNext == firstArena.Offset)
                        {
                            arena.OffsetNext = 0;
                        }
                    }
                }
                catch (Exception e)
                {
                    throw new Exception(e.Message);
                }
            }
            this.FreeSpace    = totalFree;
            this.MaxFreeSpace = maxFree;
            this.MyFreeSpace  = this.FreeSpace + (uint)MemArena.Header.Size;
        }
Exemple #7
0
        /// <summary>
        /// Coalesces/Merges all the adjacent FREE arenas into one arena.
        /// </summary>
        internal static MemArena CoalesceAdjacent(MemArena arena)
        {
            // Only free arenas can be coalesced.
            if (!arena.IsFree)
            {
                return(arena);
            }

            // Check if there is an arena next to this one.
            MemArena curr         = arena;
            MemArena next         = arena.NextArena();
            int      nHeaderCount = 0;//need to know how many headers are being freed while merging free arenas.

            if (next != null)
            {
                uint freedSpace = 0;
                // Find the first USED arena below this arena in the view.
                // Skip/Merge all the free arenas along the way.
                while (next != null && next.IsFree)
                {
                    nHeaderCount++;
                    freedSpace += next.TotalLength;
                    curr        = next;
                    next        = next.NextArena();
                }

                // Fix up links!
                if (freedSpace > 0)
                {
                    arena.Capacity += freedSpace;
                    uint nCapacity = arena.Capacity;
                    arena          = SetNextArena(arena, GetActualArena(next)); //update only the actual arena
                    arena.Capacity = nCapacity;
                }
            }

            if (arena.HasPrevious)
            {
                uint freedSpace = 0;
                // Find the first USED arena above this arena in the view.
                // Skip/Merge all the free arenas along the way.
                MemArena cur  = arena;
                MemArena prev = null;
                do
                {
                    prev = cur.PreviousArena();
                    if (prev == null || !prev.IsFree)
                    {
                        break;
                    }

                    freedSpace += prev.TotalLength;
                    cur         = prev;
                    nHeaderCount++;
                }while (true);

                // Fix up links! For even if we find previous arena free.. The last from previous is now our Pivot.Its call to adjust its Next then.
                if (freedSpace > 0)
                {
                    arena.Capacity += freedSpace;
                    uint     nCapacity = arena.Capacity;
                    MemArena tempNext  = arena.NextArena();
                    arena          = SetNextArena(cur, GetActualArena(next)); //update only the actual arena
                    arena.Capacity = nCapacity;
                }
            }
            if (nHeaderCount > 0) //update memory freed, while merging arenas.
            {
                arena.View.MyFreeSpace += (uint)(nHeaderCount * Header.Size);
            }

            return(arena);
        }