1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.directory.server.core.partition.impl.btree.mavibot;
20
21
22 import java.io.IOException;
23
24 import org.apache.directory.api.ldap.model.cursor.AbstractCursor;
25 import org.apache.directory.api.ldap.model.cursor.CursorException;
26 import org.apache.directory.api.ldap.model.cursor.InvalidCursorPositionException;
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.mavibot.btree.TupleCursor;
30 import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
31 import org.apache.directory.server.i18n.I18n;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34
35
36
37
38
39
40
41
42 class MavibotCursor<K, V> extends AbstractCursor<Tuple<K, V>>
43 {
44
45 private static final Logger LOG_CURSOR = LoggerFactory.getLogger( "CURSOR" );
46
47
48 private final MavibotTable<K, V> table;
49
50
51 private Tuple<K, V> returnedTuple = new Tuple<>();
52
53
54 private boolean valueAvailable = false;
55
56
57 private TupleCursor<K, V> browser;
58
59
60
61
62
63
64
65 MavibotCursor( MavibotTable<K, V> table )
66 {
67 LOG_CURSOR.debug( "Creating MavibotCursor {}", this );
68 this.table = table;
69 }
70
71
72
73
74
75 private void clearValue()
76 {
77 returnedTuple.setKey( null );
78 returnedTuple.setValue( null );
79 valueAvailable = false;
80 }
81
82
83
84
85
86 public boolean available()
87 {
88 return valueAvailable;
89 }
90
91
92
93
94
95
96
97
98 public void beforeKey( K key ) throws CursorException
99 {
100 checkNotClosed();
101 closeBrowser( browser );
102
103 try
104 {
105 browser = table.getBTree().browseFrom( key );
106 }
107 catch ( IOException e )
108 {
109 throw new CursorException( e );
110 }
111
112 clearValue();
113 }
114
115
116
117
118
119
120
121
122 public void afterKey( K key ) throws CursorException
123 {
124 checkNotClosed();
125
126 closeBrowser( browser );
127 try
128 {
129 browser = table.getBTree().browseFrom( key );
130
131 if ( table.isDupsEnabled() )
132 {
133 browser.nextKey();
134 }
135 else
136 {
137 if ( browser.hasNextKey() )
138 {
139 browser.nextKey();
140 }
141 else
142 {
143 browser.afterLast();
144 }
145 }
146
147 clearValue();
148 }
149 catch ( IOException e )
150 {
151 clearValue();
152 throw new CursorException( e );
153 }
154 }
155
156
157
158
159
160
161
162
163
164 public void beforeValue( K key, V value ) throws LdapException, CursorException
165 {
166 throw new UnsupportedOperationException( I18n.err( I18n.ERR_596 ) );
167 }
168
169
170
171
172
173
174
175
176
177 public void afterValue( K key, V value ) throws LdapException, CursorException
178 {
179 throw new UnsupportedOperationException( I18n.err( I18n.ERR_596 ) );
180 }
181
182
183
184
185
186 public void before( Tuple<K, V> element ) throws LdapException, CursorException
187 {
188 beforeKey( element.getKey() );
189 }
190
191
192
193
194
195 public void after( Tuple<K, V> element ) throws LdapException, CursorException
196 {
197 afterKey( element.getKey() );
198 }
199
200
201
202
203
204 public void beforeFirst() throws LdapException, CursorException
205 {
206 checkNotClosed();
207
208 try
209 {
210 if ( browser == null )
211 {
212 browser = table.getBTree().browse();
213 }
214
215 browser.beforeFirst();
216 clearValue();
217 }
218 catch ( IOException e )
219 {
220 throw new CursorException( e );
221 }
222 catch ( KeyNotFoundException knfe )
223 {
224 throw new CursorException( knfe );
225 }
226 }
227
228
229
230
231
232 public void afterLast() throws LdapException, CursorException
233 {
234 checkNotClosed();
235
236 try
237 {
238 if ( browser == null )
239 {
240 browser = table.getBTree().browse();
241 }
242
243 browser.afterLast();
244 clearValue();
245 }
246 catch ( IOException e )
247 {
248 throw new CursorException( e );
249 }
250 catch ( KeyNotFoundException knfe )
251 {
252 throw new CursorException( knfe );
253 }
254 }
255
256
257
258
259
260 public boolean first() throws LdapException, CursorException
261 {
262 beforeFirst();
263
264 return next();
265 }
266
267
268
269
270
271 public boolean last() throws LdapException, CursorException
272 {
273 afterLast();
274 return previous();
275 }
276
277
278
279
280
281 public boolean previous() throws LdapException, CursorException
282 {
283 checkNotClosed();
284 if ( browser == null )
285 {
286 afterLast();
287 }
288
289 try
290 {
291 if ( browser.hasPrev() )
292 {
293 org.apache.directory.mavibot.btree.Tuple<K, V> tuple = browser.prev();
294
295 returnedTuple.setKey( tuple.getKey() );
296 returnedTuple.setValue( tuple.getValue() );
297 valueAvailable = true;
298 return true;
299 }
300 else
301 {
302 clearValue();
303 return false;
304 }
305 }
306 catch ( IOException e )
307 {
308 throw new CursorException( e );
309 }
310 }
311
312
313
314
315
316 public boolean next() throws LdapException, CursorException
317 {
318 checkNotClosed();
319
320 if ( browser == null )
321 {
322 beforeFirst();
323 }
324
325 try
326 {
327 if ( browser.hasNext() )
328 {
329 org.apache.directory.mavibot.btree.Tuple<K, V> tuple = browser.next();
330
331 returnedTuple.setKey( tuple.getKey() );
332 returnedTuple.setValue( tuple.getValue() );
333 valueAvailable = true;
334 return true;
335 }
336 else
337 {
338 clearValue();
339 return false;
340 }
341 }
342 catch ( IOException e )
343 {
344 throw new CursorException( e );
345 }
346 }
347
348
349
350
351
352 public Tuple<K, V> get() throws CursorException
353 {
354 checkNotClosed();
355 if ( valueAvailable )
356 {
357 return returnedTuple;
358 }
359
360 throw new InvalidCursorPositionException();
361 }
362
363
364
365
366
367 @Override
368 public void close() throws IOException
369 {
370 LOG_CURSOR.debug( "Closing MavibotCursor {}", this );
371 super.close();
372 closeBrowser( browser );
373 }
374
375
376
377
378
379 @Override
380 public void close( Exception cause ) throws IOException
381 {
382 LOG_CURSOR.debug( "Closing MavibotCursor {}", this );
383 super.close( cause );
384 closeBrowser( browser );
385 }
386
387
388
389
390
391 private void closeBrowser( TupleCursor<K, V> browser )
392 {
393 if ( browser != null )
394 {
395 browser.close();
396 }
397 }
398 }