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.serializer.ElementSerializer;
27  
28  
29  /**
30   * This cless 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:labs@labs.apache.org">Mavibot labs Project</a>
36   */
37  public class BTreeFactory
38  {
39      /**
40       * Create a new BTree.
41       * 
42       * @return The created BTree
43       */
44      public static BTree createBTree()
45      {
46          BTree btree = new BTree();
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 Node createNode( BTree btree, long revision, int nbElems )
61      {
62          Node node = new Node( 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 Leaf createLeaf( BTree btree, long revision, int nbElems )
77      {
78          Leaf leaf = new Leaf( 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 void setRoot( BTree<?, ?> btree, Page 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 Page getRoot( BTree<?, ?> btree )
103     {
104         return btree.rootPage;
105     }
106 
107 
108     /**
109      * @param nbElems the nbElems to set
110      */
111     public static void setNbElems( BTree<?, ?> btree, long nbElems )
112     {
113         btree.setNbElems( nbElems );
114     }
115 
116 
117     /**
118      * @param revision the revision to set
119      */
120     public static void setRevision( BTree<?, ?> btree, long revision )
121     {
122         btree.setRevision( revision );
123     }
124 
125 
126     /**
127      * @param rootPageOffset the rootPageOffset to set
128      */
129     public static void setRootPageOffset( BTree<?, ?> btree, long rootPageOffset )
130     {
131         btree.setRootPageOffset( rootPageOffset );
132     }
133 
134 
135     /**
136      * @param nextBTreeOffset the nextBTreeOffset to set
137      */
138     public static void setNextBTreeOffset( BTree<?, ?> btree, long nextBTreeOffset )
139     {
140         btree.setNextBTreeOffset( nextBTreeOffset );
141     }
142 
143 
144     /**
145      * @param name the name to set
146      */
147     public static void setName( BTree<?, ?> 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 void setKeySerializer( BTree<?, ?> btree, String keySerializerFqcn )
163         throws ClassNotFoundException, IllegalAccessException, InstantiationException
164     {
165         Class<?> keySerializer = Class.forName( keySerializerFqcn );
166         ElementSerializer instance = ( ElementSerializer ) keySerializer.newInstance();
167         btree.setKeySerializer( instance );
168 
169         btree.setComparator( instance.getComparator() );
170     }
171 
172 
173     /**
174      * Sets the ValueSerializer into the BTree
175      *  
176      * @param btree The BTree to update
177      * @param valueSerializerFqcn the Value serializer FQCN to set
178      * @throws ClassNotFoundException
179      * @throws InstantiationException 
180      * @throws IllegalAccessException
181      */
182     public static void setValueSerializer( BTree<?, ?> btree, String valueSerializerFqcn )
183         throws ClassNotFoundException, IllegalAccessException, InstantiationException
184     {
185         Class<?> valueSerializer = Class.forName( valueSerializerFqcn );
186         btree.setValueSerializer( ( ElementSerializer ) valueSerializer.newInstance() );
187     }
188 
189 
190     /**
191      * Set the maximum number of elements we can store in a page.
192      * 
193      * @param pageSize The requested page size
194      */
195     public static void setPageSize( BTree<?, ?> btree, int pageSize )
196     {
197         btree.setPageSize( pageSize );
198     }
199 
200 
201     /**
202      * Set the RecordManager
203      * 
204      * @param recordManager The injected RecordManager
205      */
206     public static void setRecordManager( BTree<?, ?> btree, RecordManager recordManager )
207     {
208         btree.setRecordManager( recordManager );
209     }
210 
211 
212     /**
213      * Set the key at a give position
214      * @param pos The position in the keys array
215      * @param key the key to inject
216      */
217     public static void setKey( Page page, int pos, Object key )
218     {
219         ( ( AbstractPage ) page ).setKey( pos, key );
220     }
221 
222 
223     /**
224      * Set the value at a give position
225      * @param pos The position in the values array
226      * @param value the value to inject
227      */
228     public static void setValue( Leaf page, int pos, ElementHolder value )
229     {
230         page.setValue( pos, value );
231     }
232 
233 
234     /**
235      * Set the value at a give position
236      * @param pos The position in the values array
237      * @param value the value to inject
238      */
239     public static void setValue( Node page, int pos, ElementHolder value )
240     {
241         page.setValue( pos, value );
242     }
243     
244 
245     /**
246      * Includes the intermediate nodes in the path up to and including the right most leaf of the tree
247      * 
248      * @param btree the btree
249      * @return a LinkedList of all the nodes and the final leaf
250      * @throws IOException
251      */
252     public static LinkedList getPathToRightMostLeaf( BTree btree ) throws IOException
253     {
254         LinkedList<ParentPos> stack = new LinkedList<ParentPos>();
255         
256         ParentPos last = new ParentPos( btree.rootPage, btree.rootPage.getNbElems() );
257         stack.push( last );
258         
259         
260         if( btree.rootPage instanceof Leaf )
261         {
262             InternalUtil.setLastDupsContainer( last, btree );
263         }
264         else
265         {
266             Node node = ( Node ) btree.rootPage;
267             
268             while( true )
269             {
270                 Page p = ( Page ) node.children[node.getNbElems()].getValue( btree );
271                 
272                 last = new ParentPos( p, p.getNbElems() );
273                 stack.push( last );
274                 
275                 if( p instanceof Leaf )
276                 {
277                     InternalUtil.setLastDupsContainer( last, btree );
278                     break;
279                 }
280             }
281         }
282         
283         return stack;
284     }
285 }