+++ /dev/null
-package net.mograsim.machine;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Set;
-
-public abstract class GenericMemory<T> implements Memory<T>
-{
- private final long minimalAddress, maximalAddress;
- private final MemoryDefinition definition;
- private final int pageSize = 64;
- private Set<MemoryObserver> observers = new HashSet<>();
-
- private HashMap<Long, Page> pages;
-
- public GenericMemory(MemoryDefinition definition)
- {
- super();
- this.definition = definition;
- this.minimalAddress = definition.getMinimalAddress();
- this.maximalAddress = definition.getMaximalAddress();
- this.pages = new HashMap<>();
- }
-
- private void inBoundsCheck(long address)
- {
- if (address < minimalAddress || address > maximalAddress)
- throw new IndexOutOfBoundsException(String.format("Memory address out of bounds! Minimum: %d Maximum: %d Actual: %d",
- minimalAddress, maximalAddress, address));
- }
-
- private long page(long address)
- {
- return address / pageSize;
- }
-
- private int offset(long address)
- {
- return (int) (address % pageSize);
- }
-
- @Override
- public void setCell(long address, T data)
- {
- inBoundsCheck(address);
- long page = page(address);
- int offset = offset(address);
- Page p = pages.get(Long.valueOf(page));
- if (p == null)
- pages.put(page, p = new Page());
- p.setCell(offset, data);
- notifyObservers(address);
- }
-
- @Override
- public T getCell(long address)
- {
- inBoundsCheck(address);
- long page = page(address);
- int offset = offset(address);
- Page p = pages.get(Long.valueOf(page));
- if (p == null)
- return null;
- return p.getCell(offset);
- }
-
- private class Page
- {
- private Object[] memory;
-
- public Page()
- {
- memory = new Object[pageSize];
- }
-
- public T getCell(int index)
- {
- @SuppressWarnings("unchecked")
- T data = (T) memory[index];
- return data;
- }
-
- public void setCell(int index, T data)
- {
- memory[index] = data;
- }
-
- @Override
- public String toString()
- {
- return Arrays.deepToString(memory);
- }
- }
-
- @Override
- public void registerObserver(MemoryObserver ob)
- {
- observers.add(ob);
- }
-
- @Override
- public void deregisterObserver(MemoryObserver ob)
- {
- observers.remove(ob);
- }
-
- @Override
- public void notifyObservers(long address)
- {
- observers.forEach(ob -> ob.update(address));
- }
-
- @Override
- public MemoryDefinition getDefinition()
- {
- return definition;
- }
-}