Esempio n. 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);
        }
Esempio n. 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);
            }
Esempio n. 3
0
        public MemArena Allocate(uint size)
        {
            // Check if there isnt enough storage left in this view
            if (size > FreeSpace)
            {
                return(null);
            }

            MemArena arena = null;

            // Check if there isnt enough CONTIGOUS storage available
            // defragment the memory to create a large chunk of mem at
            // the end of view.
            size  = MemArena.Content.RequiredSpace(size);
            arena = FindFirstFreeArena(size);
            if (arena == null)
            {
                CalculateArenaMemoryUsage(); //keep it here ..we need it.
                arena = DeFragment();
                if (arena == null)
                {
                    return(arena);
                }
            }

            /*if (size > MaxFreeSpace) //Now call to CalculateArenaMemoryUsage is avoided so lets call it ..if required.
             *          {
             *                  arena = DeFragment();
             *          }
             *          else
             *          {
             *                  arena = FindFirstFreeArena(size);
             *          }
             *          if (arena == null) return arena;*/

            // allocate space in parent arena.
            MemArena newArena = MemArena.SplitArena(arena, size);

            if (newArena == null)
            {
                return(arena);
            }

            arena.IsFree = false;
            if (arena != newArena) // deal with the case when splitarena returns the same arena back. Saves situation where allocated arena is accidently set to be free.
            {
                newArena.IsFree = true;
                _lastFreeArena  = newArena;
            }

            FreeSpace = MyFreeSpace - (uint)MemArena.Header.Size;
            //CalculateArenaMemoryUsage(); removing it ....
            Usage++;

            return(arena);
        }
Esempio n. 4
0
        /// <summary>
        /// Swaps two arenas that are adjacent in view.
        /// </summary>
        internal static void SwapAdjacent(MemArena arena1, MemArena arena2)
        {
            arena1 = GetActualArena(arena1);
            arena2 = GetActualArena(arena2);

            // Only support swaping of adjacent aenas.
            if (!AreAdjacent(arena1, arena2))
            {
                return;
            }

            // Determine arena order and cache settings!
            MemArena arenaLo = arena1, arenaHi = arena2;

            if (arena1.Offset > arena2.Offset)
            {
                arenaLo = arena2;
                arenaHi = arena1;
            }

            Header hdrLo = arenaLo.ArenaHeader;
            Header hdrHi = arenaHi.ArenaHeader;

            MemArena arenaHiNext = arenaHi.NextArena();
            MemArena arenaLoPrev = arenaLo.PreviousArena();

            arenaHiNext = GetActualArena(arenaHiNext);
            arenaLoPrev = GetActualArena(arenaLoPrev);

            // Swap memory contents of the arenas including headers!
            int loMemNeeded = arenaLo.IsFree ? Header.Size : (int)arenaLo.TotalLength;
            int hiMemNeeded = arenaHi.IsFree ? Header.Size : (int)arenaHi.TotalLength;

            byte[] arenaLoMem = arenaLo.RawView.Read((int)arenaLo.Offset, (int)loMemNeeded);
            byte[] arenaHiMem = arenaHi.RawView.Read((int)arenaHi.Offset, (int)hiMemNeeded);

            arenaHi._offset = arenaLo.Offset + arenaHi.TotalLength;

            arenaLo.RawView.Write(arenaHiMem, (int)arenaLo.Offset, (int)arenaHiMem.Length);
            arenaHi.RawView.Write(arenaLoMem, (int)arenaHi.Offset, (int)arenaLoMem.Length);

            // Fix up links and restore new settings!
            arenaLo.IsFree     = hdrHi.IsFree;
            arenaLo.Capacity   = hdrHi.Capacity;
            arenaLo.OffsetNext = arenaHi.Offset;
            arenaLo.OffsetPrev = hdrLo.OffsetPrev;
            SetPreviousArena(arenaLo, arenaLoPrev);

            // Fix up links and restore new settings!
            arenaHi.IsFree     = hdrLo.IsFree;
            arenaHi.Capacity   = hdrLo.Capacity;
            arenaHi.OffsetNext = hdrHi.OffsetNext;
            arenaHi.OffsetPrev = arenaLo.Offset;
            SetNextArena(arenaHi, arenaHiNext);
        }
Esempio n. 5
0
        public MmfObjectPtr Add(byte[] item)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }
            if (item.Length > _viewSize)
            {
                throw new ArgumentException("item size is larger than view size");
            }

            // Find a view with enough space to contain the item.

            View view = _viewManager.GetMatchingView((uint)item.Length);

            try
            {
                if (view == null)
                {
                    GrowMemoryMappedStore(1);
                    view = _viewManager.GetMatchingView((uint)item.Length);
                }

                if (view != null)
                {
                    MemArena arena = view.Allocate((uint)item.Length);
                    if (arena == null)
                    {
                        return(null);
                    }

                    if (!arena.SetMemContents(item)) // It would return false only when size of Arena allocated is less then required even after all efforts to get arena of required size.
                    {
                        view.DeAllocate(arena);
                        return(null);
                    }

                    return(new MmfObjectPtr(view, arena));
                }
            }
            catch (OutOfMemoryException ex)
            {
                throw;
            }

            catch (Exception ex)
            {
                throw;
            }
            return(null);
        }
