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   */
20  package org.apache.directory.mavibot.btree;
21  
22  
23  import java.io.IOException;
24  import java.util.LinkedList;
25  
26  import org.apache.directory.mavibot.btree.exception.EndOfFileExceededException;
27  import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
28  
29  
30  /**
31   * A MVCC Page interface. A Page can be either a Leaf (containing keys and values) or a Node
32   * (containing keys and references to child pages).<br/>
33   * A Page can be stored on disk. If so, we store the serialized value of this Page into
34   * one or more {@link PageIO} (they will be linked)
35   * 
36   * @param <K> The type for the Key
37   * @param <V> The type for the stored value
38   *
39   * @author <a href="mailto:labs@labs.apache.org">Mavibot labs Project</a>
40   */
41  /* No qualifier */interface Page<K, V>
42  {
43      /**
44       * @return The number of keys present in this page
45       */
46      int getNbElems();
47  
48  
49      /**
50       * Inserts the given key and value into this page. We first find the place were to
51       * inject the <K,V> into the tree, by recursively browsing the pages :<br/>
52       * <ul>
53       * <li>If the index is below zero, the key is present in the Page : we modify the
54       * value and return</li>
55       * <li>If the page is a node, we have to go down to the right child page</li>
56       * <li>If the page is a leaf, we insert the new <K,V> element into the page, and if
57       * the Page is full, we split it and propagate the new pivot up into the tree</li>
58       * </ul>
59       * <p>
60       * 
61       * @param revision The new revision for the modified pages
62       * @param key Inserted key
63       * @param value Inserted value
64       * @return Either a modified Page or an Overflow element if the Page was full
65       * @throws IOException If we have an error while trying to access the page
66       */
67      InsertResult<K, V> insert( long revision, K key, V value ) throws IOException;
68  
69  
70      /**
71       * Deletes the value from an entry associated with the given key in this page. We first find 
72       * the place were to remove the <K,V> into the tree, by recursively browsing the pages.
73       * If the value is present, it will be deleted first, later if there are no other values associated with 
74       * this key(which can happen when duplicates are enabled), we will remove the key from the tree.
75       * 
76       * @param revision The new revision for the modified pages
77       * @param key The key to delete
78       * @param value The value to delete (can be null)
79       * @param parent The parent page
80       * @param parentPos The position of the current page in it's parent
81       * @return Either a modified Page if the key has been removed from the page, or a NotPresentResult.
82       * @throws IOException If we have an error while trying to access the page
83       */
84      DeleteResult<K, V> delete( long revision, K key, V value, Page<K, V> parent, int parentPos ) throws IOException;
85  
86  
87      /**
88       * Gets the value associated with the given key, if any. If we don't have 
89       * one, this method will throw a KeyNotFoundException.<br/>
90       * Note that we may get back null if a null value has been associated 
91       * with the key.
92       * 
93       * @param key The key we are looking for
94       * @return The associated value, which can be null
95       * @throws KeyNotFoundException If no entry with the given key can be found
96       * @throws IOException If we have an error while trying to access the page
97       */
98      V get( K key ) throws KeyNotFoundException, IOException;
99  
100 
101     /**
102      * Gets the values associated with the given key, if any. If we don't have 
103      * the key, this method will throw a KeyNotFoundException.<br/>
104      * Note that we may get back null if a null value has been associated 
105      * with the key.
106      * 
107      * @param key The key we are looking for
108      * @return The associated value, which can be null
109      * @throws KeyNotFoundException If no entry with the given key can be found
110      * @throws IOException If we have an error while trying to access the page
111      * @throws IllegalArgumentException If duplicates are not enabled 
112      */
113     BTree<V, V> getValues( K key ) throws KeyNotFoundException, IOException, IllegalArgumentException;
114 
115 
116     /**
117      * Checks if the page contains the given key with the given value.
118      * 
119      * @param key The key we are looking for
120      * @param value The value associated with the given key
121      * @return true if the key and value are associated with each other, false otherwise
122      */
123     boolean contains( K key, V value ) throws IOException;
124 
125 
126     /**
127      * Browses the tree, looking for the given key, and creates a Cursor on top
128      * of the found result.
129      * 
130      * @param key The key we are looking for.
131      * @param transaction The started transaction for this operation
132      * @param stack The stack of parents we go through to get to this page
133      * @return A Cursor to browse the next elements
134      * @throws IOException If we have an error while trying to access the page
135      */
136     Cursor<K, V> browse( K key, Transaction<K, V> transaction, LinkedList<ParentPos<K, V>> stack )
137         throws IOException;
138 
139 
140     /**
141      * Browses the whole tree, and creates a Cursor on top of it.
142      * 
143      * @param transaction The started transaction for this operation
144      * @param stack The stack of parents we go through to get to this page
145      * @return A Cursor to browse the next elements
146      * @throws IOException If we have an error while trying to access the page
147      */
148     Cursor<K, V> browse( Transaction<K, V> transaction, LinkedList<ParentPos<K, V>> stack )
149         throws EndOfFileExceededException, IOException;
150 
151 
152     /**
153      * @return the revision
154      */
155     long getRevision();
156 
157 
158     /**
159      * Returns the key at a given position
160      * 
161      * @param pos The position of the key we want to retrieve
162      * @return The key found at the given position
163      */
164     K getKey( int pos );
165 
166 
167     /**
168      * Finds the leftmost key in this page. If the page is a node, it will go
169      * down in the leftmost children to recursively find the leftmost key.
170      * 
171      * @return The leftmost key in the tree
172      * @throws IOException If we have an error while trying to access the page
173      */
174     K getLeftMostKey() throws IOException;
175 
176 
177     /**
178      * Finds the rightmost key in this page. If the page is a node, it will go
179      * down in the rightmost children to recursively find the rightmost key.
180      * 
181      * @return The rightmost key in the tree
182      * @throws IOException If we have an error while trying to access the page
183      */
184     K getRightMostKey() throws IOException;
185 
186 
187     /**
188      * Finds the leftmost element in this page. If the page is a node, it will go
189      * down in the leftmost children to recursively find the leftmost element.
190      * 
191      * @return The leftmost element in the tree
192      * @throws IOException If we have an error while trying to access the page
193      */
194     Tuple<K, V> findLeftMost() throws IOException;
195 
196 
197     /**
198      * Finds the rightmost element in this page. If the page is a node, it will go
199      * down in the rightmost children to recursively find the rightmost element.
200      * 
201      * @return The rightmost element in the tree
202      * @throws IOException If we have an error while trying to access the page
203      */
204     Tuple<K, V> findRightMost() throws EndOfFileExceededException, IOException;
205 
206 
207     /**
208      * Pretty-prints the tree with tabs
209      * @param tabs The tabs to add in front of each node
210      * @return A pretty-print dump of the tree
211      */
212     String dumpPage( String tabs );
213 
214 
215     /**
216      * Find the position of the given key in the page. If we have found the key,
217      * we will return its position as a negative value.
218      * <p/>
219      * Assuming that the array is zero-indexed, the returned value will be : <br/>
220      *   position = - ( position + 1)
221      * <br/>
222      * So for the following table of keys : <br/>
223      * <pre>
224      * +---+---+---+---+
225      * | b | d | f | h |
226      * +---+---+---+---+
227      *   0   1   2   3
228      * </pre>
229      * looking for 'b' will return -1 (-(0+1)) and looking for 'f' will return -3 (-(2+1)).<br/>
230      * Computing the real position is just a matter to get -(position++).
231      * <p/>
232      * If we don't find the key in the table, we will return the position of the key
233      * immediately above the key we are looking for. <br/>
234      * For instance, looking for :
235      * <ul>
236      * <li>'a' will return 0</li>
237      * <li>'b' will return -1</li>
238      * <li>'c' will return 1</li>
239      * <li>'d' will return -2</li>
240      * <li>'e' will return 2</li>
241      * <li>'f' will return -3</li>
242      * <li>'g' will return 3</li>
243      * <li>'h' will return -4</li>
244      * <li>'i' will return 4</li>
245      * </ul>
246      * 
247      * 
248      * @param key The key to find
249      * @return The position in the page.
250      */
251     int findPos( K key );
252 
253 
254     /**
255      * Checks if the given key exists.
256      *  
257      * @param key The key we are looking at
258      * @return true if the key is present, false otherwise
259      * @throws IOException If we have an error while trying to access the page
260      */
261     boolean hasKey( K key ) throws IOException;
262 
263 
264     /**
265      * @return the offset of the first {@link PageIO} which stores the Page on disk.
266      */
267     long getOffset();
268 
269 
270     /**
271      * @return the offset of the last {@link PageIO} which stores the Page on disk.
272      */
273     long getLastOffset();
274 }