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.jdbm;
20
21
22 import org.apache.directory.server.core.cursor.InvalidCursorPositionException;
23 import org.apache.directory.server.xdbm.Tuple;
24 import org.apache.directory.server.xdbm.AbstractTupleCursor;
25
26 import java.io.IOException;
27
28 import jdbm.helper.TupleBrowser;
29
30
31
32
33
34
35
36
37
38
39
40 class NoDupsCursor<K,V> extends AbstractTupleCursor<K,V>
41 {
42 private final JdbmTable<K,V> table;
43
44 private jdbm.helper.Tuple jdbmTuple = new jdbm.helper.Tuple();
45 private Tuple<K,V> returnedTuple = new Tuple<K,V>();
46 private TupleBrowser browser;
47 private boolean valueAvailable;
48
49
50
51
52
53
54
55
56 public NoDupsCursor( JdbmTable<K,V> table ) throws IOException
57 {
58 this.table = table;
59 }
60
61
62 private void clearValue()
63 {
64 returnedTuple.setKey( null );
65 returnedTuple.setValue( null );
66 jdbmTuple.setKey( null );
67 jdbmTuple.setValue( null );
68 valueAvailable = false;
69 }
70
71
72 public boolean available()
73 {
74 return valueAvailable;
75 }
76
77
78 public void beforeKey( K key ) throws Exception
79 {
80 checkNotClosed( "beforeKey()" );
81 browser = table.getBTree().browse( key );
82 clearValue();
83 }
84
85
86 @SuppressWarnings("unchecked")
87 public void afterKey( K key ) throws Exception
88 {
89 browser = table.getBTree().browse( key );
90
91
92
93
94
95
96
97
98 while ( browser.getNext( jdbmTuple ) )
99 {
100 checkNotClosed( "afterKey()" );
101 K next = ( K ) jdbmTuple.getKey();
102
103 int nextCompared = table.getKeyComparator().compare( next, key );
104
105 if ( nextCompared > 0 )
106 {
107 browser.getPrevious( jdbmTuple );
108 clearValue();
109 return;
110 }
111 }
112
113 clearValue();
114 }
115
116
117 public void beforeValue( K key, V value ) throws Exception
118 {
119 throw new UnsupportedOperationException( "This Cursor does not support duplicate keys." );
120 }
121
122
123 public void afterValue( K key, V value ) throws Exception
124 {
125 throw new UnsupportedOperationException( "This Cursor does not support duplicate keys." );
126 }
127
128
129
130
131
132
133
134
135 public void before( Tuple<K,V> element ) throws Exception
136 {
137 beforeKey( element.getKey() );
138 }
139
140
141 public void after( Tuple<K,V> element ) throws Exception
142 {
143 afterKey( element.getKey() );
144 }
145
146
147 public void beforeFirst() throws Exception
148 {
149 checkNotClosed( "beforeFirst()" );
150 browser = table.getBTree().browse();
151 clearValue();
152 }
153
154
155 public void afterLast() throws Exception
156 {
157 checkNotClosed( "afterLast()" );
158 browser = table.getBTree().browse( null );
159 clearValue();
160 }
161
162
163 public boolean first() throws Exception
164 {
165 beforeFirst();
166 return next();
167 }
168
169
170 public boolean last() throws Exception
171 {
172 afterLast();
173 return previous();
174 }
175
176
177 @SuppressWarnings("unchecked")
178 public boolean previous() throws Exception
179 {
180 checkNotClosed( "previous()" );
181 if ( browser == null )
182 {
183 afterLast();
184 }
185
186 if ( browser.getPrevious( jdbmTuple ) )
187 {
188 if( returnedTuple.getKey() != null )
189 {
190 if( table.getKeyComparator().compare(
191 ( K) jdbmTuple.getKey(), ( K) returnedTuple.getKey() ) == 0 )
192 {
193 browser.getPrevious( jdbmTuple );
194 }
195 }
196
197 returnedTuple.setKey( ( K ) jdbmTuple.getKey() );
198 returnedTuple.setValue( ( V ) jdbmTuple.getValue() );
199 return valueAvailable = true;
200 }
201 else
202 {
203 clearValue();
204 return false;
205 }
206 }
207
208
209 @SuppressWarnings("unchecked")
210 public boolean next() throws Exception
211 {
212 checkNotClosed( "previous()" );
213 if ( browser == null )
214 {
215 beforeFirst();
216 }
217
218 if ( browser.getNext( jdbmTuple ) )
219 {
220 if( returnedTuple.getKey() != null )
221 {
222 if( table.getKeyComparator().compare(
223 ( K) jdbmTuple.getKey(), ( K) returnedTuple.getKey() ) == 0 )
224 {
225 browser.getNext( jdbmTuple );
226 }
227 }
228
229 returnedTuple.setKey( ( K ) jdbmTuple.getKey() );
230 returnedTuple.setValue( ( V ) jdbmTuple.getValue() );
231 return valueAvailable = true;
232 }
233 else
234 {
235 clearValue();
236 return false;
237 }
238 }
239
240
241 public Tuple<K,V> get() throws Exception
242 {
243 checkNotClosed( "get()" );
244 if ( valueAvailable )
245 {
246 return returnedTuple;
247 }
248
249 throw new InvalidCursorPositionException();
250 }
251
252
253 public boolean isElementReused()
254 {
255 return true;
256 }
257 }