UbixOS V2
2.0
btree.cpp
Go to the documentation of this file.
1
// http://www.cs.msstate.edu/~cs2314/global/BTreeAnimation/algorithm.html
2
3
/*
4
5
#include <stdlib.h>
6
#include <string.h>
7
#include <stdio.h>
8
#include <unistd.h>
9
#include <iostream>
10
#include <assert.h>
11
#include "btree.h"
12
#include "ubixfs.h"
13
14
using namespace std;
15
#define VERIFY(x, y, z, n) if ((x) != (y)) { cout << "verify " << z << " failed" << endl; PrintWholeTree(); }
16
17
bTree::bTree(UbixFS * filesystem, fileDescriptor * myfd) {
18
size_t result = 0;
19
20
root = NULL;
21
tag = 0;
22
fs = filesystem;
23
fd = myfd;
24
header = new bTreeHeader;
25
assert(header);
26
memset(header, 0, sizeof(bTreeHeader));
27
assert(fs);
28
result = fs->vfs_read(fd, header, 0, sizeof(bTreeHeader));
29
assert(result == sizeof(bTreeHeader));
30
31
// If there are any files in this dir, load the first node of the b+tree
32
if (header->treeLeafCount != 0) {
33
assert(header->firstNodeOffset != 0);
34
root = new bNode;
35
assert(root);
36
result = fs->vfs_read(fd, root, header->firstNodeOffset, sizeof(bNode));
37
assert(result == sizeof(bNode));
38
} // if
39
40
} // bTree::bTree
41
42
bTree::bTree(const char * key, ubixfsInode * inode) {
43
// once the FS and the bTree are interfaced, this should go away
44
root = NULL;
45
tag = 0;
46
header = new bTreeHeader;
47
assert(header);
48
memset(header, 0, sizeof(bTreeHeader));
49
header->treeDepth = 1;
50
header->treeWidth = 0;
51
header->treeLeafCount = 0;
52
header->firstDeleted = -1;
53
header->firstNodeOffset = sizeof(bTreeHeader);
54
55
if (inode == NULL) return;
56
root = allocEmptyNode();
57
if (root == NULL) return;
58
root->used = 1;
59
root->parent.bPtr = NULL;
60
root->leaf = true;
61
root->childCount[1] = 1;
62
63
// cout << "---Creating " << inode->name << "@" << inode << endl;
64
strncpy(root->keys[0], key, B_MAX_NAME_LENGTH);
65
// insert pointer to data page to the right of the data
66
root->head[1].iPtr = inode;
67
root->tail[1].iPtr = inode;
68
69
root->present[1] = true;
70
if (inode != NULL) {
71
inode->next.bPtr = inode->prev.bPtr = NULL;
72
} // if
73
return;
74
} // bTree:bTree
75
76
bool
77
bTree::Insert(const char * key, ubixfsInode * inode) {
78
bNode * bnode = root;
79
ubixfsInode * tmpInode = NULL;
80
unsigned int curSlot = 0;
81
82
if (inode == NULL) return false;
83
84
// note: this code is right out of the constructor
85
if (root == NULL) {
86
if (header == NULL) header = new bTreeHeader;
87
assert(header);
88
memset(header, 0, sizeof(bTreeHeader));
89
header->treeDepth = 1;
90
header->treeWidth = 0;
91
header->treeLeafCount = 0;
92
header->firstDeleted = -1;
93
header->firstNodeOffset = sizeof(bTreeHeader);
94
95
root = allocEmptyNode();
96
assert(root);
97
if (root == NULL) return false;
98
99
root->used = 1;
100
root->parent.bPtr = NULL;
101
root->leaf = true;
102
root->childCount[1] = 1;
103
104
strncpy(root->keys[0], key, B_MAX_NAME_LENGTH);
105
// insert pointer to data page to the right of the data
106
root->head[1].iPtr = inode;
107
root->tail[1].iPtr = inode;
108
109
root->present[1] = true;
110
inode->next.iPtr = inode->prev.iPtr = NULL;
111
return true;
112
} // if
113
114
tmpInode = Find(key);
115
if (tmpInode != NULL) return false;
116
// PrintWholeTree();
117
// cout << "Insert(" << key << ")" << endl;
118
//Info(bnode);
119
++header->treeLeafCount;
120
//Find the leaf node the inode goes into
121
122
assert(bnode->used);
123
// cout << "---Inserting " << inode->name << " @ " << inode << endl;
124
while (bnode != NULL && !bnode->leaf) {
125
if (strcmp(key, bnode->keys[0]) < 0) {
126
bnode = bnode->head[0].bPtr;
127
} else {
128
if (strcmp(key, bnode->keys[bnode->used-1]) >= 0) {
129
bnode = bnode->head[bnode->used].bPtr;
130
} else {
131
for (unsigned int i = 1; i < bnode->used; i++) {
132
if (strcmp(key, bnode->keys[i]) < 0) {
133
bnode = bnode->head[i].bPtr;
134
break;
135
} // if
136
} // for i
137
} // else
138
}
139
} // while
140
141
142
assert(bnode);
143
if (bnode->leaf != true) cout << "leafnode!=true" << endl;
144
assert(inode);
145
146
if (strcmp(key, bnode->keys[curSlot = 0]) < 0)
147
tmpInode = bnode->head[curSlot].iPtr;
148
else
149
if (strcmp(key, bnode->keys[(curSlot = bnode->used)-1]) >= 0)
150
tmpInode = bnode->head[bnode->used].iPtr;
151
else {
152
for (curSlot = 1; curSlot < bnode->used; curSlot++) {
153
if (strcmp(key, bnode->keys[curSlot]) < 0) {
154
tmpInode = bnode->head[curSlot].iPtr;
155
break;
156
} // if
157
} // for curSlot
158
tmpInode = bnode->head[curSlot].iPtr;
159
} // else
160
161
162
if (tmpInode == NULL) {
163
// This is the first node in this leaf
164
bnode->head[curSlot].iPtr = bnode->tail[curSlot].iPtr = inode;
165
bnode->present[curSlot] = true;
166
167
if (curSlot == 0) {
168
169
if (bnode->head[1].iPtr != NULL) {
170
ubixfsInode * iptr = bnode->head[1].iPtr;
171
inode->prev.iPtr = iptr->prev.iPtr;
172
inode->next.iPtr = iptr;
173
iptr->prev.iPtr = inode;
174
if (inode->prev.iPtr != NULL)
175
inode->prev.iPtr->next.iPtr = inode;
176
} else {
177
inode->next.iPtr = inode->prev.iPtr = NULL;
178
} // else
179
180
} else {
181
++bnode->used;
182
} // else
183
184
} else {
185
// Add node to leaf page. Scan through to find where it goes.
186
187
if (strcmp(key, bnode->head[curSlot].iPtr->name) < 0)
188
{
189
190
inode->next.iPtr = bnode->head[curSlot].iPtr;
191
inode->prev.iPtr = inode->next.iPtr->prev.iPtr;
192
inode->next.iPtr->prev.iPtr = inode;
193
if (inode->prev.iPtr != NULL) inode->prev.iPtr->next.iPtr = inode;
194
bnode->head[curSlot].iPtr = inode;
195
196
} else {
197
198
if (strcmp(key, bnode->tail[curSlot].iPtr->name) > 0) {
199
200
inode->prev.iPtr = bnode->tail[curSlot].iPtr;
201
inode->next.iPtr = inode->prev.iPtr->next.iPtr;
202
inode->prev.iPtr->next.iPtr = inode;
203
204
if (inode->next.iPtr != NULL) inode->next.iPtr->prev.iPtr = inode;
205
bnode->tail[curSlot].iPtr = inode;
206
207
} else {
208
209
210
ubixfsInode * tmpInode = bnode->head[curSlot].iPtr;
211
for (unsigned int i = 0; i < bnode->childCount[curSlot]; i++) {
212
if (strcmp(key, tmpInode->name) < 0) {
213
inode->next.iPtr = tmpInode;
214
inode->prev.iPtr = tmpInode->prev.iPtr;
215
inode->next.iPtr->prev.iPtr = inode;
216
inode->prev.iPtr->next.iPtr = inode;
217
break;
218
} // if
219
tmpInode = tmpInode->next.iPtr;
220
} // for i
221
222
} // else
223
224
} // else
225
226
} // else
227
228
229
230
if (++bnode->childCount[curSlot] == B_MAX_CHILD_COUNT) {
231
232
// cout << "---- before split ----" << endl;
233
// Info(bnode);
234
235
if (curSlot != bnode->used) {
236
int shift = bnode->used - curSlot +1;
237
238
memmove(&bnode->head[curSlot+1],
239
&bnode->head[curSlot],
240
sizeof(bnode->head[0]) * shift);
241
memmove(&bnode->tail[curSlot+1],
242
&bnode->tail[curSlot],
243
sizeof(bnode->tail[0]) * shift);
244
memmove(&bnode->present[curSlot+1],
245
&bnode->present[curSlot],
246
sizeof(bnode->present[0]) * shift);
247
memmove(&bnode->childCount[curSlot+1],
248
&bnode->childCount[curSlot],
249
sizeof(bnode->childCount[0]) * shift);
250
251
memmove(&bnode->keys[curSlot+1],
252
&bnode->keys[curSlot],
253
sizeof(bnode->keys[0]) * (shift-1));
254
memset(bnode->keys[curSlot], 0, B_MAX_NAME_LENGTH);
255
} else {
256
bnode->head[curSlot+1] = bnode->head[curSlot];
257
bnode->tail[curSlot+1] = bnode->tail[curSlot];
258
bnode->childCount[curSlot+1] = bnode->childCount[curSlot];
259
bnode->present[curSlot+1] = bnode->present[curSlot];
260
} // else
261
262
ubixfsInode * tmpInode = bnode->head[curSlot].iPtr;
263
264
for (unsigned int i = 0; i < (B_MAX_CHILD_COUNT+1) >> 1; i++) {
265
assert(tmpInode);
266
tmpInode = tmpInode->next.iPtr;
267
} // for i
268
269
strncpy(bnode->keys[curSlot], tmpInode->name, B_MAX_NAME_LENGTH);
270
bnode->head[curSlot+1].iPtr = tmpInode;
271
bnode->tail[curSlot].iPtr = tmpInode->prev.iPtr;
272
bnode->childCount[curSlot] = (B_MAX_CHILD_COUNT+1) >> 1;
273
bnode->childCount[curSlot+1] -= bnode->childCount[curSlot];
274
bnode->present[curSlot] = true;
275
++header->treeWidth;
276
if (++bnode->used == B_MAX_KEYS) splitNode(bnode);
277
278
} // if leaf is full
279
// Info(bnode);
280
return true;
281
} // bTree::Insert
282
283
void
284
bTree::splitNode(bNode * oldNode) {
285
ubixfsInode * tmpInode = NULL;
286
assert(oldNode);
287
if (oldNode == NULL) return;
288
if (oldNode->used != B_MAX_KEYS) return;
289
290
bNode * newNode = allocEmptyNode();
291
if (newNode == NULL) return;
292
293
unsigned int shift = B_MAX_KEYS >> 1;
294
unsigned int splitLoc = B_MAX_KEYS - shift;
295
++ shift;
296
// cout << "oldNode before split: " << endl;
297
// Info(oldNode);
298
// cout << "splitLoc: " << splitLoc << endl;
299
// cout << "shift: " << shift << endl;
300
301
newNode->used = oldNode->used = B_MAX_KEYS >> 1;
302
newNode->parent.bPtr = oldNode->parent.bPtr;
303
newNode->leaf = oldNode->leaf;
304
305
// cout << "newNode->used: " << newNode->used << endl;
306
// cout << "oldNode->used: " << oldNode->used << endl;
307
308
memcpy(&newNode->keys[0],
309
&oldNode->keys[splitLoc],
310
sizeof(newNode->keys[0]) * (shift-1));
311
312
memset(&oldNode->keys[splitLoc], 0, sizeof(newNode->keys[0]) * (shift-1));
313
314
memcpy(&newNode->present[0],
315
&oldNode->present[splitLoc],
316
sizeof(newNode->present[0]) * shift);
317
318
memset(&oldNode->present[splitLoc], 0, sizeof(newNode->present[0]) * shift);
319
320
memcpy(&newNode->head[0],
321
&oldNode->head[splitLoc],
322
sizeof(newNode->head[0]) * shift);
323
324
memset(&oldNode->head[splitLoc], 0,
325
sizeof(newNode->head[0]) * shift);
326
327
memcpy(&newNode->tail[0],
328
&oldNode->tail[splitLoc],
329
sizeof(newNode->tail[0]) * shift);
330
331
memset(&oldNode->tail[splitLoc], 0,
332
sizeof(newNode->tail[0]) * shift);
333
334
memcpy(&newNode->childCount[0],
335
&oldNode->childCount[splitLoc],
336
sizeof(newNode->childCount[0]) * shift);
337
338
memset(&oldNode->childCount[splitLoc], 0,
339
sizeof(newNode->childCount[0]) * shift);
340
341
if (!newNode->leaf) {
342
for (unsigned int i = 0; i <= newNode->used; i++) {
343
newNode->head[i].bPtr->parent.bPtr = newNode;
344
} // for i
345
} // if newNode isn't a leaf
346
347
tmpInode = GetFirstNode(newNode);
348
assert(tmpInode);
349
350
if (oldNode == root) {
351
// allocate a new root node
352
++header->treeDepth;
353
root = allocEmptyNode();
354
oldNode->parent.bPtr = root;
355
newNode->parent.bPtr = root;
356
// strncpy(root->keys[0], newNode->keys[0], B_MAX_NAME_LENGTH);
357
strncpy(root->keys[0], tmpInode->name, B_MAX_NAME_LENGTH);
358
root->head[0].bPtr = oldNode;
359
root->tail[0].bPtr = root->tail[1].bPtr = NULL;
360
root->head[1].bPtr = newNode;
361
root->used = 1;
362
root->leaf = false;
363
root->present[0] = root->present[1] = true;
364
root->childCount[0] = root->childCount[1] = 0;
365
// root->childCount[0] = oldNode->used;
366
// root->childCount[1] = newNode->used;
367
368
// cout << "parent" << endl;
369
// Info(newNode->parent);
370
// cout << "oldNode" << endl;
371
// Info(oldNode);
372
// cout << "-----" << endl;
373
// cout << "newNode" << endl;
374
// Info(newNode);
375
// cout << "-----" << endl;
376
377
} else {
378
insertNode(newNode->parent.bPtr, tmpInode->name, newNode);
379
// if (oldNode->parent->used == B_MAX_KEYS) splitNode(oldNode->parent);
380
} // else
381
return;
382
} // bTree::splitNode
383
384
void
385
bTree::insertNode(bNode * node, const char * key, bNode * headPtr) {
386
unsigned int curSlot = 0;
387
if (node == NULL || key == NULL) return;
388
389
if (strcmp(key, node->keys[node->used-1]) >= 0){
390
curSlot = node->used;
391
memset(node->keys[curSlot], 0, B_MAX_NAME_LENGTH);
392
strncpy(node->keys[curSlot], key, B_MAX_NAME_LENGTH);
393
node->head[curSlot+1].bPtr = headPtr;
394
node->tail[curSlot+1].bPtr = NULL;
395
node->present[curSlot+1] = true;
396
node->childCount[node->used] = 0; // maybe?
397
398
} else {
399
400
for (curSlot = 0; curSlot < node->used; curSlot++) {
401
if (strcmp(key, node->keys[curSlot]) < 0) break;
402
} // for
403
404
405
*/
/*
406
* note that there is one more item for everything but keys
407
* So, make the shift count +1 and just subtract it from the key shift
408
* later
409
*/
/*
410
int shift = node->used - curSlot +1;
411
412
memmove(&node->head[curSlot+1],
413
&node->head[curSlot],
414
sizeof(node->head[0]) * shift);
415
memmove(&node->tail[curSlot+1],
416
&node->tail[curSlot],
417
sizeof(node->tail[0]) * shift);
418
memmove(&node->present[curSlot+1],
419
&node->present[curSlot],
420
sizeof(node->present[0]) * shift);
421
memmove(&node->childCount[curSlot+1],
422
&node->childCount[curSlot],
423
sizeof(node->childCount[0]) * shift);
424
425
memmove(&node->keys[curSlot+1],
426
&node->keys[curSlot],
427
sizeof(node->keys[0]) * (shift-1));
428
429
memset(node->keys[curSlot], 0, B_MAX_NAME_LENGTH);
430
strncpy(node->keys[curSlot], key, B_MAX_NAME_LENGTH);
431
node->head[curSlot+1].bPtr = headPtr;
432
node->tail[curSlot+1].bPtr = NULL;
433
node->present[curSlot+1] = true;
434
// node->childCount[node->used] = ?;
435
} // else
436
if (++node->used == B_MAX_KEYS) splitNode(node);
437
return;
438
} // bTree::insertNode
439
440
bNode *
441
bTree::allocEmptyNode(void) {
442
bNode * newNode = new bNode;
443
444
memset(newNode, 0, sizeof(bNode));
445
newNode->magic1 = B_NODE_MAGIC_1;
446
newNode->magic2 = B_NODE_MAGIC_2;
447
newNode->parent.bPtr = NULL;
448
newNode->tag = ++tag; // this will start at 1 (0 is the header node)
449
return newNode;
450
} // bTree::allocEmptyNode
451
452
void
453
bTree::Info(const bNode * node) {
454
ubixfsInode * inode = NULL;
455
if (node == NULL || root == NULL) return;
456
cout << node << " | " << node->parent.bPtr << endl;
457
for (unsigned int i = 0; i <= node->used; i++) {
458
inode = node->head[i].iPtr;
459
// cout << "(" << node->childCount[i] << ")";
460
for (unsigned int k = 0; k < node->childCount[i]; k++) {
461
cout << "[" << inode->name << "]";
462
inode = inode->next.iPtr;
463
} // for k
464
if (i != node->used) cout << " {" << node->keys[i] << "} ";
465
} // for i
466
cout << endl;
467
return;
468
#if 0
469
for (unsigned int i = 0; i < node->used; i++) {
470
cout << "keys[" << i << "]: " << node->keys[i] << " ";
471
} // for i
472
cout << endl;
473
cout << "node->used: " << node->used << endl;
474
cout << "leaf: " << node->leaf << endl;
475
for (unsigned int i = 0; i <= node->used; i++) {
476
inode = (ubixfsInode *)node->head[i];
477
cout << "node->childCount["<<i<<"]: " << node->childCount[i] << endl;
478
for (unsigned int j = 0; j < node->childCount[i]; j++) {
479
assert(inode);
480
cout << "[" << i << "].[" << j << "]->" << inode->name << endl;
481
inode = inode->next;
482
} // for j
483
} // for i
484
#endif
485
} // bTree::Info
486
487
void
488
bTree::Info(void) {
489
ubixfsInode * inode = NULL;
490
491
cout << "tree depth: " << header->treeDepth << endl;
492
cout << "tree width: " << header->treeWidth << endl;
493
cout << "tree leaf count: " << header->treeLeafCount << endl;
494
cout << "tag: " << tag << endl;
495
496
if (root == NULL) return;
497
498
for (unsigned int i = 0; i <= root->used; i++) {
499
cout << "CC[" << i << "]: " << root->childCount[i] << " ";
500
} // for i
501
502
cout << endl;
503
for (unsigned int i = 0; i <= root->used; i++) {
504
cout << "CH[" << i << "]: " << root->head[i].bPtr << " ";
505
} // for i
506
507
cout << endl;
508
for (unsigned int i = 0; i <=root->used; i++) {
509
cout << "CT[" << i << "]: " << root->tail[i].bPtr << " ";
510
} // for i
511
cout << endl;
512
for (unsigned int i = 0; i < root->used; i++) {
513
cout << "keys[" << i << "]: " << root->keys[i] << " ";
514
} // for i
515
cout << endl;
516
517
cout << "root->used: " << root->used << endl;
518
for (unsigned int i = 0; i <= root->used; i++) {
519
inode = root->head[i].iPtr;
520
cout << "root->childCount["<<i<<"]: " << root->childCount[i] << endl;
521
if (root->leaf) {
522
cout << "root contains leaf node" << endl;
523
for (unsigned int j = 0; j < root->childCount[i]; j++) {
524
assert(inode);
525
cout << "[" << i << "].[" << j << "]->" << inode->name << endl;
526
inode = inode->next.iPtr;
527
} // for j
528
} // if root->leaf
529
} // for i
530
} // bTree::Info
531
532
void
533
bTree::Print(void) {
534
ubixfsInode * node = GetFirstNode();
535
while (node != NULL) {
536
cout << node->name << endl;
537
node = node->next.iPtr;
538
}
539
} // bTree::Print
540
541
ubixfsInode *
542
bTree::Find(const char * key) {
543
544
*/
/*
545
ubixfsInode * tmp = GetFirstNode();
546
while (tmp!=NULL) {
547
if (strcmp(tmp->name, key) == 0) return tmp;
548
tmp = tmp->next.iPtr;
549
}
550
return NULL;
551
*/
/*
552
return treeSearch(root, key);
553
} // bTree::Find
554
555
ubixfsInode *
556
bTree::inodeSearch(ubixfsInode * inode, const char * key) {
557
if (inode == NULL || key == NULL) return NULL;
558
int result = strcmp(inode->name, key);
559
if (result == 0) return inode;
560
561
if (result < 0) {
562
inode = inode->next.iPtr;
563
while (inode != NULL && ((result = strcmp(inode->name, key)) < 0)) {
564
inode = inode->next.iPtr;
565
} // while
566
} else {
567
inode = inode->prev.iPtr;
568
while (inode != NULL && ((result = strcmp(inode->name, key)) > 0)) {
569
inode = inode->prev.iPtr;
570
} // while
571
} // else
572
return (result == 0 ? inode : NULL);
573
} // bTree::inodeSearch
574
575
ubixfsInode *
576
bTree::treeSearch(bNode * bnode, const char * key) {
577
578
if (bnode == NULL || key == NULL || bnode->used == 0) return NULL;
579
580
if (bnode->leaf)
581
return inodeSearch(GetFirstNode(bnode), key);
582
583
if (strcmp(key, bnode->keys[0]) < 0) {
584
return treeSearch(bnode->head[0].bPtr, key);
585
} // if
586
587
if (strcmp(key, bnode->keys[bnode->used-1]) >= 0) {
588
return treeSearch(bnode->head[bnode->used].bPtr, key);
589
} // if
590
591
for (unsigned int i = 1; i < bnode->used; i++) {
592
if (strcmp(key, bnode->keys[i]) < 0) {
593
return treeSearch(bnode->head[i].bPtr, key);
594
} // if
595
} // for i
596
597
return NULL;
598
} // bTree::treeSearch
599
600
ubixfsInode *
601
bTree::GetFirstNode(void) {
602
return GetFirstNode(root);
603
} // bTree::GetFirstNode
604
605
ubixfsInode *
606
bTree::GetFirstNode(bNode * node) {
607
bNode * tmpNode = node;
608
609
if (tmpNode == NULL) return NULL;
610
611
while (!tmpNode->leaf) {
612
for (unsigned int i = 0; i < tmpNode->used; i++) {
613
if (tmpNode->head[i].bPtr != NULL) {
614
tmpNode = tmpNode->head[i].bPtr;
615
break;
616
} // if
617
} // for i
618
} // while
619
620
for (unsigned int i = 0; i < tmpNode->used; i++) {
621
if (tmpNode->head[i].iPtr != NULL) return tmpNode->head[i].iPtr;
622
} // for i
623
return NULL;
624
} // bTree::GetFirstNode
625
626
bNode *
627
bTree::findLeafNode(bNode * node, const char * key) {
628
assert(node);
629
assert(key);
630
if (node == NULL || key == NULL) return NULL;
631
assert(node->used);
632
if (node->leaf) return node;
633
634
if (strcmp(key, node->keys[0]) < 0)
635
return findLeafNode(node->head[0].bPtr, key);
636
637
if (strcmp(key, node->keys[node->used-1]) >= 0)
638
return findLeafNode(node->head[node->used].bPtr, key);
639
640
for (unsigned int i = 1; i < node->used; i++) {
641
if (strcmp(key, node->keys[i]) < 0)
642
return findLeafNode(node->head[i].bPtr, key);
643
} // for i
644
645
return NULL;
646
} // bTree::findLeafNode
647
648
void
649
bTree::saveNode(FILE * fd, bNode * node, void * tmpPtr) {
650
651
bNode * ptr = (bNode *)tmpPtr;
652
assert(tmpPtr);
653
assert(fd);
654
assert(node);
655
cout << "writing tag: " << node->tag << endl;
656
657
memcpy(tmpPtr, node, sizeof(bNode));
658
659
if (node->parent.bPtr != NULL)
660
ptr->parent.offset = node->parent.bPtr->tag * sizeof(bNode);
661
else
662
ptr->parent.offset = 0;
663
664
for (unsigned int i = 0; i <= node->used; i++) {
665
bNode * bPtr = node->head[i].bPtr;
666
667
if (bPtr != NULL)
668
ptr->head[i].offset = bPtr->tag * sizeof(bNode);
669
else
670
ptr->head[i].offset = ~0;
671
ptr->present[i] = false;
672
} // for i
673
674
if (node->leaf) {
675
676
for (unsigned int i = 0; i <= node->used; i++) {
677
// ubixfsInode * inode = node->head[i].iPtr;
678
// mji if (inode != NULL) tmp->head[i] = inode->
679
} // for i
680
} else {
681
682
for (unsigned int i = 0; i <= node->used; i++) {
683
684
if (node->head[i].bPtr != NULL) saveNode(fd, node->head[i].bPtr, tmpPtr);
685
686
} // for i
687
688
} // else
689
690
return;
691
} // bTree::saveNode
692
693
bool
694
bTree::Save(const char * filename) {
695
ubixfsInode * uPtr = NULL;
696
if (filename == NULL) return false;
697
FILE * fd = NULL;
698
if ((fd = fopen(filename, "wb+")) == NULL) return false;
699
700
cout << "tags: " << tag << endl;
701
lseek(fileno(fd), tag * sizeof(bNode), SEEK_END);
702
703
header->firstNodeOffset = sizeof(bNode);
704
header->firstDeleted = -1;
705
void * tmpPtr = malloc(sizeof(bNode));
706
assert(tmpPtr);
707
uPtr = (ubixfsInode *)tmpPtr;
708
memset(tmpPtr, 0, sizeof(bNode));
709
fwrite(header, sizeof(bTreeHeader), 1, fd);
710
saveNode(fd, root, tmpPtr);
711
712
fclose(fd);
713
free(tmpPtr);
714
return true;
715
} // bTree::Save
716
717
bool
718
bTree::Load(const char * filename) {
719
if (filename == NULL) return false;
720
return true;
721
} // bTree::Load
722
723
bool
724
bTree::Delete(const char * key) {
725
726
if (key == NULL) return false;
727
return true;
728
} // bTree::Delete
729
730
bool
731
bTree::Verify(void) {
732
ubixfsInode * node = GetFirstNode();
733
if (node == NULL) return true;
734
735
while (node != NULL) {
736
ubixfsInode * next = node->next.iPtr;
737
if (next != NULL) {
738
// cout << node->name << "::" << node->next->name << ":::" << strcmp(node->name, node->next->name) << endl;
739
if (strcmp(node->name, next->name) > 0) return false;
740
}
741
node = next;
742
} // while
743
return true;
744
} // bTree::Verify
745
746
void
747
bTree::Print(bNode * node) {
748
if (node == NULL) return;
749
Info(node);
750
if (!node->leaf)
751
for (unsigned int i = 0; i <= node->used; i++) {
752
Print(node->head[i].bPtr);
753
} // for i
754
} // bTree::Print
755
756
void
757
bTree::PrintWholeTree(void) {
758
Print(root);
759
} // bTree::PrintWholeTree;
760
761
bTree::~bTree(void) {
762
cout << "tree depth: " << header->treeDepth << endl;
763
cout << "tree width: " << header->treeWidth << endl;
764
cout << "tree leaf count: " << header->treeLeafCount << endl;
765
} // bTree::~bTree
766
767
*/
C:
Dev
git
UbixOS
sys
fs
ubixfsv2
btree.cpp
Generated by
1.8.16