package org.eclipse.viatra.solver.data.model.internal; import java.util.HashMap; import java.util.Map; import java.util.Set; import org.eclipse.viatra.solver.data.map.ContinousHashProvider; import org.eclipse.viatra.solver.data.map.Cursor; import org.eclipse.viatra.solver.data.map.DiffCursor; import org.eclipse.viatra.solver.data.map.VersionedMap; import org.eclipse.viatra.solver.data.map.internal.MapDiffCursor; import org.eclipse.viatra.solver.data.model.Model; import org.eclipse.viatra.solver.data.model.ModelDiffCursor; import org.eclipse.viatra.solver.data.model.ModelStore; import org.eclipse.viatra.solver.data.model.representation.DataRepresentation; public class ModelImpl implements Model { private final ModelStore store; private final Map, VersionedMap> maps; public ModelImpl(ModelStore store, Map, VersionedMap> maps) { this.store = store; this.maps = maps; } @Override public Set> getDataRepresentations() { return maps.keySet(); } @SuppressWarnings("unchecked") private VersionedMap getMap(DataRepresentation representation) { if (maps.containsKey(representation)) { return (VersionedMap) maps.get(representation); } else { throw new IllegalArgumentException("Model does have representation " + representation); } } private VersionedMap getMapValidateKey(DataRepresentation representation, K key) { if (representation.isValidKey(key)) { return getMap(representation); } else { throw new IllegalArgumentException( "Key is not valid for representation! (representation=" + representation + ", key=" + key + ");"); } } @Override public V get(DataRepresentation representation, K key) { return getMapValidateKey(representation, key).get(key); } @Override public Cursor getAll(DataRepresentation representation) { return getMap(representation).getAll(); } @Override public V put(DataRepresentation representation, K key, V value) { return getMapValidateKey(representation, key).put(key, value); } @Override public void putAll(DataRepresentation representation, Cursor cursor) { getMap(representation).putAll(cursor); } @Override public long getSize(DataRepresentation representation) { return getMap(representation).getSize(); } @Override public ModelDiffCursor getDiffCursor(long to) { Model toModel = store.createModel(to); Map, DiffCursor> diffCursors = new HashMap<>(); for (DataRepresentation representation : this.maps.keySet()) { MapDiffCursor diffCursor = constructDiffCursor(toModel, representation); diffCursors.put(representation, diffCursor); } return new ModelDiffCursor(diffCursors); } private MapDiffCursor constructDiffCursor(Model toModel, DataRepresentation representation) { @SuppressWarnings("unchecked") Cursor fromCursor = (Cursor) this.maps.get(representation).getAll(); Cursor toCursor = toModel.getAll(representation); ContinousHashProvider hashProvider = representation.getHashProvider(); V defaultValue = representation.getDefaultValue(); return new MapDiffCursor<>(hashProvider, defaultValue, fromCursor, toCursor); } @Override public long commit() { long version = 0; boolean versionSet = false; for (VersionedMap map : maps.values()) { long newVersion = map.commit(); if (versionSet) { if (version != newVersion) { throw new IllegalStateException( "Maps in model have different versions! (" + version + " and" + newVersion + ")"); } } else { version = newVersion; versionSet = true; } } return version; } @Override public void restore(long state) { if(store.getStates().contains(state)) { for (VersionedMap map : maps.values()) { map.restore(state); } } else { throw new IllegalArgumentException("Map does not contain state "+state+"!"); } } }