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.impl.avl;
21
22
23 import java.net.URI;
24
25 import org.apache.directory.api.ldap.model.cursor.Cursor;
26 import org.apache.directory.api.ldap.model.cursor.EmptyCursor;
27 import org.apache.directory.api.ldap.model.cursor.Tuple;
28 import org.apache.directory.api.ldap.model.exception.LdapException;
29 import org.apache.directory.api.ldap.model.schema.AttributeType;
30 import org.apache.directory.api.ldap.model.schema.LdapComparator;
31 import org.apache.directory.api.ldap.model.schema.MatchingRule;
32 import org.apache.directory.api.ldap.model.schema.Normalizer;
33 import org.apache.directory.api.ldap.model.schema.SchemaManager;
34 import org.apache.directory.api.ldap.model.schema.comparators.UuidComparator;
35 import org.apache.directory.server.core.partition.impl.btree.IndexCursorAdaptor;
36 import org.apache.directory.server.i18n.I18n;
37 import org.apache.directory.server.xdbm.AbstractIndex;
38 import org.apache.directory.server.xdbm.EmptyIndexCursor;
39 import org.apache.directory.server.xdbm.IndexEntry;
40
41
42
43
44
45
46
47 public class AvlIndex<K, O> extends AbstractIndex<K, O, String>
48 {
49 protected Normalizer normalizer;
50 protected AvlTable<K, String> forward;
51 protected AvlTable<String, K> reverse;
52
53
54 public AvlIndex()
55 {
56 super( true );
57 }
58
59
60 public AvlIndex( String attributeId )
61 {
62 super( attributeId, true );
63 }
64
65
66 public AvlIndex( String attributeId, boolean withReverse )
67 {
68 super( attributeId, withReverse );
69 }
70
71
72 public void init( SchemaManager schemaManager, AttributeType attributeType ) throws Exception
73 {
74 this.attributeType = attributeType;
75
76 MatchingRule mr = attributeType.getEquality();
77
78 if ( mr == null )
79 {
80 mr = attributeType.getOrdering();
81 }
82
83 if ( mr == null )
84 {
85 mr = attributeType.getSubstring();
86 }
87
88 normalizer = mr.getNormalizer();
89
90 if ( normalizer == null )
91 {
92 throw new Exception( I18n.err( I18n.ERR_212, attributeType ) );
93 }
94
95 LdapComparator<K> comp = ( LdapComparator<K> ) mr.getLdapComparator();
96
97
98
99
100
101
102 forward = new AvlTable<K, String>( attributeType.getName(), comp, UuidComparator.INSTANCE, true );
103
104
105
106
107
108
109
110 if ( withReverse )
111 {
112 if ( attributeType.isSingleValued() )
113 {
114 reverse = new AvlTable<String, K>( attributeType.getName(), UuidComparator.INSTANCE, comp, false );
115 }
116 else
117 {
118 reverse = new AvlTable<String, K>( attributeType.getName(), UuidComparator.INSTANCE, comp, true );
119 }
120 }
121 }
122
123
124 public void add( K attrVal, String id ) throws Exception
125 {
126 forward.put( attrVal, id );
127
128 if ( withReverse )
129 {
130 reverse.put( id, attrVal );
131 }
132 }
133
134
135
136
137
138 public void close() throws Exception
139 {
140 if ( forward != null )
141 {
142 forward.close();
143 }
144
145 if ( reverse != null )
146 {
147 reverse.close();
148 }
149 }
150
151
152
153
154
155 public int count() throws Exception
156 {
157 return forward.count();
158 }
159
160
161
162
163
164 public int count( K attrVal ) throws Exception
165 {
166 return forward.count( attrVal );
167 }
168
169
170
171
172
173 public void drop( String id ) throws Exception
174 {
175 if ( withReverse )
176 {
177 if ( isDupsEnabled() )
178 {
179 Cursor<Tuple<String, K>> cursor = reverse.cursor( id );
180
181 while ( cursor.next() )
182 {
183 Tuple<String, K> tuple = cursor.get();
184 forward.remove( tuple.getValue(), id );
185 }
186
187 cursor.close();
188
189 }
190 else
191 {
192 K key = reverse.get( id );
193 forward.remove( key );
194 }
195
196 reverse.remove( id );
197 }
198 }
199
200
201
202
203
204 public void drop( K attrVal, String id ) throws Exception
205 {
206 forward.remove( attrVal, id );
207
208 if ( withReverse )
209 {
210 reverse.remove( id, attrVal );
211 }
212 }
213
214
215
216
217
218 public boolean forward( K attrVal ) throws Exception
219 {
220 return forward.has( attrVal );
221 }
222
223
224
225
226
227 public boolean forward( K attrVal, String id ) throws LdapException
228 {
229 return forward.has( attrVal, id );
230 }
231
232
233
234
235
236 @SuppressWarnings("unchecked")
237 public Cursor<IndexEntry<K, String>> forwardCursor() throws LdapException
238 {
239 return new IndexCursorAdaptor( forward.cursor(), true );
240 }
241
242
243
244
245
246 @SuppressWarnings("unchecked")
247 public Cursor<IndexEntry<K, String>> forwardCursor( K key ) throws Exception
248 {
249 return new IndexCursorAdaptor( forward.cursor( key ), true );
250 }
251
252
253
254
255
256 public boolean forwardGreaterOrEq( K attrVal ) throws Exception
257 {
258 return forward.hasGreaterOrEqual( attrVal );
259 }
260
261
262
263
264
265 public boolean forwardGreaterOrEq( K attrVal, String id ) throws Exception
266 {
267 return forward.hasGreaterOrEqual( attrVal, id );
268 }
269
270
271
272
273
274 public boolean forwardLessOrEq( K attrVal ) throws Exception
275 {
276 return forward.hasLessOrEqual( attrVal );
277 }
278
279
280
281
282
283 public boolean forwardLessOrEq( K attrVal, String id ) throws Exception
284 {
285 return forward.hasLessOrEqual( attrVal, id );
286 }
287
288
289
290
291
292 public String forwardLookup( K attrVal ) throws Exception
293 {
294 return forward.get( attrVal );
295 }
296
297
298
299
300
301 public Cursor<String> forwardValueCursor( K key ) throws Exception
302 {
303 return forward.valueCursor( key );
304 }
305
306
307
308
309
310 public int greaterThanCount( K attrVal ) throws Exception
311 {
312 return forward.greaterThanCount( attrVal );
313 }
314
315
316
317
318
319 public int lessThanCount( K attrVal ) throws Exception
320 {
321 return forward.lessThanCount( attrVal );
322 }
323
324
325
326
327
328 public boolean reverse( String id ) throws Exception
329 {
330 if ( withReverse )
331 {
332 return reverse.has( id );
333 }
334 else
335 {
336 return false;
337 }
338 }
339
340
341
342
343
344 public boolean reverse( String id, K attrVal ) throws Exception
345 {
346 if ( withReverse )
347 {
348 return reverse.has( id, attrVal );
349 }
350 else
351 {
352 return false;
353 }
354 }
355
356
357
358
359
360 @SuppressWarnings("unchecked")
361 public Cursor<IndexEntry<K, String>> reverseCursor() throws Exception
362 {
363 if ( withReverse )
364 {
365 return new IndexCursorAdaptor( reverse.cursor(), false );
366 }
367 else
368 {
369 return new EmptyIndexCursor<K>();
370 }
371 }
372
373
374
375
376
377 @SuppressWarnings("unchecked")
378 public Cursor<IndexEntry<K, String>> reverseCursor( String id ) throws Exception
379 {
380 if ( withReverse )
381 {
382 return new IndexCursorAdaptor( reverse.cursor( id ), false );
383 }
384 else
385 {
386 return new EmptyIndexCursor<K>();
387 }
388 }
389
390
391
392
393
394 public boolean reverseGreaterOrEq( String id ) throws Exception
395 {
396 if ( withReverse )
397 {
398 return reverse.hasGreaterOrEqual( id );
399 }
400 else
401 {
402 return false;
403 }
404 }
405
406
407
408
409
410 public boolean reverseGreaterOrEq( String id, K attrVal ) throws LdapException
411 {
412 if ( withReverse )
413 {
414 return reverse.hasGreaterOrEqual( id, attrVal );
415 }
416 else
417 {
418 return false;
419 }
420 }
421
422
423
424
425
426 public boolean reverseLessOrEq( String id ) throws Exception
427 {
428 if ( withReverse )
429 {
430 return reverse.hasLessOrEqual( id );
431 }
432 else
433 {
434 return false;
435 }
436 }
437
438
439
440
441
442 public boolean reverseLessOrEq( String id, K attrVal ) throws Exception
443 {
444 if ( withReverse )
445 {
446 return reverse.hasLessOrEqual( id, attrVal );
447 }
448 else
449 {
450 return false;
451 }
452 }
453
454
455
456
457
458 public K reverseLookup( String id ) throws LdapException
459 {
460 if ( withReverse )
461 {
462 return reverse.get( id );
463 }
464 else
465 {
466 return null;
467 }
468 }
469
470
471
472
473
474 public Cursor<K> reverseValueCursor( String id ) throws Exception
475 {
476 if ( withReverse )
477 {
478 return reverse.valueCursor( id );
479 }
480 else
481 {
482 return new EmptyCursor<K>();
483 }
484 }
485
486
487
488
489
490 public void setWkDirPath( URI wkDirPath )
491 {
492 throw new UnsupportedOperationException( I18n.err( I18n.ERR_213 ) );
493 }
494
495
496
497
498
499 public URI getWkDirPath()
500 {
501 return null;
502 }
503
504
505
506
507
508 public boolean isDupsEnabled()
509 {
510 if ( withReverse )
511 {
512 return reverse.isDupsEnabled();
513 }
514 else
515 {
516 return false;
517 }
518 }
519
520
521
522
523
524 public void sync() throws Exception
525 {
526 }
527 }