1 23 24 package org.objectweb.medor.optim.lib; 25 26 import java.util.ArrayList ; 27 import java.util.HashMap ; 28 import java.util.Iterator ; 29 import java.util.Map ; 30 31 import org.objectweb.medor.api.Field; 32 import org.objectweb.medor.api.MedorException; 33 import org.objectweb.medor.expression.api.Expression; 34 import org.objectweb.medor.expression.api.Operator; 35 import org.objectweb.medor.filter.api.FieldOperand; 36 import org.objectweb.medor.query.api.CalculatedField; 37 import org.objectweb.medor.query.api.FilteredQueryTree; 38 import org.objectweb.medor.query.api.NestQueryNode; 39 import org.objectweb.medor.query.api.NestedField; 40 import org.objectweb.medor.query.api.PropagatedField; 41 import org.objectweb.medor.query.api.QueryLeaf; 42 import org.objectweb.medor.query.api.QueryNode; 43 import org.objectweb.medor.query.api.QueryTree; 44 import org.objectweb.medor.query.api.QueryTreeField; 45 import org.objectweb.medor.query.lib.QueryTreePrinter; 46 import org.objectweb.medor.query.rdb.api.RdbExpField; 47 import org.objectweb.medor.query.rdb.api.RdbExpQueryLeaf; 48 import org.objectweb.util.monolog.api.BasicLevel; 49 50 58 public class DropUnusedProjFieldsRule extends BasicRule { 59 60 public DropUnusedProjFieldsRule() { 61 super("DropUnusedProjFieldsRule"); 62 } 63 64 68 public QueryTree rewrite(QueryTree qt, QueryNode _parent) 69 throws MedorException { 70 debug = log != null && log.isLoggable(BasicLevel.DEBUG); 71 if (qt instanceof QueryNode) { 72 Field[] myFields = qt.getTupleStructure().getFields(); 73 dropUnusedProjFields(qt, array2arrayList(myFields)); 74 } 75 return qt; 76 } 77 78 private void dropUnusedProjFields(QueryTree qt, 79 ArrayList wanted) 80 throws MedorException { 81 if (debug) log.log(BasicLevel.DEBUG, "-Current node is " + qt); 82 if (debug) log.log(BasicLevel.DEBUG, "Query tree before dropping fields:"); 83 if (debug) QueryTreePrinter.printQueryTree(qt, log); 84 85 Map qt2ReqFields = new HashMap (); 86 87 if (debug) log.log(BasicLevel.DEBUG, " Drop unused fields from projected fields in according to usage"); 88 Field[] myFields = qt.getTupleStructure().getFields(); 90 for (int i = 0; i < myFields.length; i++) { 91 if (debug) log.log(BasicLevel.DEBUG, "\tfield=" + myFields[i].getName()); 92 if (!wanted.contains(myFields[i])) { 93 if (debug) log.log(BasicLevel.DEBUG, "\tDropping field " + myFields[i].getName() + " (" + myFields[i] + ") " + " qt=" + qt); 94 if (qt instanceof QueryNode) { 95 ((QueryNode) qt).removeField(myFields[i].getName()); 96 } 97 else if (qt instanceof RdbExpQueryLeaf) 98 ((RdbExpQueryLeaf) qt).removeRdbField( 99 (RdbExpField) myFields[i]); 100 } 101 } 102 103 if (debug) log.log(BasicLevel.DEBUG, "Query tree after dropping fields:"); 104 if (debug) QueryTreePrinter.printQueryTree(qt, log); 105 106 if (qt instanceof QueryLeaf) 107 return; 108 109 if (debug) log.log(BasicLevel.DEBUG, " calculate the Map (qt child => { field }"); 111 myFields = qt.getTupleStructure().getFields(); 112 for (int i = 0; i < myFields.length; i++) { 113 if (debug) log.log(BasicLevel.DEBUG, "\tfield " + myFields[i].getName() + " is " + myFields[i]); 114 if (myFields[i] instanceof CalculatedField) 115 addFieldFromExpression(qt2ReqFields, 116 ((CalculatedField) myFields[i]).getExpression()); 117 else 118 addFieldInMap(qt2ReqFields, (QueryTreeField) myFields[i]); 119 } 121 122 if (qt instanceof NestQueryNode) { 123 myFields = ((NestQueryNode) qt).getNestingFields(); 124 for (int i = 0; i < myFields.length; i++) { 125 addAncestorsToMap(qt2ReqFields, new Field[] {(QueryTreeField) myFields[i]}); 126 } 127 } 128 129 if (debug) log.log(BasicLevel.DEBUG, "Add field from the query filter"); 130 addFieldFromExpression(qt2ReqFields, 131 ((FilteredQueryTree) qt).getQueryFilter()); 132 133 if (debug) log.log(BasicLevel.DEBUG, "Recall on children"); 134 for (Iterator it = qt2ReqFields.entrySet().iterator(); it.hasNext();) { 136 Map.Entry e = (Map.Entry ) it.next(); 137 dropUnusedProjFields((QueryTree) e.getKey(), 138 (ArrayList ) e.getValue()); 139 } 140 } 141 142 145 private void addFieldFromExpression(Map qt2ReqFields, Expression exp) { 146 if (exp instanceof FieldOperand) { 147 QueryTreeField f = (QueryTreeField) ((FieldOperand) exp).getField(); 148 QueryTree qt = f.getQueryTree(); 149 ArrayList fields = (ArrayList ) qt2ReqFields.get(qt); 150 if (fields == null) { 151 if (debug) log.log(BasicLevel.DEBUG, "addFieldFromExpression: FieldOperand, new Qt in map"); 152 fields = new ArrayList (1); 153 fields.add(f); 154 qt2ReqFields.put(qt, fields); 155 } 156 else if (!(fields.contains(f))) { 157 if (debug) log.log(BasicLevel.DEBUG, "addFieldFromExpression: FieldOperand, Qt exists in map"); 158 fields.add(f); 159 } else { 160 if (debug) log.log(BasicLevel.DEBUG, "addFieldFromExpression: FieldOperand already referenced"); 161 } 162 } else if (exp instanceof Operator) { 163 if (debug) log.log(BasicLevel.DEBUG, "addFieldFromExpression: Operator"); 164 for(int i=0; i<((Operator) exp).getOperandNumber(); i++) { 165 addFieldFromExpression(qt2ReqFields, 166 ((Operator) exp).getExpression(i)); 167 } 168 } 169 } 170 171 private void addFieldInMap(Map qt2ReqFields, QueryTreeField field) { 172 if (debug) log.log(BasicLevel.DEBUG, "addFieldInMap: field " + field); 173 Field[] anc = null; 174 if (field instanceof PropagatedField) { 175 anc = ((PropagatedField) field).getPreviousFields(); 176 if (debug) log.log(BasicLevel.DEBUG, "addFieldInMap: PropagatedField " + field.getName()); 177 } 178 else if (field instanceof NestedField) { 179 anc = ((NestedField) field).getFields(); 180 if (debug) log.log(BasicLevel.DEBUG, "addFieldInMap: NestedField " + field.getName()); 181 } 182 else 183 anc = new Field[0]; 184 addAncestorsToMap(qt2ReqFields, anc); 185 } 186 187 private void addAncestorsToMap(Map qt2ReqFields, Field[] anc) { 188 if (debug) log.log(BasicLevel.DEBUG, "addFieldInMap: registered previous, nb=" + anc.length); 189 for (int i = 0; i < anc.length; i++) { 190 QueryTree qt = ((QueryTreeField) anc[i]).getQueryTree(); 191 ArrayList fields = (ArrayList ) qt2ReqFields.get(qt); 192 if (fields == null) { 193 if (debug) log.log(BasicLevel.DEBUG, "addFieldInMap: Field, new Qt exists map"); 194 fields = new ArrayList (1); 195 fields.add(anc[i]); 196 qt2ReqFields.put(qt, fields); 197 } 198 else if (!(fields.contains(anc[i]))) { 199 if (debug) log.log(BasicLevel.DEBUG, "addFieldInMap: Field, Qt exists in map"); 200 fields.add(anc[i]); 201 } 202 else { 203 if (debug) log.log(BasicLevel.DEBUG, "addFieldInMap: Field already referenced"); 204 } 205 } 206 } 207 208 private ArrayList array2arrayList(Object [] array) { 209 ArrayList alist = new ArrayList (array.length); 210 for (int i = 0; i < array.length; i++) { 211 alist.add(array[i]); 212 } 213 return alist; 214 } 215 } 216 | Popular Tags |