30
30
31
31
#define BLOCKSIZE 4096
32
32
#define T 255
33
+ #define LEAF 0x0001
34
+ #define ONDISK 0x0002
35
+
33
36
namespace alg {
34
37
class BTree {
35
38
private:
36
39
// 4K node, 4096 bytes to write
37
40
// t = 255
38
41
struct node_t {
39
- int16_t leaf ; // is leaf?
40
- int16_t n ; // num key
41
- int32_t offset; // block offset (8 byte head)
42
- int32_t key[ 509 ]; // key
43
- int32_t c[ 510 ]; // childs pointers (file offsets related to 0)
44
- char padding[ 12 ]; // padding to 4096
42
+ uint16_t n ; // num key
43
+ uint16_t flag ; // flags
44
+ uint32_t offset; // block offset (8 byte head)
45
+ char padding[ 12 ]; // padding to 4096
46
+ int32_t key[ 509 ]; // key
47
+ int32_t c[ 510 ]; // childs pointers (file offsets related to 0)
45
48
} __attribute__ ((packed));
46
49
typedef struct node_t *node;
47
50
@@ -67,7 +70,7 @@ namespace alg {
67
70
node x = (node)allocate_node ();
68
71
int n = read (fd,x,BLOCKSIZE);
69
72
if (n != BLOCKSIZE) { // init new btree
70
- x->leaf = true ;
73
+ x->flag |= LEAF ;
71
74
WRITE (x);
72
75
}
73
76
m_root = (node)x;
@@ -86,13 +89,14 @@ namespace alg {
86
89
if (r->n == 2 *T - 1 ) {
87
90
node s = (node)allocate_node ();
88
91
// place the old root node to the end of the file
89
- m_root->offset = - 1 ;
90
- WRITE (m_root);
92
+ m_root->flag &= ~ONDISK ;
93
+ WRITE (m_root);
91
94
// new root
95
+ s->flag &= ~LEAF;
92
96
s->offset = 0 ;
93
97
s->n = 0 ;
94
98
s->c [0 ] = m_root->offset ;
95
- free (m_root);
99
+ // free(m_root);
96
100
m_root = s;
97
101
split_child (s, 0 );
98
102
insert_nonfull (s, k);
@@ -106,14 +110,14 @@ namespace alg {
106
110
* search a key, returns node and index
107
111
*/
108
112
search_r search (node x, int32_t k) {
109
- int i = 0 ;
113
+ uint16_t i = 0 ;
110
114
search_r ret;
111
115
while (i<x->n && k > x->key [i]) i++;
112
116
113
- if (i < x->n && k == x->key [i]) {
117
+ if (i< x->n && k == x->key [i]) {
114
118
ret.n = x, ret.i = i;
115
119
return ret;
116
- } else if (x->leaf ) {
120
+ } else if (x->flag & LEAF ) {
117
121
ret.n = NULL , ret.i = i;
118
122
return ret;
119
123
} else {
@@ -127,7 +131,7 @@ namespace alg {
127
131
*/
128
132
void insert_nonfull (node x, int32_t k) {
129
133
int32_t i = x->n -1 ;
130
- if (x->leaf ) {
134
+ if (x->flag & LEAF ) {
131
135
while (i>=0 && k <x->key [i]) {
132
136
x->key [i+1 ] = x->key [i];
133
137
i = i - 1 ;
@@ -140,14 +144,15 @@ namespace alg {
140
144
i = i-1 ;
141
145
}
142
146
i=i+1 ;
143
- std::auto_ptr< node_t > xi ( READ (x, i) );
147
+ node xi = READ (x, i);
144
148
if (xi->n == 2 *T-1 ) {
145
149
split_child (x, i);
146
150
if (k > x->key [i]) {
147
151
i = i+1 ;
148
152
}
149
153
}
150
- insert_nonfull (xi.get (), k);
154
+ insert_nonfull (xi, k);
155
+ free (xi);
151
156
}
152
157
}
153
158
@@ -156,9 +161,9 @@ namespace alg {
156
161
*/
157
162
void * allocate_node () {
158
163
node x = (node)malloc (sizeof (node_t ));
159
- x->leaf = false ;
160
164
x->n = 0 ;
161
- x->offset = -1 ;
165
+ x->offset = 0 ;
166
+ x->flag = 0 ;
162
167
memset (x->key , 0 , sizeof (x->key ));
163
168
memset (x->c , 0 , sizeof (x->c ));
164
169
return x;
@@ -170,15 +175,15 @@ namespace alg {
170
175
void split_child (node x, int32_t i) {
171
176
std::auto_ptr<node_t > z ((node)allocate_node ());
172
177
std::auto_ptr<node_t > y (READ (x, i));
173
- z->leaf = y->leaf ;
178
+ z->flag |= ( y->flag & LEAF) ;
174
179
z->n = T - 1 ;
175
180
176
- int j;
181
+ uint16_t j;
177
182
for (j=0 ;j<T-1 ;j++) { // init z
178
183
z->key [j] = y->key [j+T];
179
184
}
180
185
181
- if (!y->leaf ) {
186
+ if (!( y->flag & LEAF) ) {
182
187
for (j=0 ;j<T;j++) {
183
188
z->c [j] = y->c [j+T];
184
189
}
@@ -192,13 +197,13 @@ namespace alg {
192
197
x->c [j+1 ] = x->c [j]; // shift
193
198
}
194
199
195
- // relocate z
200
+ // save z
196
201
x->c [i+1 ] = z->offset ;
197
202
198
203
for (j=x->n -1 ;j>=i;j--) {
199
204
x->key [j+1 ] = x->key [j];
200
205
}
201
- x->key [i] = y->key [T];
206
+ x->key [i] = y->key [T- 1 ];
202
207
x->n = x->n +1 ;
203
208
WRITE (x);
204
209
}
@@ -217,11 +222,12 @@ namespace alg {
217
222
* update a node struct to file, create if offset is -1.
218
223
*/
219
224
void WRITE (node x) {
220
- if (x->offset !=- 1 ) {
225
+ if (x->flag & ONDISK ) {
221
226
lseek (fd, x->offset , SEEK_SET);
222
227
} else {
223
228
x->offset = lseek (fd,0 , SEEK_END);
224
229
}
230
+ x->flag |= ONDISK;
225
231
write (fd, x, BLOCKSIZE);
226
232
}
227
233
};
0 commit comments