1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.server.xdbm.search.impl;
21
22
23 import java.util.List;
24 import java.util.ArrayList;
25
26 import org.apache.directory.server.xdbm.Store;
27 import org.apache.directory.server.xdbm.IndexCursor;
28 import org.apache.directory.server.xdbm.search.Evaluator;
29 import org.apache.directory.server.core.entry.ServerEntry;
30 import org.apache.directory.shared.ldap.NotImplementedException;
31 import org.apache.directory.shared.ldap.filter.*;
32
33
34
35
36
37
38
39
40 public class CursorBuilder
41 {
42
43 private Store<ServerEntry> db = null;
44
45
46 private EvaluatorBuilder evaluatorBuilder;
47
48
49
50
51
52
53
54
55 public CursorBuilder( Store<ServerEntry> db, EvaluatorBuilder evaluatorBuilder )
56 {
57 this.db = db;
58 this.evaluatorBuilder = evaluatorBuilder;
59 }
60
61
62 public IndexCursor<?,ServerEntry> build( ExprNode node ) throws Exception
63 {
64 switch ( node.getAssertionType() )
65 {
66
67
68 case APPROXIMATE:
69 return new ApproximateCursor( db, ( ApproximateEvaluator ) evaluatorBuilder.build( node ) );
70 case EQUALITY:
71 return new EqualityCursor( db, ( EqualityEvaluator ) evaluatorBuilder.build( node ) );
72 case GREATEREQ:
73 return new GreaterEqCursor( db, ( GreaterEqEvaluator ) evaluatorBuilder.build( node ) );
74 case LESSEQ:
75 return new LessEqCursor( db, ( LessEqEvaluator ) evaluatorBuilder.build( node ) );
76 case PRESENCE:
77 return new PresenceCursor( db, ( PresenceEvaluator ) evaluatorBuilder.build( node ) );
78 case SCOPE:
79 if ( ( ( ScopeNode ) node ).getScope() == SearchScope.ONELEVEL )
80 {
81 return new OneLevelScopeCursor( db, ( OneLevelScopeEvaluator ) evaluatorBuilder.build( node ) );
82 }
83 else
84 {
85 return new SubtreeScopeCursor( db, ( SubtreeScopeEvaluator ) evaluatorBuilder.build( node ) );
86 }
87 case SUBSTRING:
88 return new SubstringCursor( db, ( SubstringEvaluator ) evaluatorBuilder.build( node ) );
89
90
91
92 case AND:
93 return buildAndCursor( ( AndNode ) node );
94 case NOT:
95 return new NotCursor( db, evaluatorBuilder.build( ( ( NotNode ) node).getFirstChild() ) );
96 case OR:
97 return buildOrCursor( ( OrNode ) node );
98
99
100
101 case ASSERTION:
102 case EXTENSIBLE:
103 throw new NotImplementedException();
104
105 default:
106 throw new IllegalStateException( "Unknown assertion type: " + node.getAssertionType() );
107 }
108 }
109
110
111
112
113
114
115
116
117
118 private IndexCursor<?,ServerEntry> buildOrCursor( OrNode node ) throws Exception
119 {
120 List<ExprNode> children = node.getChildren();
121 List<IndexCursor<?,ServerEntry>> childCursors = new ArrayList<IndexCursor<?,ServerEntry>>( children.size() );
122 List<Evaluator<? extends ExprNode, ServerEntry>> childEvaluators
123 = new ArrayList<Evaluator<? extends ExprNode, ServerEntry>>( children.size() );
124
125
126 for ( ExprNode child : children )
127 {
128 childCursors.add( build( child ) );
129 childEvaluators.add( evaluatorBuilder.build( child ) );
130 }
131
132
133 return new OrCursor( childCursors, childEvaluators );
134 }
135
136
137
138
139
140
141
142
143
144 private IndexCursor<?,ServerEntry> buildAndCursor( AndNode node ) throws Exception
145 {
146 int minIndex = 0;
147 long minValue = Long.MAX_VALUE;
148
149 long value = Long.MAX_VALUE;
150
151
152
153
154
155
156 final List<ExprNode> children = node.getChildren();
157
158 for ( int ii = 0; ii < children.size(); ii++ )
159 {
160 ExprNode child = children.get( ii );
161 Object count = child.get( "count" );
162 if( count == null )
163 {
164 continue;
165 }
166 value = ( Long ) count;
167 minValue = Math.min( minValue, value );
168
169 if ( minValue == value )
170 {
171 minIndex = ii;
172 }
173 }
174
175
176 ExprNode minChild = children.get( minIndex );
177 List<Evaluator<? extends ExprNode, ServerEntry>> childEvaluators =
178 new ArrayList<Evaluator<? extends ExprNode, ServerEntry>>( children.size() - 1 );
179 for ( ExprNode child : children )
180 {
181 if ( child == minChild )
182 {
183 continue;
184 }
185
186 childEvaluators.add( evaluatorBuilder.build( child ) );
187 }
188
189
190 IndexCursor<?,ServerEntry> childCursor = build( minChild );
191 return new AndCursor( childCursor, childEvaluators );
192 }
193 }