TurtleDB
A mini distributed database system
src/ca/uqac/dim/turtledb/Product.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 java.util.Iterator;
00021 
00022 import ca.uqac.dim.turtledb.QueryVisitor.VisitorException;
00023 
00024 public class Product extends NAryRelation
00025 { 
00026   @Override
00027   public Schema getSchema()
00028   {
00029     Schema sch = new Schema();
00030     for (Relation r : m_relations)
00031     {
00032       Schema s = r.getSchema();
00033       sch.addAll(s);
00034     }
00035     return sch;
00036   }
00037   
00038 
00039   @Override
00040   public void accept(QueryVisitor v) throws VisitorException
00041   {
00042     super.acceptNAry(v);
00043     v.visit(this);
00044   }
00045   
00046   protected class ProductStreamIterator extends NAryRelationStreamIterator
00047   {
00048     @Override
00049     protected Tuple internalNext()
00050     { 
00051       if (m_first)
00052       {
00053         m_first = false;
00054         super.initializeIteration();
00055       }
00056       else
00057       {  
00058         int len = m_relations.size();
00059         // Update m_lastTuple by "incrementing" the vector
00060         for (int i = len - 1; i >= 0; i--)
00061         {
00062           RelationIterator r = m_iterators.get(i);
00063           if (r.hasNext())
00064           {
00065             Tuple t = r.next();
00066             assert t != null;
00067             m_lastTuple.setElementAt(t, i);
00068             break;
00069           }
00070           else
00071           {
00072             if (i == 0)
00073               return null; // We exhausted the iteration
00074             r.reset();
00075             assert r.hasNext();
00076             Tuple t = r.next();
00077             assert t != null;
00078             m_lastTuple.setElementAt(t, i);
00079           }
00080         }
00081       }
00082       return Tuple.makeTuple(m_lastTuple);
00083     }
00084   }
00085 
00086   @Override
00087   public RelationStreamIterator streamIterator()
00088   {
00089     return new ProductStreamIterator();
00090   }
00091 
00092 
00093   @Override
00094   public RelationIterator cacheIterator()
00095   {
00096     return new ProductCacheIterator();
00097   }
00098   
00099   protected class ProductCacheIterator extends NAryRelationCacheIterator
00100   {
00101 
00102     @Override
00103     protected void getIntermediateResult()
00104     {
00105       Table tab_out = new Table(getSchema());
00106       super.getIntermediateResult();
00107       super.initializeIteration();
00108       boolean in = true;
00109       while (in)
00110       {
00111         int len = m_relations.size();
00112         // Update m_lastTuple by "incrementing" the vector
00113         for (int i = len - 1; i >= 0; i--)
00114         {
00115           Table tab = m_results.get(i);
00116           Iterator<Tuple> r = m_iterators.get(i);
00117           if (r.hasNext())
00118           {
00119             Tuple t = r.next();
00120             assert t != null;
00121             m_lastTuple.setElementAt(t, i);
00122             break;
00123           }
00124           else
00125           {
00126             if (i == 0)
00127             {
00128               in = false;
00129               break;
00130             }
00131             r = tab.tupleIterator();
00132             m_iterators.setElementAt(r, i);
00133             assert r.hasNext();
00134             Tuple t = r.next();
00135             assert t != null;
00136             m_lastTuple.setElementAt(t, i);
00137           }
00138         }
00139         tab_out.put(Tuple.makeTuple(m_lastTuple));
00140       }
00141       m_intermediateResult = tab_out;
00142     }
00143     
00144   }
00145 }