KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jalisto > se > query > execution > ExecutionTree


1 /*
2  * Jalisto - JAva LIght STOrage
3  * Copyright (C) 2000-2005 Xcalia http://www.xcalia.com
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
18  *
19  * Xcalia
20  * 71, rue Desnouettes
21  * 75014 Paris - France
22  * http://www.xcalia.com
23  */

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 JavaDoc 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     /**
95      * ******************************* RESOLVE ***************************************
96      */

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 JavaDoc[] values = (Object JavaDoc[]) 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 JavaDoc baseClassName;
224     private Map readedValues;
225 }
226
Popular Tags