import java.util.Scanner;

public class MemoryHierarchy {
	
	// Variaveis para contagem de tempo
	private static long tempoInicio;
	private static long tempoPadara;
	
	// Definição do tamanho de cada memória
    private static final int CACHE_SIZE = 5;
    private static final int RAM_SIZE = 8;
    private static final int DISK_SIZE = 10;
    
    // Definição do tempo de demora de busca em cada memória
    private static final int CACHE_TIME = 1;
    private static final int RAM_TIME = 10;
    private static final int DISK_TIME = 100;

    // Memorias simuladas
    private int[] cache;
    private int[] ram;
    private int[] disk;
    
    private int cache_indice;
    private int ram_indice;
    
    private int valor_encontrado;

    public MemoryHierarchy() 
    {
        cache = new int[CACHE_SIZE];
        ram = new int[RAM_SIZE];
        disk = new int[DISK_SIZE];
        
        cache_indice = 0;
        ram_indice = 0;

        // Inicializa o cache com valores inexistentes (0)
        for (int i = 0; i < CACHE_SIZE; i++) {
            cache[i] = 0;
        }

        // Inicializa a RAM com valores inexistentes (0)
        for (int i = 0; i < RAM_SIZE; i++) {
            ram[i] = 0;
        }

        // Inicializa o disco com valores aleatórios
        for (int i = 0; i < DISK_SIZE; i++) {
            disk[i] = (int) (Math.random() * 900 + 100); // Valores entre 100 e 999
        }
    }

    public void buscaNaMemoria(int endereco) 
    {
        // Verifica se o valor está no cache (nível 1)
    	boolean encontrouNoCache = buscaNoCache(endereco);
    	
    	if(encontrouNoCache)
    	{
    		return;
    	}

        // Verifica se o valor está na RAM (nível 2)
    	boolean encontrouNaRAM = buscaNaRAM(endereco);
    	
    	if(encontrouNaRAM)
    	{
    		salvaNoCache();
    		return;
    	}
    	
        // Se não está no cache ou na RAM, acessa o disco (nível 3)
    	buscaNoDisco(endereco);
    	
    	salvaNaRAM();
    	salvaNoCache();
    	
    	return;
    }
    
    private boolean buscaNoCache(int endereco)
    {
        for (int i = 0; i < CACHE_SIZE; i++) 
        {
            if (cache[i] == disk[endereco]) 
            {
            	simulaTempo(CACHE_TIME);  // Simula o tempo de acesso ao cache
                valor_encontrado = cache[i];
                System.out.println("Valor " + valor_encontrado + " encontrado no Cache (nível 1).");
                return true;
            }
        }
        return false;
    }
    
    private boolean buscaNaRAM(int endereco)
    {
        for (int i = 0; i < RAM_SIZE; i++) 
        {
            if (ram[i] == disk[endereco]) 
            {
            	simulaTempo(RAM_TIME);  // Simula o tempo de acesso à RAM
                valor_encontrado = ram[i];
                System.out.println("Valor " + valor_encontrado + " encontrado na RAM (nível 2).");
                return true;
            }
        }
        return false;
    }
    
    private boolean buscaNoDisco(int endereco)
    {
    	simulaTempo(DISK_TIME);  // Simula o tempo de acesso à RAM
        valor_encontrado = disk[endereco];
        System.out.println("Valor " + valor_encontrado + " encontrado no Disco (nível 3).");
        return true;
    }
    
    private void salvaNoCache()
    {
    	// Se há espaço vazio no cache, apenas adiciona
        if (cache_indice < CACHE_SIZE) {
            cache[cache_indice++] = valor_encontrado;
        }
        // Se não há espaço vazio no cache, move todo o cache para criar espaço
        else {
            System.arraycopy(cache, 1, cache, 0, CACHE_SIZE - 1);
            cache[CACHE_SIZE - 1] = valor_encontrado;
        }
        System.out.println("Valor " + valor_encontrado + " adicionado no Cache (nível 1).");
        return;
    }
    
    private void salvaNaRAM()
    {
    	// Se há espaço vazio na ram, apenas adiciona
        if (ram_indice < RAM_SIZE) {
            ram[ram_indice++] = valor_encontrado;
        }
        // Se não há espaço vazio na ram, move toda a ram para criar espaço
        else {
            System.arraycopy(ram, 1, ram, 0, RAM_SIZE - 1);
            ram[RAM_SIZE - 1] = valor_encontrado;
        }
        System.out.println("Valor " + valor_encontrado + " adicionado na RAM (nível 2).");
        return;
    }

    private void simulaTempo(int milliseconds) {
        try {
            Thread.sleep(milliseconds);
        } catch (InterruptedException e) {
            System.err.println("Erro ao simular o tempo de espera.");
        }
    }
    
    private void imprimeMemorias()
    {
    	System.out.print("\r\n");
    	System.out.println("Memórias:");
    	
    	System.out.print("CACHE\t");
    	for(int i=0; i < CACHE_SIZE; i++)
    	{
    		System.out.print(String.format("%03d", cache[i]) + "\t");
    	}
    	System.out.print("\r\n");
    	System.out.print("RAM\t");
    	for(int i=0; i < RAM_SIZE; i++)
    	{
    		System.out.print(String.format("%03d", ram[i]) + "\t");
    	}
    	System.out.print("\r\n");
    	System.out.print("DISCO\t");
    	for(int i=0; i < DISK_SIZE; i++)
    	{
    		System.out.print(String.format("%03d", disk[i]) + "\t");
    	}
    	System.out.print("\r\n");
    	System.out.print("\r\n");
    }
    
    private void iniciarContagemTempo()
    {
        tempoInicio = System.nanoTime();
    }
    
    private void pararContagemTempo()
    {
        tempoPadara = System.nanoTime();
    }
    
    private void imprimirContagemTempo()
    {
        long duracao = (tempoPadara - tempoInicio) / 1_000_000;
        
        System.out.println("Operacao realiza em " + duracao + " milisegundos.");
    }
    
    

    public static void main(String[] args) {
        MemoryHierarchy memory = new MemoryHierarchy();
        Scanner scanner = new Scanner(System.in);
        int address;

        System.out.println("Simulação de Hierarquia de Memória");

        // Loop para interação com o usuário
        while (true) {
        	memory.imprimeMemorias();
        	
            System.out.print("Digite o endereço de memória (0-9) para acessar ou -1 para sair: ");
            address = scanner.nextInt();

            if (address == -1) {
                break;
            }

            if (address >= 0 && address < DISK_SIZE) {
                memory.iniciarContagemTempo();
                memory.buscaNaMemoria(address);
                memory.pararContagemTempo();
                memory.imprimirContagemTempo();
            } else {
                System.out.println("Endereço inválido. Tente novamente.");
            }
        }

        scanner.close();
    }
}

Embed on website

To embed this program on your website, copy the following code and paste it into your website's HTML: