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.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 }