/******************************************************************************* * 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.db.layer0.genericrelation.combinators; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.simantics.db.ReadGraph; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.adapter.GenericRelation; import org.simantics.db.layer0.genericrelation.AbstractRelation; import org.simantics.utils.datastructures.Pair; /** * Takes the intersection of multiple relations. */ public class Intersection extends AbstractRelation { GenericRelation realizable = null; Collection constraints; public Intersection(Collection relations) { for(GenericRelation relation : relations) if(realizable == null && relation.isRealizable()) { realizable = relation; } else constraints.add(relation); } public Intersection(GenericRelation realizable, Collection constraints) { assert(realizable.isRealizable()); this.realizable = realizable; this.constraints = constraints; } @Override public boolean contains(ReadGraph g, Object[] tuple) throws DatabaseException { if(!realizable.contains(g, tuple)) return false; for(GenericRelation relation : constraints) if(!relation.contains(g, tuple)) return false; return true; } @Override public boolean isRealizable() { return realizable != null; } @Override public List realize(ReadGraph g) throws DatabaseException { ArrayList result = new ArrayList(); loop: for(Object[] tuple : realizable.realize(g)) { for(GenericRelation constraint : constraints) if(!constraint.contains(g, tuple)) continue loop; result.add(tuple); } return result; } // TODO optimize select @Override public GenericRelation selectByRelation(String bindingPattern, GenericRelation constraint) { if(realizable != null) return new Intersection(realizable.selectByRelation(bindingPattern, constraint), constraints); else return super.selectByRelation(bindingPattern, constraint); } @Override public Pair[] getFields() { if(realizable != null) return realizable.getFields(); for(GenericRelation relation : constraints) return relation.getFields(); return null; } }