1 package uba.db.ar;
2
3 public class Cartesiano implements TupleProvider {
4
5 private TupleProvider mySourceLeft, mySourceRight;
6
7 private TuplaDef myTuplaDef;
8
9 private Tupla lastOuterTuple;
10
11 public Cartesiano(TupleProvider sourceLeft, TupleProvider sourceRight) {
12 mySourceLeft = sourceLeft;
13 mySourceRight = sourceRight;
14 myTuplaDef = mySourceLeft.tupleDefinition().concat(
15 sourceRight.tupleDefinition());
16 }
17
18 /***
19 * hasNext
20 *
21 * @return boolean
22 */
23 public boolean hasNext() {
24 return (mySourceLeft.hasNext() || mySourceRight.hasNext());
25 }
26
27 public TuplaDef tupleDefinition() {
28 return myTuplaDef;
29 }
30
31 /***
32 * next
33 *
34 * @return Tupla
35 */
36 public Tupla next() {
37
38 Tupla result, leftTupla, rightTupla;
39 if (lastOuterTuple == null) {
40 lastOuterTuple = mySourceLeft.next();
41 }
42 if (!(mySourceRight.hasNext())) {
43 lastOuterTuple = mySourceLeft.next();
44 mySourceRight.reset();
45 }
46 leftTupla = lastOuterTuple;
47 rightTupla = mySourceRight.next();
48 result = append(leftTupla, rightTupla);
49 return result;
50 }
51
52 private Tupla append(Tupla leftTupla, Tupla rightTupla) {
53 Tupla result = new Tupla(myTuplaDef);
54 copyValues(result, leftTupla, 1);
55 copyValues(result, rightTupla,
56 leftTupla.tuplaDefinition().getSize() + 1);
57 return result;
58 }
59
60 private void copyValues(Tupla destino, Tupla origen, int baseIndex) {
61 int sourceIndex = 1;
62 while (sourceIndex <= origen.tuplaDefinition().getSize()) {
63 destino.set(baseIndex, origen.get(sourceIndex));
64 sourceIndex++;
65 baseIndex++;
66 }
67 }
68
69 public void reset() {
70 mySourceLeft.reset();
71 mySourceRight.reset();
72 }
73
74 public String toString() {
75 return "(" + mySourceLeft.toString() + ", " + mySourceRight.toString()
76 + ")";
77 }
78 }