Esempio n. 6
0
        private static MemArena SetPreviousArena(MemArena arena, MemArena arenaPrev)
        {
            if (arenaPrev != null) //avoid scanario when two identical arenas are there for addition.
            {
                if (arenaPrev == arena)
                {
                    return(arena);
                }
            }

            arena.OffsetPrev = arenaPrev == null ? 0 : arenaPrev.Offset;
            if (arenaPrev != null)
            {
                arenaPrev.OffsetNext = arena.Offset;
            }

            return(arena);
        }
Esempio n. 7
0
 /// <summary>
 /// Gets the primary allocated arena for the arena provided. Checks key and then  gets the original one.
 /// </summary>
 // To keep the HashTable synch with the MemArena changes, we need to apply changes  to only those objects that
 // are allocated primarily to be added into hash-table. This function returns the original allocated MemArena against a key
 // so that at time of MemArena updates _itemDict-->MmfObjectPtr-->MemArena is the one to be updated
 internal static MemArena GetActualArena(MemArena arenaCopy)
 {
     if (arenaCopy != null)
     {
         if (!arenaCopy.IsFree)
         {
             byte[]    data    = arenaCopy.GetMemContents();
             StoreItem item    = StoreItem.FromBinary(data, arenaCopy.View.ParentStorageProvider.CacheContext);
             MemArena  arenAct = arenaCopy.View.ParentStorageProvider.GetMemArena(item.Key);
             return(arenAct);
         }
         else
         {
             return(arenaCopy);
         }
     }
     return(null);
 }
Esempio n. 8
0
        /// <summary>
        /// Creates and returns a Ptr to object.
        /// </summary>
        public MmfObjectPtr GetPtr(uint vid, uint offset)
        {
            View view = _viewManager.GetViewByID(vid);

            if (view == null)
            {
                return(null);
            }

            try
            {
                MemArena arena = view.ArenaAtOffset(offset);
                return(new MmfObjectPtr(view, arena));
            }
            catch (Exception)
            {
            }
            return(null);
        }
Esempio n. 9
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);
        }
Esempio n. 10
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());
        }
Esempio n. 11
0
        /// <summary>
        /// Formats the view and writes a valid header. Analogous to a
        /// hard-disk format operation.
        /// </summary>
        public void Format()
        {
            if (!IsOpen)
            {
                return;
            }

            int headerSize = ViewHeader.Size;

            Signature              = ViewHeader.SIGNATURE;
            FreeSpace              = MaxFreeSpace = (uint)(_view.Length - headerSize);
            MyFreeSpace            = FreeSpace;
            _parentStorageProvider = null;
            MemArena arena = FirstArena();

            arena.IsFree     = true;
            arena.Capacity   = (uint)(_view.Length - headerSize - MemArena.Header.Size);
            arena.OffsetNext = 0;
            arena.OffsetPrev = 0;
        }
Esempio n. 12
0
        public MemArena DeAllocate(MemArena arena)
        {
            if (arena.IsFree)
            {
                return(arena);
            }

            uint freedMem = arena.Capacity;

            arena.View.MyFreeSpace += arena.Capacity;
            arena.IsFree            = true;
            arena        = MemArena.CoalesceAdjacent(arena);
            arena.IsFree = true;

            FreeSpace = MyFreeSpace - (uint)MemArena.Header.Size;
            //CalculateArenaMemoryUsage(); removing it..

            Usage++;

            return(arena);
        }
Esempio n. 13
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);
        }
Esempio n. 14
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;
        }
Esempio n. 15
0
        public bool SetMemContents(byte[] value)
        {
            // capacity minus data-length minus data
            int diff = (int)(Capacity - Content.RequiredSpace((uint)value.Length));

            if (diff >= 0)
            {
                Content item = new Content();
                item.Data = value;
                item.RawWrite(RawView, (int)DataOffset);

                if (diff > SPLIT_THRESHOLD)
                {
                    MemArena newArena = SplitArena(this, Content.RequiredSpace((uint)value.Length));
                    if (newArena != this)
                    {
                        newArena.IsFree = true;
                    }
                }

                return(true);
            }
            return(false);
        }
Esempio n. 16
0
 public MmfStorageEnumerator(MmfStorage storage)
 {
     _storage = storage;
     _view    = _storage._viewManager.GetViewByID(0);
     _arena   = null;
 }
Esempio n. 17
0
 void IEnumerator.Reset()
 {
     _view  = _storage._viewManager.GetViewByID(0);
     _arena = null;
 }
Esempio n. 18
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);
        }
Esempio n. 19
0
 /// <summary>
 /// Returns true if the specified arenas are adjacent in the view.
 /// </summary>
 private static bool AreAdjacent(MemArena arena1, MemArena arena2)
 {
     return(arena1.OffsetNext == arena2.Offset ||
            arena2.OffsetNext == arena1.Offset);
 }