KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > medor > optim > lib > IndexesGenerator


1 /**
2  * MEDOR: Middleware Enabling Distributed Object Requests
3  *
4  * Copyright (C) 2001-2003 France Telecom R&D
5  * Contact: alexandre.lefebvre@rd.francetelecom.com
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  *
21  * Initial developers: M. Alia, A. Lefebvre
22  */

23
24 package org.objectweb.medor.optim.lib;
25
26 import org.objectweb.medor.api.Field;
27 import org.objectweb.medor.api.MedorException;
28 import org.objectweb.medor.api.QueryNodeException;
29 import org.objectweb.medor.api.TupleStructure;
30 import org.objectweb.medor.expression.api.ExpressionException;
31 import org.objectweb.medor.expression.api.Operator;
32 import org.objectweb.medor.expression.api.Expression;
33 import org.objectweb.medor.filter.api.FieldOperand;
34 import org.objectweb.medor.optim.api.ExecPlanGenerator;
35 import org.objectweb.medor.query.api.CalculatedField;
36 import org.objectweb.medor.query.api.PropagatedField;
37 import org.objectweb.medor.query.api.QueryNode;
38 import org.objectweb.medor.query.api.QueryTree;
39 import org.objectweb.medor.query.api.TCQueryLeaf;
40 import org.objectweb.medor.query.rdb.lib.AggregateRdbQueryNode;
41 import org.objectweb.medor.tuple.lib.GeneralTupleLoader;
42
43 public class IndexesGenerator implements ExecPlanGenerator {
44
45     public QueryTree transform(QueryTree query) throws MedorException {
46         // generate indexes and TupleLoaders
47
try {
48             generateIndexes(query);
49         }
50         catch (MedorException e) {
51             throw e;
52         }
53         catch (ExpressionException e) {
54             throw new MedorException(e);
55         }
56         return query; // We don't clone it...
57
}
58
59     private void generateIndexes(QueryTree query) throws MedorException, ExpressionException {
60         if (query instanceof QueryNode) {
61             QueryNode qn = (QueryNode) query;
62             if (!(query instanceof AggregateRdbQueryNode)) {
63                 setFilterIndexes(qn.getQueryFilter(), qn.getChildren());
64             }
65             // setting a TupleLoader
66
qn.setTupleLoader(
67                 new GeneralTupleLoader(
68                     computesFieldIndexes(qn.getTupleStructure(), qn.getChildren()),
69                     query.getTupleStructure()));
70             QueryTree[] children = qn.getChildren();
71             for (int cpt = 0; (cpt < children.length); cpt++) {
72                 generateIndexes(children[cpt]);
73             }
74             // This case appears when MedorTC queryLeaf
75
}
76         else if (query instanceof TCQueryLeaf) {
77             // At first indexes of the Fields of the TupleStructure
78
TCQueryLeaf tcLeaf = (TCQueryLeaf) query;
79             TupleStructure ts = tcLeaf.getTupleStructure();
80             boolean stop = false;
81             int cpt = 0;
82             int[] indexes = new int[ts.getSize()];
83             while (cpt < ts.getSize() && !stop) {
84                 indexes[cpt] =
85                     tcLeaf.getTupleCollection().getMetaData().getFieldRank(
86                         tcLeaf.getTupleCollection().getMetaData().getField(
87                             ts.getField(cpt + 1).getName()
88                         )
89                     );
90                 cpt++;
91             }
92             tcLeaf.setTupleLoader(
93                 new GeneralTupleLoader(indexes, query.getTupleStructure()));
94
95             // Then the expression filter fieldOperand indexes
96
setTCQLFilterIndexes(tcLeaf.getQueryFilter(), tcLeaf);
97         }
98     }
99
100     public int[] computesFieldIndexes(TupleStructure ts, QueryTree[] nodes)
101         throws MedorException, ExpressionException {
102         Field[] ancestor = null;
103         Field current = null;
104
105         //indexs will contain ranges of attributes to be projected in the
106
// concatenated tuple
107
int[] indexes = new int[ts.getSize()];
108         for (int i = 1; i <= ts.getSize(); i++) {
109             try {
110                 current = ts.getField(i);
111             }
112             catch (MedorException me) {
113                 // Impossible case
114
}
115             if (current instanceof PropagatedField) {
116                 ancestor = ((PropagatedField) current).getPreviousFields();
117                 for (int j = 0; j < ancestor.length; j++) {
118                     int rank = 0;
119                     int cpt = 0;
120                     // We will take the first QueryTree
121
for (cpt = 0;
122                          ((cpt < nodes.length) &&
123                         !containsField(nodes[cpt], ancestor[j]));
124                          cpt++) {
125                         rank = rank + nodes[cpt].getTupleStructure().getSize();
126                     }
127                     // The last node witch matches the field i
128
if (cpt < nodes.length) {
129                         indexes[i - 1] = rank + nodes[cpt].getTupleStructure().getFieldRank(nodes[cpt].getTupleStructure().getField(ancestor[j].getName()));
130                     }
131                     else {
132                         throw new QueryNodeException(
133                             "The previous field " + ancestor[j].getName()
134                             + " must have a QueryTree which matches with one of children");
135                     }
136                 }
137             }
138             else if (current instanceof CalculatedField) {
139                 // Setting the field operand indexes
140
setFilterIndexes(((CalculatedField) current).getExpression(), nodes);
141                 indexes[i - 1] = -1; // means a calculated field
142
}
143             /*
144             else if (current instanceof NestedField) {
145                 // Do nothing
146                 //TODO handle the nested field !!
147                 indexes[i - 1] = -1;
148             }
149             */

150             else
151                 throw new QueryNodeException(
152                     "QueryNode fields error for field " + current.getName());
153         }
154 // for (int cpt = 0; (cpt < indexes.length); cpt++) {
155
// System.out.println("les indexes " + indexes[cpt]);
156
// }
157
return indexes;
158     }
159
160     /**
161      * This method inherited from QueryIndexGenerator.
162      * It checks that all Fields in the Expression are present in the array
163      * of QueryTree and sets yhe indexs of the fieldOperand.
164      * @param e Expression filter
165      * @param qts array of QueryTree
166      */

167     public void setFilterIndexes(Expression e, QueryTree[] qts)
168         throws MedorException, ExpressionException {
169         if (e == null)
170             return;
171         e.compileExpression();// Compiling the QueryFilter Expression
172
if (e instanceof Operator) {
173             for (int i = 0; i<((Operator) e).getOperandNumber(); i++) {
174                 setFilterIndexes((Expression) ((Operator) e).getExpression(i), qts);
175             }
176         }
177         else if (e instanceof FieldOperand) {
178             int i;
179             /**
180              * Stops if the QueryTree of the Field is found in the array.
181              * In this case, it stops with i equals to the rank of the
182              * QueryTree in the array.
183              */

184             int rank = 0;
185             for (i = 0;
186                  i < qts.length &&
187                 !containsField(qts[i], ((FieldOperand) e).getField());
188                  rank = rank + qts[i].getTupleStructure().getSize(), i++)
189                 ;
190
191             /**
192              * All qts have been looked at.
193              * If the QueryTree has been found, i != length.
194              * Otherwise, the QueryTree of the Field has not been found and
195              * i equals length.
196              */

197
198             if (i != qts.length) {
199                 ((FieldOperand) e).setIndex(
200                     rank + qts[i].getTupleStructure().getFieldRank(qts[i].getTupleStructure().getField(((FieldOperand) e).getField().getName())));
201             }
202             else {
203                 throw new ExpressionException(
204                     "Field not found in the subQueryTree: "
205                     + ((FieldOperand) e).getField().getName());
206             }
207         }
208     }
209
210     private void setTCQLFilterIndexes(Expression e, TCQueryLeaf tcLeaf)
211             throws MedorException,ExpressionException {
212         if (e == null)
213             return;
214
215         e.compileExpression();// Compiling QueryFilter Expression
216
if (e instanceof Operator) {
217             for (int i = 0; i<((Operator) e).getOperandNumber(); i++) {
218                 setTCQLFilterIndexes((Expression) ((Operator) e).getExpression(i), tcLeaf);
219             }
220         }
221         else if (e instanceof FieldOperand) {
222             ((FieldOperand) e).setIndex(
223                 tcLeaf.getTupleStructure().getFieldRank(
224                     tcLeaf.getTupleStructure().getField(
225                         ((FieldOperand) e).getField().getName()
226                     )
227                 )
228             );
229         }
230     }
231
232     private boolean containsField(QueryTree qt, Field field) {
233         return qt.getTupleStructure().contains(field.getName());
234     }
235 }
236
Popular Tags