1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.directory.mavibot.btree;
22
23
24 import java.io.IOException;
25 import java.lang.reflect.Array;
26 import java.util.ArrayList;
27 import java.util.Iterator;
28 import java.util.List;
29
30 import org.apache.directory.mavibot.btree.serializer.ElementSerializer;
31
32
33
34
35
36
37
38 public class InMemoryBTreeBuilder<K, V>
39 {
40 private String name;
41
42 private int numKeysInNode;
43
44 private ElementSerializer<K> keySerializer;
45
46 private ElementSerializer<V> valueSerializer;
47
48
49 public InMemoryBTreeBuilder( String name, int numKeysInNode, ElementSerializer<K> keySerializer,
50 ElementSerializer<V> valueSerializer )
51 {
52 this.name = name;
53 this.numKeysInNode = numKeysInNode;
54 this.keySerializer = keySerializer;
55 this.valueSerializer = valueSerializer;
56 }
57
58
59 @SuppressWarnings("unchecked")
60 public BTree<K, V> build( Iterator<Tuple<K, V>> sortedTupleItr ) throws IOException
61 {
62 BTree<K, V> btree = BTreeFactory.createInMemoryBTree( name, keySerializer, valueSerializer );
63
64 List<Page<K, V>> lstLeaves = new ArrayList<Page<K, V>>();
65
66 int totalTupleCount = 0;
67
68 InMemoryLeaf<K, V> leaf1 = ( InMemoryLeaf<K, V> ) BTreeFactory.createLeaf( btree, 0, numKeysInNode );
69 lstLeaves.add( leaf1 );
70
71 int leafIndex = 0;
72
73 while ( sortedTupleItr.hasNext() )
74 {
75 Tuple<K, V> tuple = sortedTupleItr.next();
76
77 BTreeFactory.setKey( btree, leaf1, leafIndex, tuple.getKey() );
78
79 InMemoryValueHolder<V> eh = new InMemoryValueHolder<V>( btree, tuple.getValue() );
80
81 BTreeFactory.setValue( btree, leaf1, leafIndex, eh );
82
83 leafIndex++;
84 totalTupleCount++;
85
86 if ( ( totalTupleCount % numKeysInNode ) == 0 )
87 {
88 leafIndex = 0;
89 leaf1 = ( InMemoryLeaf<K, V> ) BTreeFactory.createLeaf( btree, 0, numKeysInNode );
90 lstLeaves.add( leaf1 );
91 }
92 }
93
94 if ( lstLeaves.isEmpty() )
95 {
96 return btree;
97 }
98
99
100 InMemoryLeaf<K, V> lastLeaf = ( InMemoryLeaf<K, V> ) lstLeaves.get( lstLeaves.size() - 1 );
101
102 for ( int i = 0; i < lastLeaf.getNbElems(); i++ )
103 {
104 if ( lastLeaf.getKeys()[i] == null )
105 {
106 int n = i;
107 lastLeaf.setNbElems( n );
108 KeyHolder<K>[] keys = lastLeaf.getKeys();
109
110 lastLeaf.setKeys( ( KeyHolder[] ) Array.newInstance( KeyHolder.class, n ) );
111 System.arraycopy( keys, 0, lastLeaf.getKeys(), 0, n );
112
113 ValueHolder<V>[] values = lastLeaf.values;
114 lastLeaf.values = ( InMemoryValueHolder<V>[] ) Array.newInstance( InMemoryValueHolder.class, n );
115 System.arraycopy( values, 0, lastLeaf.values, 0, n );
116
117 break;
118 }
119 }
120
121 Page<K, V> rootPage = attachNodes( lstLeaves, btree );
122
123 System.out.println( "built rootpage : " + rootPage );
124
125 ( ( AbstractBTree<K, V> ) btree ).setRootPage( rootPage );
126
127 return btree;
128 }
129
130
131 @SuppressWarnings("unchecked")
132 private Page<K, V> attachNodes( List<Page<K, V>> children, BTree<K, V> btree ) throws IOException
133 {
134 if ( children.size() == 1 )
135 {
136 return children.get( 0 );
137 }
138
139 List<Page<K, V>> lstNodes = new ArrayList<Page<K, V>>();
140
141 int numChildren = numKeysInNode + 1;
142
143 InMemoryNode<K, V> node = ( InMemoryNode<K, V> ) BTreeFactory.createNode( btree, 0, numKeysInNode );
144 lstNodes.add( node );
145 int i = 0;
146 int totalNodes = 0;
147
148 for ( Page<K, V> p : children )
149 {
150 if ( i != 0 )
151 {
152 BTreeFactory.setKey( btree, node, i - 1, p.getLeftMostKey() );
153 }
154
155 node.setPageHolder( i, new PageHolder<K, V>( btree, p ) );
156
157 i++;
158 totalNodes++;
159
160 if ( ( totalNodes % numChildren ) == 0 )
161 {
162 i = 0;
163 node = ( InMemoryNode<K, V> ) BTreeFactory.createNode( btree, 0, numKeysInNode );
164 lstNodes.add( node );
165 }
166 }
167
168
169 AbstractPage<K, V> lastNode = ( AbstractPage<K, V> ) lstNodes.get( lstNodes.size() - 1 );
170
171 for ( int j = 0; j < lastNode.getNbElems(); j++ )
172 {
173 if ( lastNode.getKey( j ) == null )
174 {
175 int n = j;
176 lastNode.setNbElems( n );
177 KeyHolder<K>[] keys = lastNode.getKeys();
178
179 lastNode.setKeys( ( KeyHolder[] ) Array.newInstance( KeyHolder.class, n ) );
180 System.arraycopy( keys, 0, lastNode.getKeys(), 0, n );
181
182 break;
183 }
184 }
185
186 return attachNodes( lstNodes, btree );
187 }
188 }