/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.layer0.utils.writer; import gnu.trove.list.array.TIntArrayList; import gnu.trove.map.hash.TIntObjectHashMap; import gnu.trove.map.hash.TObjectIntHashMap; import java.util.ArrayList; import org.eclipse.core.runtime.IProgressMonitor; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.Session; import org.simantics.db.WriteOnlyGraph; import org.simantics.db.exception.DatabaseException; public abstract class AbstractDelayedGraphWriter extends GraphWriterPartial { protected int current = 0; int externalCount = 0; protected int internalCount = 0; ArrayList externals = new ArrayList(); protected TObjectIntHashMap externalsInv = new TObjectIntHashMap(); protected TIntObjectHashMap inverses = new TIntObjectHashMap(); TIntArrayList timestamps = new TIntArrayList(); long[] resourceIds; int time = 0; public long getResourceId(Session session, Resource r) { if(r instanceof InternalResource) { if(resourceIds == null) { System.out.println("ERROR. Requesting resource id for new resource in writer before ids have been assigned."); return 0; } return resourceIds[((InternalResource)r).id-1]; } else { return r.getResourceId(); } } protected static class InternalResource implements Resource { int id; public InternalResource(int id) { this.id = id; } @Override public long getResourceId() { return (long)id; } @Override public Resource get() { return this; } @Override public boolean isPersistent() { return false; } @Override public boolean equals(Object obj) { return this==obj || (obj instanceof InternalResource && ((InternalResource)obj).id == id); } @Override public boolean equalsResource(Resource other) { return equals(other); } @Override public int hashCode() { return id; } @Override public int getThreadHash() { return id>>>16; } @Override public int compareTo(Resource o) { if(this==o) return 0; if(o instanceof InternalResource) return id - ((InternalResource)o).id; else return -1; } } public AbstractDelayedGraphWriter(ReadGraph graph) { super(graph); } @Override public GraphWriter create() { current = ++internalCount; timestamps.add(0); return this; } @Override public Resource get() { if(current > 0) return new InternalResource(current); else if(current < 0) return externals.get(-1-current); else return null; } protected int getId(Resource r) { if(r instanceof InternalResource) return ((InternalResource)r).id; int id = externalsInv.get(r); if(id==0) { id = -(++externalCount); externals.add(r); externalsInv.put(r, id); } return id; } @Override public GraphWriter handle(Resource s) { current = getId(s); return this; } protected int getPredicateId(Resource p) throws DatabaseException { int pId = getId(p); if(!inverses.contains(pId)) if(!(p instanceof InternalResource)) inverses.put(pId, graph.getInverse(p)); return pId; } public abstract void commit(IProgressMonitor monitor, WriteOnlyGraph wg) throws DatabaseException; }