package org.simantics.acorn.lru; import java.util.ArrayList; import org.simantics.acorn.ClusterManager; import org.simantics.acorn.exception.AcornAccessVerificationException; import org.simantics.acorn.exception.IllegalAcornStateException; import org.simantics.acorn.internal.Change; import org.simantics.acorn.internal.ClusterChange; import org.simantics.db.procore.cluster.ClusterTraits; import org.simantics.db.service.ClusterUID; import gnu.trove.list.array.TByteArrayList; public class ClusterChangeSet { public enum Type { ADD,REMOVE,VALUE } public static class Entry { final Type type; final short subject; final short predicate; final short object; final ClusterUID predicateUID; final ClusterUID objectUID; final boolean oldValueEx; final byte[] oldValue; final byte[] newValue; public Entry(Type type, int subject, ClusterUID predicateUID, int predicate, ClusterUID objectUID, int object) { this.type = type; this.subject = (short)(subject & 0xFFF); this.predicate = (short)predicate; this.object = (short)object; this.predicateUID = predicateUID; this.objectUID = objectUID; this.oldValueEx = false; this.oldValue = null; this.newValue = null; } public Entry(int subject, boolean oldValueEx, byte[] oldValue, byte[] newValue) throws IllegalAcornStateException { if(oldValue == null && newValue == null) throw new IllegalAcornStateException("oldValue == null && newValue == null"); this.type = Type.VALUE; this.subject = (short)(subject & 0xFFF); this.predicate = 0; this.object = 0; this.predicateUID = null; this.objectUID = null; this.oldValueEx = oldValueEx; this.oldValue = oldValue; this.newValue = newValue; } public void process(ClusterManager clusters, ClusterChange cs, int clusterKey) throws AcornAccessVerificationException { Entry e = this; if(e.type == Type.VALUE) { if(e.oldValue != null) { cs.setValue(e.subject, e.oldValue, e.oldValue.length); } else { Change change = new Change(); change.addStatementIndex(e.subject, null, ClusterChange.DELETE_OPERATION); cs.addChange(change); } } else if(e.type == Type.ADD) { int s = ClusterTraits.createResourceKeyNoThrow(clusterKey, e.subject); int p = clusters.getResourceKey(e.predicateUID, e.predicate); int o = clusters.getResourceKey(e.objectUID, e.object); Change change = new Change(); change.addStatementIndex(s, null, ClusterChange.REMOVE_OPERATION); change.addStatementIndex(p, e.predicateUID, (byte)0); change.addStatementIndex(o, e.objectUID, (byte)0); cs.addChange(change); } else if(e.type == Type.REMOVE) { int s = ClusterTraits.createResourceKeyNoThrow(clusterKey, e.subject); int p = clusters.getResourceKey(e.predicateUID, e.predicate); int o = clusters.getResourceKey(e.objectUID, e.object); Change change = new Change(); change.addStatementIndex(s, null, ClusterChange.ADD_OPERATION); change.addStatementIndex(p, e.predicateUID, (byte)0); change.addStatementIndex(o, e.objectUID, (byte)0); cs.addChange(change); } } } final public String id; final public ClusterUID cuid; public String chunkKey; public int chunkOffset = -1; public TByteArrayList statementMask = new TByteArrayList(); public TByteArrayList oldValueEx = new TByteArrayList(); public ArrayList oldValues = new ArrayList(); public ClusterChangeSet(String id ,ClusterUID cuid) { this.id = id; this.cuid = cuid; String[] ss = id.split("\\."); chunkKey = ss[0]; chunkOffset = Integer.parseInt(ss[1]); } public ClusterStreamChunk getChunk(ClusterManager manager) throws AcornAccessVerificationException { return manager.streamLRU.get(chunkKey); } }