/// <summary> /// Move para o próximo item. /// </summary> /// <returns></returns> bool IEnumerator.MoveNext() { if (_view == null) { return(false); } _storage._viewManager.OpenView(_view); if (_area == null) { _area = _view.FirstArea(); } else { _area = _area.NextArea(); if (_area == null) { _view = _storage._viewManager.GetViewByID(_view.ID + 1); if (_view != null) { _storage._viewManager.OpenView(_view); _area = _view.FirstArea(); } } } return(_area != null); }
/// <summary> /// Calcula a area da memória usada. /// </summary> private void CalculateAreaMemoryUsage() { MemArea arena = this.FirstArea(); MemArea arena2 = this.FirstArea(); uint capacity = 0; uint num2 = 0; while (arena != null) { try { if (arena.IsFree) { num2 += arena.Capacity; if (arena.Capacity >= capacity) { capacity = arena.Capacity; } } arena = arena.NextArea(); if ((arena != null) && (arena.OffsetNext == arena2.Offset)) { arena.OffsetNext = 0; } continue; } catch (Exception exception) { throw new Exception(exception.Message); } } this.FreeSpace = num2; this.MaxFreeSpace = capacity; this.MyFreeSpace = this.FreeSpace + ((uint)MemArea.Header.Size); }
/// <summary> /// Desfragmenta. /// </summary> /// <returns></returns> public MemArea DeFragment() { MemArea arena2; MemArea arena = this.FirstArea(); arena2 = arena.NextArea(); while (arena2 != null) { if (!arena.IsFree) { arena = arena2; } else if (arena2.IsFree) { arena = MemArea.CoalesceAdjacent(arena2); } else { MemArea.SwapAdjacent(arena2, arena); arena = arena2; } arena2 = arena.NextArea(); } this.FreeSpace = arena.Capacity; this.MaxFreeSpace = arena.Capacity; this.CalculateAreaMemoryUsage(); return(arena); }
/// <summary> /// Divida a <see cref="MemArea"/> em partes com o tamanhon informado. /// </summary> /// <param name="area"></param> /// <param name="size"></param> /// <returns></returns> internal static MemArea SplitArea(MemArea area, uint size) { uint num = size + ((uint)Header.Size); if (area.OffsetNext != 0) { area.Capacity = area.OffsetNext - (area.Offset + ((uint)Header.Size)); } if (num > area.Capacity) { return(null); } uint num2 = (area.Capacity - size) - ((uint)Header.Size); if (num2 < SPLIT_THRESHOLD) { View view1 = area.View; view1.MyFreeSpace -= area.Capacity + ((uint)Header.Size); return(area); } area.Capacity = size; MemArea arena2 = area.View.AreaAtOffset(area.Offset + area.TotalLength); arena2.Capacity = num2; View view = area.View; view.MyFreeSpace -= num; MemArea arenaCopy = area.NextArea(); SetNextArea(arena2, GetActualArea(arenaCopy)); SetNextArea(area, arena2); return(arena2); }
/// <summary> /// Aloca uma <see cref="MemArea"/> com o tamanho informado. /// </summary> /// <param name="size"></param> /// <returns></returns> public MemArea Allocate(uint size) { if (size > this.FreeSpace) { return(null); } MemArea arena = null; size = MemArea.Content.RequiredSpace(size); arena = this.FindFirstFreeArena(size); if (arena == null) { this.CalculateAreaMemoryUsage(); arena = this.DeFragment(); if (arena == null) { return(arena); } } MemArea arena2 = MemArea.SplitArea(arena, size); if (arena2 != null) { arena.IsFree = false; if (arena != arena2) { arena2.IsFree = true; _lastFreeArena = arena2; } this.FreeSpace = this.MyFreeSpace - ((uint)MemArea.Header.Size); this.Usage++; } return(arena); }
/// <summary> /// Verifica se as areas informadas são adjacentes. /// </summary> /// <param name="area1"></param> /// <param name="area2"></param> /// <returns></returns> private static bool AreAdjacent(MemArea area1, MemArea area2) { if (area1.OffsetNext != area2.Offset) { return(area2.OffsetNext == area1.Offset); } return(true); }
/// <summary> /// Adquire uma area adjacente. /// </summary> /// <param name="area"></param> /// <returns></returns> internal static MemArea CoalesceAdjacent(MemArea area) { if (area.IsFree) { MemArea arenaCopy = area.NextArea(); int num = 0; if (arenaCopy != null) { uint num2 = 0; while ((arenaCopy != null) && arenaCopy.IsFree) { num++; num2 += arenaCopy.TotalLength; arenaCopy = arenaCopy.NextArea(); } if (num2 > 0) { area.Capacity += num2; uint capacity = area.Capacity; area = SetNextArea(area, GetActualArea(arenaCopy)); area.Capacity = capacity; } } if (area.HasPrevious) { uint num4 = 0; MemArea arena3 = area; MemArea arena4 = null; while (true) { arena4 = arena3.PreviousArea(); if ((arena4 == null) || !arena4.IsFree) { break; } num4 += arena4.TotalLength; arena3 = arena4; num++; } if (num4 > 0) { area.Capacity += num4; uint num5 = area.Capacity; area.NextArea(); area = SetNextArea(arena3, GetActualArea(arenaCopy)); area.Capacity = num5; } } if (num > 0) { View view = area.View; view.MyFreeSpace += (uint)(num * Header.Size); } } return(area); }
/// <summary> /// Define a area anterior. /// </summary> /// <param name="arena"></param> /// <param name="arenaPrev"></param> /// <returns></returns> private static MemArea SetPreviousArena(MemArea arena, MemArea arenaPrev) { if ((arenaPrev == null) || (arenaPrev != arena)) { arena.OffsetPrev = (arenaPrev == null) ? 0 : arenaPrev.Offset; if (arenaPrev != null) { arenaPrev.OffsetNext = arena.Offset; } } return(arena); }
/// <summary> /// Define a próxima area. /// </summary> /// <param name="arena"></param> /// <param name="arenaNext"></param> /// <returns></returns> private static MemArea SetNextArea(MemArea arena, MemArea arenaNext) { if ((arenaNext == null) || (arenaNext != arena)) { arena.OffsetNext = (arenaNext == null) ? 0 : arenaNext.Offset; if (arenaNext != null) { arenaNext.OffsetPrev = arena.Offset; } } return(arena); }
/// <summary> /// Recupera a <see cref="MemArea"/> associado com os dados armazenados na <see cref="MemArea"/> informada. /// </summary> /// <param name="areaCopy"><see cref="MemArea"/> com os dados do item de armazenamento.</param> /// <returns></returns> internal static MemArea GetActualArea(MemArea areaCopy) { if (areaCopy == null) { return(null); } if (!areaCopy.IsFree) { StoreItem item = StoreItem.FromBinary(areaCopy.GetMemContents(), areaCopy.View.ParentStorageProvider.CacheContext); return(areaCopy.View.ParentStorageProvider.GetMemArea(item.Key)); } return(areaCopy); }
/// <summary> /// Recupera o texto que representa a instancia. /// </summary> /// <returns></returns> public override string ToString() { StringBuilder builder = new StringBuilder(); builder.Append("View, ID=").Append(this.ID).Append(", maxFree=").Append(this.MaxFreeSpace).Append(", Free=").Append(this.FreeSpace).Append("\r\n"); if (this.IsOpen) { for (MemArea arena = this.FirstArea(); arena != null; arena = arena.NextArea()) { builder.Append(arena.ToString()).Append("\r\n"); } } return(builder.ToString()); }
/// <summary> /// Desaloca a <see cref="MemArea"/> informada. /// </summary> /// <param name="area"><see cref="MemArea"/> que será desalocada.</param> /// <returns></returns> public MemArea DeAllocate(MemArea area) { if (!area.IsFree) { uint capacity = area.Capacity; View view = area.View; view.MyFreeSpace += area.Capacity; area.IsFree = true; area = MemArea.CoalesceAdjacent(area); area.IsFree = true; this.FreeSpace = this.MyFreeSpace - ((uint)MemArea.Header.Size); this.Usage++; } return(area); }
/// <summary> /// Formata os dados da instancia. /// </summary> public void Format() { if (this.IsOpen) { int size = ViewHeader.Size; this.Signature = 0xface0ff; this.FreeSpace = this.MaxFreeSpace = _view.Length - ((uint)size); this.MyFreeSpace = this.FreeSpace; _parentStorageProvider = null; MemArea arena = this.FirstArea(); arena.IsFree = true; arena.Capacity = (uint)((_view.Length - size) - MemArea.Header.Size); arena.OffsetNext = 0; arena.OffsetPrev = 0; } }
/// <summary> /// Adiciona os dados do item na memória. /// </summary> /// <param name="item">Buffer com os dados que serão adicionados.</param> /// <returns>Ponteiro dos dados adicionados.</returns> 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"); } View matchingView = _viewManager.GetMatchingView((uint)item.Length); try { if (matchingView == null) { this.GrowMemoryMappedStore(1); matchingView = _viewManager.GetMatchingView((uint)item.Length); } if (matchingView != null) { MemArea area = matchingView.Allocate((uint)item.Length); if (area == null) { return(null); } if (!area.SetMemContents(item)) { matchingView.DeAllocate(area); return(null); } return(new MmfObjectPtr(matchingView, area)); } } catch (OutOfMemoryException) { throw; } catch (Exception) { throw; } return(null); }
/// <summary> /// Define o buffer com o conteúdo. /// </summary> /// <param name="value"></param> /// <returns></returns> public bool SetMemContents(byte[] value) { int num = (int)(this.Capacity - Content.RequiredSpace((uint)value.Length)); if (num < 0) { return(false); } Content content = new Content(); content.Data = value; content.RawWrite(this.RawView, (int)this.DataOffset); if (num > SPLIT_THRESHOLD) { MemArea arena = SplitArea(this, Content.RequiredSpace((uint)value.Length)); if (arena != this) { arena.IsFree = true; } } return(true); }
/// <summary> /// Realiza a troca a <see cref="MemArea"/> adjacente. /// </summary> /// <param name="arena1"></param> /// <param name="arena2"></param> internal static void SwapAdjacent(MemArea arena1, MemArea arena2) { arena1 = GetActualArea(arena1); arena2 = GetActualArea(arena2); if (AreAdjacent(arena1, arena2)) { MemArea arena = arena1; MemArea arena3 = arena2; if (arena1.Offset > arena2.Offset) { arena = arena2; arena3 = arena1; } Header arenaHeader = arena.AreaHeader; Header header2 = arena3.AreaHeader; MemArea arenaCopy = arena3.NextArea(); MemArea actualArena = arena.PreviousArea(); arenaCopy = GetActualArea(arenaCopy); actualArena = GetActualArea(actualArena); int count = arena.IsFree ? Header.Size : ((int)arena.TotalLength); int num2 = arena3.IsFree ? Header.Size : ((int)arena3.TotalLength); byte[] buffer = arena.RawView.Read((int)arena.Offset, count); byte[] buffer2 = arena3.RawView.Read((int)arena3.Offset, num2); arena3._offset = arena.Offset + arena3.TotalLength; arena.RawView.Write(buffer2, (int)arena.Offset, buffer2.Length); arena3.RawView.Write(buffer, (int)arena3.Offset, buffer.Length); arena.IsFree = header2.IsFree; arena.Capacity = header2.Capacity; arena.OffsetNext = arena3.Offset; arena.OffsetPrev = arenaHeader.OffsetPrev; SetPreviousArena(arena, actualArena); arena3.IsFree = arenaHeader.IsFree; arena3.Capacity = arenaHeader.Capacity; arena3.OffsetNext = header2.OffsetNext; arena3.OffsetPrev = arena.Offset; SetNextArea(arena3, arenaCopy); } }
/// <summary> /// Procura pela primeira <see cref="MemArea"/> livre. /// </summary> /// <param name="memRequirements">Quantidade de memória requerida.</param> /// <returns><see cref="MemArea"/> disponível.</returns> private MemArea FindFirstFreeArena(uint memRequirements) { memRequirements += (uint)MemArea.Header.Size; MemArea arena = this.FirstArea(); if (arena.OffsetNext != 0) { arena.Capacity = arena.OffsetNext - (arena.Offset + ((uint)MemArea.Header.Size)); } if (((_lastFreeArena == null) || !_lastFreeArena.IsFree) || (_lastFreeArena.Capacity < memRequirements)) { while (arena != null) { if (arena.IsFree && (arena.Capacity >= memRequirements)) { return(arena); } arena = arena.NextArea(); } return(null); } return(_lastFreeArena); }
/// <summary> /// Construtor padrão. /// </summary> /// <param name="storage"></param> public MmfStorageEnumerator(MmfStorage storage) { _storage = storage; _view = _storage._viewManager.GetViewByID(0); _area = null; }
/// <summary> /// Reseta o enumerado. /// </summary> void IEnumerator.Reset() { _view = _storage._viewManager.GetViewByID(0); _area = null; }
/// <summary> /// Cria uma instancia já definindo a visão e o bloco da memória. /// </summary> /// <param name="v"></param> /// <param name="block"></param> public MmfObjectPtr(View v, MemArea block) { this.View = v; this.Area = block; }