1 24 package org.objectweb.jalisto.se.query.execution; 25 26 import org.objectweb.jalisto.se.impl.LogicalOid; 27 import org.objectweb.jalisto.se.api.Session; 28 import org.objectweb.jalisto.se.api.MetaRepository; 29 import org.objectweb.jalisto.se.api.query.IndexManager; 30 import org.objectweb.jalisto.se.api.query.Constraint; 31 import org.objectweb.jalisto.se.api.internal.SessionInternal; 32 import org.objectweb.jalisto.se.api.internal.InternalMetaRepository; 33 import org.objectweb.jalisto.se.query.constraint.*; 34 import org.objectweb.jalisto.se.query.result.QueryResultWrapper; 35 import org.objectweb.jalisto.se.query.result.WrapperSet; 36 37 import java.util.*; 38 39 public class ExecutionTree { 40 41 public ExecutionTree(Constraint rootConstraint, MetaRepository repository, String className) { 42 toResolveAndNodes = new ArrayList(); 43 44 readedValues = new HashMap(); 45 leafs = new HashSet(); 46 47 this.baseClassName = className; 48 49 root = buildElement(null, rootConstraint, 0); 50 toResolveAndNodesBackup = new ArrayList(toResolveAndNodes); 51 root.defineMeta(repository); 52 } 53 54 public ExecutionElement buildElement(ExecutionElement father, Constraint constraint, int depth) { 55 ExecutionElement element = null; 56 if (constraint instanceof BinaryBooleanOperatorConstraint) { 57 BinaryBooleanOperatorConstraint binConstraint = (BinaryBooleanOperatorConstraint) constraint; 58 ExecutionNode node = new ExecutionNode(this, father, binConstraint, depth); 59 node.setLeft(buildElement(node, binConstraint.getLeft(), depth + 1)); 60 node.setRight(buildElement(node, binConstraint.getRight(), depth + 1)); 61 if (binConstraint.isAndOperator()) { 62 toResolveAndNodes.add(node); 63 } 64 element = node; 65 } else if (constraint instanceof ValueConstraintImpl) { 66 element = new ValueExecutionLeaf(this, father, (ValueConstraintImpl) constraint, depth); 67 leafs.add(element); 68 } else if (constraint instanceof SubQueryConstraintImpl) { 69 element = new SubQueryExecutionLeaf(this, father, (SubQueryConstraintImpl) constraint, depth); 70 leafs.add(element); 71 } 72 return element; 73 } 74 75 public Collection getToResolveAndNodes() { 76 return toResolveAndNodes; 77 } 78 79 public Set getLeafs() { 80 return leafs; 81 } 82 83 public Map getReadedValues() { 84 return readedValues; 85 } 86 87 public void cleanLeaf() { 88 root.cleanAll(); 89 readedValues.clear(); 90 toResolveAndNodes.clear(); 91 toResolveAndNodes.addAll(toResolveAndNodesBackup); 92 } 93 94 97 98 public Set resolve(SessionInternal session, IndexManager indexManager) { 99 if (manageIndexes(session, indexManager)) { 100 resolveWithIndex(session); 101 } 102 if (root.isResolved()) { 103 return root.getResolvedValues().getCopyInSet(); 104 } 105 return resolveOnElements(session); 106 } 107 108 public Set resolveOnElements(SessionInternal session) { 109 Iterator extent = session.getExtent(baseClassName).readFully().iterator(); 110 Set result = new HashSet(); 111 while (extent.hasNext()) { 112 LogicalOid floid = (LogicalOid) extent.next(); 113 Object [] values = (Object []) readedValues.get(floid); 114 if (values == null) { 115 values = session.readObjectByOid(floid, true); 116 readedValues.put(floid, values); 117 } 118 QueryResultWrapper wrapper = new QueryResultWrapper(floid, values); 119 if (root.resolveOnElement(session, wrapper)) { 120 result.add(wrapper); 121 } 122 } 123 return result; 124 } 125 126 public boolean resolveOnOneElement(SessionInternal session, QueryResultWrapper wrapper) { 127 return root.resolveOnElement(session, wrapper); 128 } 129 130 private boolean manageIndexes(Session session, IndexManager indexManager) { 131 boolean useIndexes = false; 132 Set toResolveBack = new HashSet(); 133 Iterator leafIterator = leafs.iterator(); 134 while (leafIterator.hasNext()) { 135 ExecutionElement leaf = (ExecutionElement) leafIterator.next(); 136 leaf.resolveLeafOnIndex(session, indexManager); 137 if (leaf.isResolved()) { 138 ExecutionElement resBack = leaf.resolveBack(); 139 if (resBack != null) { 140 toResolveBack.add(resBack); 141 } 142 } 143 } 144 145 Set toResolveBackNext = new HashSet(); 146 while (!toResolveBack.isEmpty()) { 147 useIndexes = true; 148 Iterator it = toResolveBack.iterator(); 149 while (it.hasNext()) { 150 ExecutionElement element = (ExecutionElement) it.next(); 151 ExecutionNode node = element.resolveBack(); 152 if (node != null) { 153 toResolveBackNext.add(node); 154 } 155 } 156 toResolveBack.clear(); 157 toResolveBack.addAll(toResolveBackNext); 158 toResolveBackNext.clear(); 159 } 160 161 return useIndexes; 162 } 163 164 private void resolveWithIndex(SessionInternal session) { 165 if (root.isResolved()) { 166 return; 167 } 168 169 LinkedList toResolve = new LinkedList(); 170 Iterator ands = toResolveAndNodes.iterator(); 171 while (ands.hasNext()) { 172 ExecutionElement e = (ExecutionElement) ands.next(); 173 if (e.onlyOneToResolve()) { 174 toResolve.add(e); 175 } 176 } 177 Collections.sort(toResolve); 178 179 while (!toResolve.isEmpty()) { 180 ExecutionNode andNode = (ExecutionNode) toResolve.removeFirst(); 181 182 boolean before = false; 183 while ((andNode.getFather() != null) && 184 (andNode.getFather().isAndNode()) && 185 (andNode.getFather().onlyOneToResolve())) { 186 andNode = andNode.getFather(); 187 before = true; 188 } 189 190 if (before) { 191 andNode.resolveBeforeAndNodeNearRoot(session, null, toResolve); 192 } else { 193 andNode.resolveWithCandidates(session, new WrapperSet()); 194 } 195 196 ExecutionElement son = andNode; 197 ExecutionElement father = andNode.resolveBack(); 198 while (father != null) { 199 son = father; 200 father = father.resolveBack(); 201 } 202 203 if ((son == root) && root.isResolved) { 204 return; 205 } 206 207 if (son.isAndNode() && son.onlyOneToResolve()) { 208 toResolve.add(son); 209 Collections.sort(toResolve); 210 } 211 } 212 } 213 214 public boolean detectOrBranch(IndexManager indexManager) { 215 return root.isInOrBranch(indexManager); 216 } 217 218 219 private ArrayList toResolveAndNodes; 220 private ArrayList toResolveAndNodesBackup; 221 private Set leafs; 222 private ExecutionElement root; 223 private String baseClassName; 224 private Map readedValues; 225 } 226 | Popular Tags |