TurtleDB
A mini distributed database system
src/ca/uqac/dim/turtledb/NAryRelation.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.*;
00021 
00022 import ca.uqac.dim.turtledb.QueryVisitor.VisitorException;
00023 
00034 public abstract class NAryRelation extends Relation
00035 {
00039   protected List<Relation> m_relations;
00040   
00041   protected NAryRelation()
00042   {
00043     super();
00044     m_relations = new LinkedList<Relation>();
00045   }
00046   
00047   @Override
00048   public Schema getSchema()
00049   {
00050     // Sufficient to return schema of first operand
00051     for (Relation r : m_relations)
00052       return r.getSchema();
00053     return null;
00054   }
00055   
00056   public void addOperand(Relation r)
00057   {
00058     m_relations.add(r);
00059   }
00060   
00066   public int getArity()
00067   {
00068     return m_relations.size();
00069   }
00070   
00071   public int tupleCount()
00072   {
00073     int count = 0;
00074     for (Relation r : m_relations)
00075       count += r.tupleCount();
00076     return count;
00077   }
00078   
00079   protected void acceptNAry(QueryVisitor v) throws VisitorException
00080   {
00081     for (Relation r : m_relations)
00082       r.accept(v);
00083   }
00084   
00085 
00086   
00087   protected abstract class NAryRelationStreamIterator extends RelationStreamIterator
00088   {
00092     protected boolean m_first;
00093     
00097     protected Vector<Tuple> m_lastTuple;
00098     
00102     protected Vector<RelationIterator> m_iterators;
00103     
00104     public NAryRelationStreamIterator()
00105     {
00106       super();
00107       m_lastTuple = new Vector<Tuple>();
00108       m_iterators = new Vector<RelationIterator>();
00109       for (Relation r : m_relations)
00110       {
00111         m_iterators.addElement(r.streamIterator());
00112       }
00113       reset();
00114     }
00115     
00116     protected void initializeIteration()
00117     {
00118       int len = m_iterators.size();
00119       // Get first tuple of every table and fill m_lastTuple with them
00120       for (int i = 0; i < len; i++)
00121       {
00122         RelationIterator r = m_iterators.get(i);
00123         if (r.hasNext())
00124         {
00125           Tuple t = r.next();
00126           m_lastTuple.insertElementAt(t, i);
00127         }
00128         else
00129         {
00130           m_lastTuple.insertElementAt(null, i);
00131         }
00132       }
00133     }
00134 
00140     protected Tuple incrementSmallestTuple()
00141     {
00142       int len = m_relations.size();
00143       Tuple smallest_tuple = null;
00144       int smallest_index = -1;
00145       for (int i = len - 1; i >= 0; i--)
00146       {
00147         Tuple t = m_lastTuple.get(i);
00148         if (t == null)
00149           continue;
00150         if (smallest_tuple == null || smallest_tuple.compareTo(t) < 0)
00151         {
00152           smallest_tuple = t;
00153           smallest_index = i;
00154         }
00155       }
00156       if (smallest_index == -1)
00157         return null;
00158       RelationIterator r = m_iterators.get(smallest_index);
00159       if (r.hasNext())
00160       {
00161         Tuple next_t = r.next();
00162         m_lastTuple.setElementAt(next_t, smallest_index);
00163       }
00164       else
00165       {
00166         m_lastTuple.setElementAt(null, smallest_index);
00167       }
00168       return smallest_tuple;    
00169     }
00170     
00171     @Override
00172     public void reset()
00173     {
00174       super.reset();
00175       for (RelationIterator r : m_iterators)
00176         r.reset();
00177       m_first = true;
00178     }
00179   }
00180   
00181   protected class NAryRelationCacheIterator extends RelationCacheIterator
00182   {
00183     
00184     protected Vector<Table> m_results = null;
00185     
00186     protected Vector<Tuple> m_lastTuple = new Vector<Tuple>();
00187     
00188     protected Vector<Iterator<Tuple>> m_iterators;
00189     
00190     public NAryRelationCacheIterator()
00191     {
00192       super();
00193       m_lastTuple = new Vector<Tuple>();
00194       m_iterators = new Vector<Iterator<Tuple>>();
00195       for (Relation r : m_relations)
00196       {
00197         m_iterators.addElement(r.streamIterator());
00198       }
00199       //reset();
00200     }
00201     
00202     @Override
00203     protected void getIntermediateResult()
00204     {
00205       m_results = new Vector<Table>();
00206       for (Relation r : m_relations)
00207       {
00208         Table tab_int = new Table(r.getSchema());
00209         RelationIterator i = r.cacheIterator();
00210         while (i.hasNext())
00211         {
00212           Tuple t = i.next();
00213           tab_int.put(t);
00214         }
00215         m_results.add(tab_int);
00216       }
00217     }
00218     
00219     protected void initializeIteration()
00220     {
00221       int len = m_results.size();
00222       // Get first tuple of every table and fill m_lastTuple with them
00223       for (int i = 0; i < len; i++)
00224       {
00225         Table tab = m_results.elementAt(i);
00226         Iterator<Tuple> r = tab.tupleIterator();
00227         m_iterators.add(r);
00228         if (r.hasNext())
00229         {
00230           Tuple t = r.next();
00231           m_lastTuple.insertElementAt(t, i);
00232         }
00233         else
00234         {
00235           m_lastTuple.insertElementAt(null, i);
00236         }
00237       }
00238     }
00239     
00240   }
00241   
00242 }