//Gera a lista para gerenciar espaços livres private List <EspacoLivre> GeraListaLivres(Memory memory, List <Frame> InitialFrames) { //lista de espacos livres na memoria List <EspacoLivre> listaEspacoLivre = new List <EspacoLivre>(); //long -> RegB, int -> id(Frame), Dictionary <long, int> mapFrame = new Dictionary <long, int>(); //Mapeia todos os frames utilizados foreach (var item in InitialFrames) { mapFrame.Add(item.RegB, item.ID); } //frames disponiveis int framesLivres = 0; //guarda o regB do primeiro frame livre long regB = 0; //passa por todos registradores base da memória for (long i = 0; i < memory.Size; i += memory.FramesSize) { //verifica se o frame está livre //(está livre) if (!mapFrame.ContainsKey(i)) { //guarda o registrador base do primerio frame disponivel if (framesLivres == 0) { regB = i; } //soma a quantidade de frames livres framesLivres++; } //(Não está livre) else { //Verifica se é necessário criar o objeto if (framesLivres != 0) { EspacoLivre espacoLivre = new EspacoLivre { EspacosLivres = framesLivres, RegB = regB }; listaEspacoLivre.Add(espacoLivre); //reseta a quantidade de frames livres framesLivres = 0; } } } return(listaEspacoLivre); }
public JsonResult AlgSimulation(int?id, string Alg) { try { if (id != null) { Memory memory = _context.Memories.Find(id); if (!memory.IsGeneratedProcessList) { throw new Exception("É necessário gerar a lista de processos."); } string algSimuExistenteError = "Já foi gerada a simulação para esse algoritmo."; if (memory.IsFirstFitCompleted && Alg == "FirstFit") { throw new Exception(algSimuExistenteError); } if (memory.IsNextFitCompleted && Alg == "NextFit") { throw new Exception(algSimuExistenteError); } if (memory.IsBestFitCompleted && Alg == "BestFit") { throw new Exception(algSimuExistenteError); } if (memory.IsWorstFitCompleted && Alg == "WorstFit") { throw new Exception(algSimuExistenteError); } List <Process> processToInsert = GetProcessesToInsert(id); List <Frame> initialFrames = GetInitialFrames(id); List <Frame> framesToInsert = new List <Frame>(); List <EspacoLivre> espacosLivres = GeraListaLivres(memory, initialFrames); int processInserted = 0; // tempo de execução para acha o index do processo var watch = System.Diagnostics.Stopwatch.StartNew(); foreach (var process in processToInsert) { watch.Start(); int framesNeeded = (int)(process.Size / memory.FramesSize); framesNeeded = process.Size % memory.FramesSize > 0 ? framesNeeded + 1 : framesNeeded; if (Alg == "FirstFit") { for (int i = 0; i < espacosLivres.Count; ++i) { //se o processo caber no espaco disponivel na memória if (espacosLivres[i].EspacosLivres >= framesNeeded) { for (int j = 0; j < framesNeeded; ++j) { Frame newFrame = new Frame { IsInitial = false, RegB = espacosLivres[i].RegB + (memory.FramesSize * j), TipoAlg = Frame.TipoAlgVal.FirstFit, MemoryID = memory.ID, ProcessID = process.ID, Name = process.Name, FrameSize = (int)memory.FramesSize }; newFrame.FrameNumber = newFrame.RegB > 0 ? (int)(newFrame.RegB / memory.FramesSize) : 0; //se for o ultimo frame, verifica qual a capacidade utilizada do mesmo if (j + 1 == framesNeeded) { newFrame.CapacidadeUtilizada = (int)(process.Size % memory.FramesSize); } else { newFrame.CapacidadeUtilizada = (int)memory.FramesSize; } framesToInsert.Add(newFrame); } //se for necessario remove o item da lista de livre if (espacosLivres[i].EspacosLivres - framesNeeded == 0) { espacosLivres.RemoveAt(i); } else { //Atualiza a lista de espacos livres int quantidadeLivreAnt = espacosLivres[i].EspacosLivres; long regBAnt = espacosLivres[i].RegB; espacosLivres[i] = new EspacoLivre { RegB = regBAnt + (memory.FramesSize * framesNeeded), EspacosLivres = quantidadeLivreAnt - framesNeeded }; } watch.Stop(); // Get the elapsed time as a TimeSpan value. TimeSpan ts = watch.Elapsed; process.TimeToFindIndexFirst = ts.Milliseconds; processInserted++; break; } } } if (Alg == "NextFit") { bool isFirst = true; for (int i = 0; i < espacosLivres.Count; ++i) { //se o processo caber no espaco disponivel na memória if (espacosLivres[i].EspacosLivres >= framesNeeded && !isFirst) { for (int j = 0; j < framesNeeded; ++j) { Frame newFrame = new Frame { IsInitial = false, RegB = espacosLivres[i].RegB + (memory.FramesSize * j), TipoAlg = Frame.TipoAlgVal.NextFit, MemoryID = memory.ID, ProcessID = process.ID, Name = process.Name, FrameSize = (int)memory.FramesSize }; newFrame.FrameNumber = newFrame.RegB > 0 ? (int)(newFrame.RegB / memory.FramesSize) : 0; //se for o ultimo frame, verifica qual a capacidade utilizada do mesmo if (j + 1 == framesNeeded) { newFrame.CapacidadeUtilizada = (int)(process.Size % memory.FramesSize); } else { newFrame.CapacidadeUtilizada = (int)memory.FramesSize; } framesToInsert.Add(newFrame); } //se for necessario remove o item da lista de livre if (espacosLivres[i].EspacosLivres - framesNeeded == 0) { espacosLivres.RemoveAt(i); } else { //Atualiza a lista de espacos livres int quantidadeLivreAnt = espacosLivres[i].EspacosLivres; long regBAnt = espacosLivres[i].RegB; espacosLivres[i] = new EspacoLivre { RegB = regBAnt + (memory.FramesSize * framesNeeded), EspacosLivres = quantidadeLivreAnt - framesNeeded }; } processInserted++; watch.Stop(); // Get the elapsed time as a TimeSpan value. TimeSpan ts = watch.Elapsed; process.TimeToFindIndexNext = ts.Milliseconds; break; } if (espacosLivres[i].EspacosLivres >= framesNeeded) { if (isFirst) { isFirst = false; } } } } if (Alg == "BestFit") { int?melhorEspaco = null; for (int i = 0; i < espacosLivres.Count; ++i) { if (espacosLivres[i].EspacosLivres >= framesNeeded) { if (melhorEspaco == null) { melhorEspaco = i; } else { if (espacosLivres[(int)melhorEspaco].EspacosLivres > espacosLivres[i].EspacosLivres) { melhorEspaco = i; } } } } //se o processo caber no espaco disponivel na memória if (melhorEspaco != null) { for (int j = 0; j < framesNeeded; ++j) { Frame newFrame = new Frame { IsInitial = false, RegB = espacosLivres[(int)melhorEspaco].RegB + (memory.FramesSize * j), TipoAlg = Frame.TipoAlgVal.BestFit, MemoryID = memory.ID, ProcessID = process.ID, Name = process.Name, FrameSize = (int)memory.FramesSize }; newFrame.FrameNumber = newFrame.RegB > 0 ? (int)(newFrame.RegB / memory.FramesSize) : 0; //se for o ultimo frame, verifica qual a capacidade utilizada do mesmo if (j + 1 == framesNeeded) { newFrame.CapacidadeUtilizada = (int)(process.Size % memory.FramesSize); } else { newFrame.CapacidadeUtilizada = (int)memory.FramesSize; } framesToInsert.Add(newFrame); } //se for necessario remove o item da lista de livre if (espacosLivres[(int)melhorEspaco].EspacosLivres - framesNeeded == 0) { espacosLivres.RemoveAt((int)melhorEspaco); } else { //Atualiza a lista de espacos livres int quantidadeLivreAnt = espacosLivres[(int)melhorEspaco].EspacosLivres; long regBAnt = espacosLivres[(int)melhorEspaco].RegB; espacosLivres[(int)melhorEspaco] = new EspacoLivre { RegB = regBAnt + (memory.FramesSize * framesNeeded), EspacosLivres = quantidadeLivreAnt - framesNeeded }; } processInserted++; watch.Stop(); // Get the elapsed time as a TimeSpan value. TimeSpan ts = watch.Elapsed; process.TimeToFindIndexBest = ts.Milliseconds; } } if (Alg == "WorstFit") { int?piorEspaco = null; for (int i = 0; i < espacosLivres.Count; ++i) { if (espacosLivres[i].EspacosLivres >= framesNeeded) { if (piorEspaco == null) { piorEspaco = i; } else { if (espacosLivres[(int)piorEspaco].EspacosLivres < espacosLivres[i].EspacosLivres) { piorEspaco = i; } } } } //se o processo caber no espaco disponivel na memória if (piorEspaco != null) { for (int j = 0; j < framesNeeded; ++j) { Frame newFrame = new Frame { IsInitial = false, RegB = espacosLivres[(int)piorEspaco].RegB + (memory.FramesSize * j), TipoAlg = Frame.TipoAlgVal.WorstFit, MemoryID = memory.ID, ProcessID = process.ID, Name = process.Name, FrameSize = (int)memory.FramesSize }; newFrame.FrameNumber = newFrame.RegB > 0 ? (int)(newFrame.RegB / memory.FramesSize) : 0; //se for o ultimo frame, verifica qual a capacidade utilizada do mesmo if (j + 1 == framesNeeded) { newFrame.CapacidadeUtilizada = (int)(process.Size % memory.FramesSize); } else { newFrame.CapacidadeUtilizada = (int)memory.FramesSize; } framesToInsert.Add(newFrame); } //se for necessario remove o item da lista de livre if (espacosLivres[(int)piorEspaco].EspacosLivres - framesNeeded == 0) { espacosLivres.RemoveAt((int)piorEspaco); } else { //Atualiza a lista de espacos livres int quantidadeLivreAnt = espacosLivres[(int)piorEspaco].EspacosLivres; long regBAnt = espacosLivres[(int)piorEspaco].RegB; espacosLivres[(int)piorEspaco] = new EspacoLivre { RegB = regBAnt + (memory.FramesSize * framesNeeded), EspacosLivres = quantidadeLivreAnt - framesNeeded }; } processInserted++; watch.Stop(); // Get the elapsed time as a TimeSpan value. TimeSpan ts = watch.Elapsed; process.TimeToFindIndexWorst = ts.Milliseconds; } } } switch (Alg) { case "FirstFit": memory.IsFirstFitCompleted = true; memory.FirstFitInseridos = processInserted; break; case "NextFit": memory.IsNextFitCompleted = true; memory.NextFitInseridos = processInserted; break; case "BestFit": memory.IsBestFitCompleted = true; memory.BestFitInseridos = processInserted; break; case "WorstFit": memory.IsWorstFitCompleted = true; memory.WorstFitInseridos = processInserted; break; } _context.Frames.AddRange(framesToInsert); _context.Processes.UpdateRange(processToInsert); _context.Memories.Update(memory); _context.SaveChanges(); return(Json( new { processos = processInserted, success = true } )); } else { throw new Exception("Mémoria não informada!"); } } catch (Exception e) { return(Json( new { success = false, error = e.Message } )); } }