TurtleDB
A mini distributed database system
src/ca/uqac/dim/turtledb/Intersection.java
Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002     Simple distributed database engine
00003     Copyright (C) 2012  Sylvain Hallé
00004 
00005     This program is free software: you can redistribute it and/or modify
00006     it under the terms of the GNU General Public License as published by
00007     the Free Software Foundation, either version 3 of the License, or
00008     (at your option) any later version.
00009 
00010     This program is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with this program.  If not, see <http://www.gnu.org/licenses/>.
00017  -------------------------------------------------------------------------*/
00018 package ca.uqac.dim.turtledb;
00019 
00020 import ca.uqac.dim.turtledb.QueryVisitor.VisitorException;
00021 
00022 public class Intersection extends NAryRelation
00023 {   
00024 
00025   @Override
00026   public void accept(QueryVisitor v) throws VisitorException
00027   {
00028     super.acceptNAry(v);
00029     v.visit(this);
00030   }
00031   
00032   protected class IntersectionIterator extends NAryRelationStreamIterator
00033   {
00039     @Override
00040     protected Tuple internalNext()
00041     {
00042       super.initializeIteration();
00043 
00044       // Iterate through the vector of last tuples and find
00045       // the smallest one
00046       Tuple smallest_tuple = null;
00047       boolean all_equal = false;
00048       do
00049       {
00050         all_equal = allEqual();
00051         smallest_tuple = super.incrementSmallestTuple();
00052       } while (!all_equal && smallest_tuple != null);
00053       // Change tuple's schema to that of first relation
00054       Relation r = m_relations.get(0);
00055       Schema sch = r.getSchema();
00056       Tuple t2 = new Tuple(smallest_tuple);
00057       t2.setSchema(sch);
00058       return t2;
00059     }
00060     
00067     protected boolean allEqual()
00068     {
00069       int len = m_relations.size();
00070       Tuple last_elem = null;
00071       for (int i = 0; i < len; i++)
00072       {
00073         Tuple t = m_lastTuple.elementAt(i);
00074         if (i == 0)
00075         {
00076           last_elem = t;
00077           continue;
00078         }
00079         if (t == null)
00080           return false;
00081         if (!last_elem.equals(t))
00082           return false;
00083       }
00084       return true;
00085     }
00086   }
00087 
00088   @Override
00089   public RelationStreamIterator streamIterator()
00090   {
00091     return new IntersectionIterator();
00092   }
00093 
00094   @Override
00095   public RelationIterator cacheIterator()
00096   {
00097     return new IntersectionCacheIterator();
00098   }
00099   
00100   protected class IntersectionCacheIterator extends NAryRelationCacheIterator
00101   {
00102     @Override
00103     protected void getIntermediateResult()
00104     {
00105       super.getIntermediateResult();
00106       Table tab = new Table(getSchema());
00107       Table first_table = m_results.firstElement();
00108       for (Tuple t : first_table.m_tuples)
00109       {
00110         boolean all_in = true;
00111         for (int i = 1; i < m_results.size(); i++)
00112         {
00113           Table tt = m_results.elementAt(i);
00114           // Set schema of t to that of tt so that it can find it
00115           Schema sch = tt.getSchema();
00116           Tuple t2 = new Tuple(t);
00117           t2.setSchema(sch);
00118           if (!tt.contains(t2))
00119           {
00120             all_in = false;
00121             break;
00122           }
00123         }
00124         if (all_in)
00125           tab.put(t);
00126       }
00127       m_intermediateResult = tab;
00128     }
00129   }
00130 
00131 }