View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *  http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.directory.server.core.partition.impl.btree.jdbm;
20  
21  
22  import jdbm.btree.BTree;
23  import jdbm.helper.Tuple;
24  import jdbm.helper.TupleBrowser;
25  
26  import org.apache.directory.server.core.cursor.AbstractCursor;
27  import org.apache.directory.server.core.cursor.InvalidCursorPositionException;
28  
29  import java.util.Comparator;
30  
31  
32  /**
33   * Cursor over the keys of a JDBM BTree.  Obviously does not return duplicate
34   * keys since JDBM does not natively support multiple values for the same key.
35   *
36   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
37   * @version $Rev$, $Date$
38   */
39  public class KeyBTreeCursor<E> extends AbstractCursor<E>
40  {
41      private final Tuple tuple = new Tuple();
42  
43      private final BTree btree;
44      private final Comparator<E> comparator;
45      private boolean valueAvailable;
46      private TupleBrowser browser;
47  
48  
49      /**
50       * Creates a Cursor over the keys of a JDBM BTree.
51       *
52       * @param btree the JDBM BTree to build a Cursor over
53       * @param comparator the Comparator used to determine key ordering
54       * @throws Exception of there are problems accessing the BTree
55       */
56      public KeyBTreeCursor( BTree btree, Comparator<E> comparator ) throws Exception
57      {
58          this.btree = btree;
59          this.comparator = comparator;
60      }
61  
62  
63      private void clearValue()
64      {
65          tuple.setKey( null );
66          tuple.setValue( null );
67          valueAvailable = false;
68      }
69  
70  
71      public boolean available()
72      {
73          return valueAvailable;
74      }
75  
76  
77      public void before( E element ) throws Exception
78      {
79          checkNotClosed( "before()" );
80          browser = btree.browse( element );
81          clearValue();
82      }
83  
84  
85      @SuppressWarnings("unchecked")
86      public void after( E element ) throws Exception
87      {
88          browser = btree.browse( element );
89  
90          /*
91           * While the next value is less than or equal to the element keep
92           * advancing forward to the next item.  If we cannot advance any
93           * further then stop and return.  If we find a value greater than
94           * the element then we stop, backup, and return so subsequent calls
95           * to getNext() will return a value greater than the element.
96           */
97          while ( browser.getNext( tuple ) )
98          {
99              checkNotClosed( "after()" );
100             E next = ( E ) tuple.getKey();
101             int nextCompared = comparator.compare( next, element );
102 
103             if ( nextCompared <= 0 )
104             {
105                 // just continue
106             }
107             else 
108             {
109                 /*
110                  * If we just have values greater than the element argument
111                  * then we are before the first element and must backup to
112                  * before the first element state for the JDBM browser which 
113                  * apparently the browser supports.
114                  */
115                 browser.getPrevious( tuple );
116                 clearValue();
117                 return;
118             }
119         }
120 
121         clearValue();
122         // just return
123     }
124 
125 
126     public void beforeFirst() throws Exception
127     {
128         checkNotClosed( "beforeFirst()" );
129         browser = btree.browse();
130         clearValue();
131     }
132 
133 
134     public void afterLast() throws Exception
135     {
136         checkNotClosed( "afterLast()" );
137         browser = btree.browse( null );
138     }
139 
140 
141     public boolean first() throws Exception
142     {
143         beforeFirst();
144         return next();
145     }
146 
147 
148     public boolean last() throws Exception
149     {
150         afterLast();
151         return previous();
152     }
153 
154 
155     public boolean previous() throws Exception
156     {
157         checkNotClosed( "previous()" );
158         if ( browser == null )
159         {
160             browser = btree.browse( null );
161         }
162 
163         if ( browser.getPrevious( tuple ) )
164         {
165             return valueAvailable = true;
166         }
167         else
168         {
169             clearValue();
170             return false;
171         }
172     }
173 
174 
175     public boolean next() throws Exception
176     {
177         checkNotClosed( "next()" );
178         if ( browser == null )
179         {
180             browser = btree.browse();
181         }
182 
183         if ( browser.getNext( tuple ) )
184         {
185             return valueAvailable = true;
186         }
187         else
188         {
189             clearValue();
190             return false;
191         }
192     }
193 
194 
195     @SuppressWarnings("unchecked")
196     public E get() throws Exception
197     {
198         checkNotClosed( "get()" );
199         if ( valueAvailable )
200         {
201             return ( E ) tuple.getKey();
202         }
203 
204         throw new InvalidCursorPositionException();
205     }
206 
207 
208     public boolean isElementReused()
209     {
210         return false;
211     }
212 }