TurtleDB
A mini distributed database system
|
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 }