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.managed;
21  
22  
23  import java.io.IOException;
24  import java.util.LinkedList;
25  
26  import org.apache.directory.mavibot.btree.serializer.ElementSerializer;
27  
28  
29  /**
30   * This class construct a BTree from a serialized version of a BTree. We need it
31   * to avoid exposing all the methods of the BTree class.<br>
32   * 
33   * All its methods are static.
34   *  
35   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
36   */
37  public class BTreeFactory
38  {
39      /**
40       * Create a new BTree.
41       * 
42       * @return The created BTree
43       */
44      public static <K, V> BTree<K, V> createBTree()
45      {
46          BTree<K, V> btree = new BTree<K, V>();
47  
48          return btree;
49      }
50  
51  
52      /**
53       * Create a new Node for the give BTree.
54       * 
55       * @param btree The BTree which will contain this node
56       * @param revision The Node's revision
57       * @param nbElems The number or elements in this node
58       * @return A Node instance
59       */
60      public static <K, V> Node<K, V> createNode( BTree<K, V> btree, long revision, int nbElems )
61      {
62          Node<K, V> node = new Node<K, V>( btree, revision, nbElems );
63  
64          return node;
65      }
66  
67  
68      /**
69       * Create a new Leaf for the give BTree.
70       * 
71       * @param btree The BTree which will contain this leaf
72       * @param revision The Leaf's revision
73       * @param nbElems The number or elements in this leaf
74       * @return A Leaf instance
75       */
76      public static <K, V> Leaf<K, V> createLeaf( BTree<K, V> btree, long revision, int nbElems )
77      {
78          Leaf<K, V> leaf = new Leaf<K, V>( btree, revision, nbElems );
79  
80          return leaf;
81      }
82  
83  
84      /**
85       * Set the new root page for this tree. Used for debug purpose only. The revision
86       * will always be 0;
87       * 
88       * @param root the new root page.
89       */
90      public static <K, V> void setRoot( BTree<K, V> btree, Page<K, V> root )
91      {
92          btree.setRoot( root );
93      }
94  
95  
96      /**
97       * Return the BTree root page
98       * 
99       * @param btree The Btree we want to root page from
100      * @return The root page
101      */
102     public static <K, V> Page<K, V> getRoot( BTree<K, V> btree )
103     {
104         return btree.rootPage;
105     }
106 
107 
108     /**
109      * @param nbElems the nbElems to set
110      */
111     public static <K, V> void setNbElems( BTree<K, V> btree, long nbElems )
112     {
113         btree.setNbElems( nbElems );
114     }
115 
116 
117     /**
118      * @param revision the revision to set
119      */
120     public static <K, V> void setRevision( BTree<K, V> btree, long revision )
121     {
122         btree.setRevision( revision );
123     }
124 
125 
126     /**
127      * @param rootPageOffset the rootPageOffset to set
128      */
129     public static <K, V> void setRootPageOffset( BTree<K, V> btree, long rootPageOffset )
130     {
131         btree.setRootPageOffset( rootPageOffset );
132     }
133 
134 
135     /**
136      * @param nextBTreeOffset the nextBTreeOffset to set
137      */
138     public static <K, V> void setNextBTreeOffset( BTree<K, V> btree, long nextBTreeOffset )
139     {
140         btree.setNextBTreeOffset( nextBTreeOffset );
141     }
142 
143 
144     /**
145      * @param name the name to set
146      */
147     public static <K, V> void setName( BTree<K, V> btree, String name )
148     {
149         btree.setName( name );
150     }
151 
152 
153     /**
154      * Sets the KeySerializer into the BTree
155      *  
156      * @param btree The BTree to update
157      * @param keySerializerFqcn the Key serializer FQCN to set
158      * @throws ClassNotFoundException
159      * @throws InstantiationException 
160      * @throws IllegalAccessException
161      */
162     public static <K, V> void setKeySerializer( BTree<K, V> btree, String keySerializerFqcn )
163         throws ClassNotFoundException, IllegalAccessException, InstantiationException
164     {
165         Class<?> keySerializer = Class.forName( keySerializerFqcn );
166         @SuppressWarnings("unchecked")
167         ElementSerializer<K> instance = ( ElementSerializer<K> ) keySerializer.newInstance();
168         btree.setKeySerializer( instance );
169 
170         btree.setComparator( instance.getComparator() );
171     }
172 
173 
174     /**
175      * Sets the ValueSerializer into the BTree
176      *  
177      * @param btree The BTree to update
178      * @param valueSerializerFqcn the Value serializer FQCN to set
179      * @throws ClassNotFoundException
180      * @throws InstantiationException 
181      * @throws IllegalAccessException
182      */
183     public static <K, V> void setValueSerializer( BTree<K, V> btree, String valueSerializerFqcn )
184         throws ClassNotFoundException, IllegalAccessException, InstantiationException
185     {
186         Class<?> valueSerializer = Class.forName( valueSerializerFqcn );
187         @SuppressWarnings("unchecked")
188         ElementSerializer<V> instance = ( ElementSerializer<V> ) valueSerializer.newInstance();
189         btree.setValueSerializer( instance );
190     }
191 
192 
193     /**
194      * Set the maximum number of elements we can store in a page.
195      * 
196      * @param pageSize The requested page size
197      */
198     public static <K, V> void setPageSize( BTree<K, V> btree, int pageSize )
199     {
200         btree.setPageSize( pageSize );
201     }
202 
203 
204     /**
205      * Set the RecordManager
206      * 
207      * @param recordManager The injected RecordManager
208      */
209     public static <K, V> void setRecordManager( BTree<K, V> btree, RecordManager recordManager )
210     {
211         btree.setRecordManager( recordManager );
212     }
213 
214 
215     /**
216      * Set the key at a give position
217      * @param pos The position in the keys array
218      * @param key the key to inject
219      */
220     public static <K, V> void setKey( Page<K, V> page, int pos, K key )
221     {
222         ( ( AbstractPage<K, V> ) page ).setKey( pos, key );
223     }
224 
225 
226     /**
227      * Set the key at a give position
228      * @param pos The position in the keys array
229      * @param pos the position of this key in the page
230      * @param buffer the byte[] containing the serialized key
231      */
232     public static <K, V> void setKey( Page<K, V> page, int pos, byte[] buffer )
233     {
234         ( ( AbstractPage<K, V> ) page ).setKey( pos, buffer );
235     }
236 
237 
238     /**
239      * Set the value at a give position
240      * @param pos The position in the values array
241      * @param value the value to inject
242      */
243     public static <K, V> void setValue( Leaf<K, V> page, int pos, ValueHolder<V> value )
244     {
245         page.setValue( pos, value );
246     }
247 
248 
249     /**
250      * Set the value at a give position
251      * @param pos The position in the values array
252      * @param value the value to inject
253      */
254     public static <K, V> void setValue( Node<K, V> page, int pos, ElementHolder<Page<K, V>, K, V> value )
255     {
256         page.setValue( pos, value );
257     }
258 
259 
260     /**
261      * Includes the intermediate nodes in the path up to and including the right most leaf of the tree
262      * 
263      * @param btree the btree
264      * @return a LinkedList of all the nodes and the final leaf
265      * @throws IOException
266      */
267     public static <K, V> LinkedList<ParentPos<K, V>> getPathToRightMostLeaf( BTree<K, V> btree ) throws IOException
268     {
269         LinkedList<ParentPos<K, V>> stack = new LinkedList<ParentPos<K, V>>();
270 
271         ParentPos<K, V> last = new ParentPos<K, V>( btree.rootPage, btree.rootPage.getNbElems() );
272         stack.push( last );
273 
274         if ( btree.rootPage instanceof Leaf )
275         {
276             InternalUtil.setLastDupsContainer( last, btree );
277         }
278         else
279         {
280             Node<K, V> node = ( Node<K, V> ) btree.rootPage;
281 
282             while ( true )
283             {
284                 Page<K, V> p = node.children[node.getNbElems()].getValue( btree );
285 
286                 last = new ParentPos<K, V>( p, p.getNbElems() );
287                 stack.push( last );
288 
289                 if ( p instanceof Leaf )
290                 {
291                     InternalUtil.setLastDupsContainer( last, btree );
292                     break;
293                 }
294             }
295         }
296 
297         return stack;
298     }
299 }