@@ -73,7 +73,7 @@ namespace alg {
73
73
fd = open (path, O_RDWR|O_CREAT, 0640 );
74
74
if (fd == -1 )
75
75
return ;
76
- node x = (node)allocate_node ();
76
+ node x = (node)ALLOCBLK ();
77
77
int n = read (fd,x,BLOCKSIZE);
78
78
if (n != BLOCKSIZE) { // init new btree
79
79
x->flag |= LEAF;
@@ -97,7 +97,7 @@ namespace alg {
97
97
r->flag &= ~ONDISK;
98
98
WRITE (r);
99
99
// new root
100
- node s = (node)allocate_node ();
100
+ node s = (node)ALLOCBLK ();
101
101
s->flag &= ~LEAF;
102
102
s->flag |= ONDISK; // write to offset 0
103
103
s->offset = 0 ;
@@ -143,9 +143,9 @@ namespace alg {
143
143
*/
144
144
void insert_nonfull (node x, int32_t k) {
145
145
int32_t i = x->n -1 ;
146
- if (x->flag & LEAF) { // insert into leaf
147
- while (i>=0 && k < x->key [i]) { // shift from right to left, when k < key[i]
148
- x->key [i+1 ] = x->key [i];
146
+ if (x->flag & LEAF) { // insert into this leaf
147
+ while (i>=0 && k < x->key [i]) { // right shift to
148
+ x->key [i+1 ] = x->key [i]; // make place for k
149
149
i = i - 1 ;
150
150
}
151
151
x->key [i+1 ] = k;
@@ -156,38 +156,26 @@ namespace alg {
156
156
i = i-1 ;
157
157
}
158
158
i=i+1 ;
159
- node xi = READ (x, i);
159
+ node xi = READ (x, i); // insert the key into one child.
160
160
if (xi->n == 2 *T-1 ) {
161
161
split_child (x, i);
162
162
if (k > x->key [i]) {
163
163
i = i+1 ;
164
164
}
165
- // reload x[i] after split_child(will modify child x[i])
165
+ // NOTICE!
166
+ // reload x[i] after split_child.
166
167
xi = READ (x, i);
167
168
}
168
169
insert_nonfull (xi, k);
169
170
delete xi;
170
171
}
171
172
}
172
173
173
- /* *
174
- * allocate empty node struct
175
- */
176
- void * allocate_node () {
177
- node x = new node_t ;
178
- x->n = 0 ;
179
- x->offset = 0 ;
180
- x->flag = 0 ;
181
- memset (x->key , 0 , sizeof (x->key ));
182
- memset (x->c , 0 , sizeof (x->c ));
183
- return x;
184
- }
185
-
186
174
/* *
187
175
* split a node into 2.
188
176
*/
189
177
void split_child (node x, int32_t i) {
190
- std::auto_ptr<node_t > z ((node)allocate_node ());
178
+ std::auto_ptr<node_t > z ((node)ALLOCBLK ());
191
179
std::auto_ptr<node_t > y (READ (x, i));
192
180
z->flag &= ~LEAF;
193
181
z->flag |= (y->flag & LEAF);
@@ -258,11 +246,13 @@ namespace alg {
258
246
}
259
247
}
260
248
249
+ /* *
250
+ * case 1.
251
+ * If the key k is in node x and x is a leaf, delete the key k from x.
252
+ */
261
253
void case1 (node x, int32_t i, int32_t k) {
262
- // case 1.
263
- // If the key k is in node x and x is a leaf, delete the key k from x.
264
254
int j;
265
- for (j = i;j<x->n -1 ;j++) { // shifting the keys.
255
+ for (j = i;j<x->n -1 ;j++) { // shifting the keys only, no childs available .
266
256
x->key [j] = x->key [j+1 ];
267
257
}
268
258
x->n = x->n - 1 ;
@@ -346,138 +336,139 @@ namespace alg {
346
336
347
337
void case3 (node x, int32_t i, int32_t k) {
348
338
std::auto_ptr<node_t > ci (READ (x, i));
339
+ if (ci->n > T-1 ) { // ready to delete in child.
340
+ delete_op (ci.get (), k);
341
+ return ;
342
+ }
343
+
349
344
// case 3a.
350
345
// If x.c[i] has only t - 1 keys but has an immediate sibling with at least t keys,
351
346
// give x.c[i] an extra key by moving a key from x down into x.c[i], moving a
352
347
// key from x.c[i]’s immediate left or right sibling up into x, and moving the
353
348
// appropriate child pointer from the sibling into x.c[i].
354
- if (ci->n == T-1 ) {
355
- std::auto_ptr<node_t > left (READ (x, i-1 ));
356
- if (i-1 >=0 && left->n >= T) {
357
- // printf("case3a, left");
358
- // right shift keys and childs of x.c[i] to make place for a key
359
- // right shift ci childs
349
+ std::auto_ptr<node_t > left (READ (x, i-1 ));
350
+ if (i-1 >=0 && left->n >= T) {
351
+ // printf("case3a, left");
352
+ // right shift keys and childs of x.c[i] to make place for a key
353
+ // right shift ci childs
354
+ int j;
355
+ for (j=ci->n -1 ;j>0 ;j--) {
356
+ ci->key [j] = ci->key [j-1 ];
357
+ }
358
+
359
+ for (j=ci->n ;j>0 ;j--) {
360
+ ci->c [j] = ci->c [j-1 ];
361
+ }
362
+ ci->n = ci->n +1 ;
363
+ ci->key [0 ] = x->key [i-1 ]; // copy key from x[i-1] to ci[0]
364
+ ci->c [0 ] = left->c [left->n ]; // copy child from left last child.
365
+ x->key [i] = left->key [left->n -1 ]; // copy left last key into x[i]
366
+ left->n = left->n -1 ; // decrease left size
367
+
368
+ WRITE (ci.get ());
369
+ WRITE (x);
370
+ WRITE (left.get ());
371
+ delete_op (ci.get (), k);
372
+ return ;
373
+ }
374
+
375
+ // case 3a. right sibling
376
+ std::auto_ptr<node_t > right (READ (x, i+1 ));
377
+ if (i+1 <=x->n && right->n >= T) {
378
+ // printf("case3a, right");
379
+ ci->key [ci->n ] = x->key [i]; // append key from x
380
+ ci->c [ci->n +1 ] = right->c [0 ]; // append child from right
381
+ ci->n = ci->n +1 ;
382
+ x->key [i] = right->key [0 ]; // subsitute key in x
383
+
384
+ int j;
385
+ for (j=0 ;j<right->n -1 ;j++) { // remove key[0] from right sibling
386
+ right->key [j] = right->key [j+1 ];
387
+ }
388
+
389
+ for (j=0 ;j<right->n ;j++) { // and also the child c[0] of the right sibling.
390
+ right->c [j] = right->c [j+1 ];
391
+ }
392
+ right->n = right->n - 1 ; // reduce the size of the right sibling.
393
+
394
+ WRITE (ci.get ());
395
+ WRITE (x);
396
+ WRITE (right.get ());
397
+ delete_op (ci.get (), k); // recursive delete key in x.c[i]
398
+ return ;
399
+ }
400
+
401
+ // case 3b.
402
+ // If x.c[i] and both of x.c[i]’s immediate siblings have t-1 keys, merge x.c[i]
403
+ // with one sibling, which involves moving a key from x down into the new
404
+ // merged node to become the median key for that node.
405
+ if ((i-1 <0 ||left->n == T-1 ) && (i+1 <=x->n || right->n == T-1 )) {
406
+ if (left->n == T-1 ) {
407
+ // copy x[i] to left
408
+ left->key [left->n ] = x->key [i];
409
+ left->n = left->n + 1 ;
410
+
411
+ // remove key[i] from x and also the child
412
+ // shrink the size & set the child-0 to left
413
+ delete_i (x, i);
414
+
360
415
int j;
361
- for (j=ci->n -1 ;j>0 ;j--) {
362
- ci->key [j] = ci->key [j-1 ];
416
+ // append x.c[i] into left sibling
417
+ for (j=0 ;j<ci->n ;j++) {
418
+ left->key [left->n + j] = ci->key [j];
363
419
}
364
420
365
- for (j=ci->n ;j> 0 ;j-- ) {
366
- ci ->c [j] = ci->c [j- 1 ];
421
+ for (j=0 ;j< ci->n + 1 ;j++ ) {
422
+ left ->c [left-> n + j] = ci->c [j];
367
423
}
368
- ci->n = ci->n +1 ;
369
- ci->key [0 ] = x->key [i-1 ]; // copy key from x[i-1] to ci[0]
370
- ci->c [0 ] = left->c [left->n ]; // copy child from left last child.
371
- x->key [i] = left->key [left->n -1 ]; // copy left last key into x[i]
372
- left->n = left->n -1 ; // decrease left size
373
-
424
+ left->n += ci->n ; // left became 2T-1
425
+ ci->flag |= MARKFREE; // free ci
426
+ ci->n = 0 ;
374
427
WRITE (ci.get ());
375
428
WRITE (x);
429
+ // root check
430
+ if (x->n == 0 && x->offset ==0 ) {
431
+ left->flag |= MARKFREE;
432
+ WRITE (left.get ());
433
+ left->flag &= ~MARKFREE;
434
+ left->offset = 0 ;
435
+ }
376
436
WRITE (left.get ());
377
- delete_op (ci .get (), k);
437
+ delete_op (left .get (), k);
378
438
return ;
379
- }
380
-
381
- // case 3a. right sibling
382
- std::auto_ptr<node_t > right (READ (x, i+1 ));
383
- if (i+1 <=x->n && right->n >= T) {
384
- // printf("case3a, right");
385
- ci->key [ci->n ] = x->key [i]; // append key from x
386
- ci->c [ci->n +1 ] = right->c [0 ]; // append child from right
387
- ci->n = ci->n +1 ;
388
- x->key [i] = right->key [0 ]; // subsitute key in x
439
+ } else if (right->n == T-1 ) {
440
+ // copy x[i] to x.c[i]
441
+ ci->key [ci->n ] = x->key [i];
442
+ ci->n = ci->n + 1 ;
443
+ // remove key[i] from x and also the child
444
+ // shrink the size & set the child-0 to ci
445
+ delete_i (x, i);
389
446
390
447
int j;
391
- for (j=0 ;j<right->n -1 ;j++) { // remove key[0] from right sibling
392
- right->key [j] = right->key [j+1 ];
448
+ // append right sibling into x.c[i]
449
+ for (j=0 ;j<right->n ;j++) {
450
+ ci->key [ci->n + j] = right->key [j];
393
451
}
394
452
395
- for (j=0 ;j<right->n ;j++) { // and also the child c[0] of the right sibling.
396
- right ->c [j] = right->c [j+ 1 ];
453
+ for (j=0 ;j<right->n + 1 ;j++) {
454
+ ci ->c [ci-> n + j] = right->c [j];
397
455
}
398
- right->n = right->n - 1 ; // reduce the size of the right sibling.
399
-
400
- WRITE (ci.get ());
401
- WRITE (x);
456
+ ci->n += right->n ; // ci became 2T-1
457
+ right->flag |= MARKFREE; // free right
458
+ right->n = 0 ;
402
459
WRITE (right.get ());
403
- delete_op (ci.get (), k); // recursive delete key in x.c[i]
404
- return ;
405
- }
406
-
407
- // case 3b.
408
- // If x.c[i] and both of x.c[i]’s immediate siblings have t-1 keys, merge x.c[i]
409
- // with one sibling, which involves moving a key from x down into the new
410
- // merged node to become the median key for that node.
411
- if ((i-1 <0 ||left->n == T-1 ) && (i+1 <=x->n || right->n == T-1 )) {
412
- if (left->n == T-1 ) {
413
- // copy x[i] to left
414
- left->key [left->n ] = x->key [i];
415
- left->n = left->n + 1 ;
416
-
417
- // remove key[i] from x and also the child
418
- // shrink the size & set the child-0 to left
419
- delete_i (x, i);
420
-
421
- int j;
422
- // append x.c[i] into left sibling
423
- for (j=0 ;j<ci->n ;j++) {
424
- left->key [left->n + j] = ci->key [j];
425
- }
426
-
427
- for (j=0 ;j<ci->n +1 ;j++) {
428
- left->c [left->n + j] = ci->c [j];
429
- }
430
- left->n += ci->n ; // left became 2T-1
431
- ci->flag |= MARKFREE; // free ci
432
- ci->n = 0 ;
433
- WRITE (ci.get ());
434
- WRITE (x);
435
- // root check
436
- if (x->n == 0 && x->offset ==0 ) {
437
- left->flag |= MARKFREE;
438
- WRITE (left.get ());
439
- left->flag &= ~MARKFREE;
440
- left->offset = 0 ;
441
- }
442
- WRITE (left.get ());
443
- delete_op (left.get (), k);
444
- return ;
445
- } else if (right->n == T-1 ) {
446
- // copy x[i] to x.c[i]
447
- ci->key [ci->n ] = x->key [i];
448
- ci->n = ci->n + 1 ;
449
- // remove key[i] from x and also the child
450
- // shrink the size & set the child-0 to ci
451
- delete_i (x, i);
452
-
453
- int j;
454
- // append right sibling into x.c[i]
455
- for (j=0 ;j<right->n ;j++) {
456
- ci->key [ci->n + j] = right->key [j];
457
- }
458
-
459
- for (j=0 ;j<right->n +1 ;j++) {
460
- ci->c [ci->n + j] = right->c [j];
461
- }
462
- ci->n += right->n ; // ci became 2T-1
463
- right->flag |= MARKFREE; // free right
464
- right->n = 0 ;
465
- WRITE (right.get ());
466
- WRITE (x);
467
- // root check
468
- if (x->n == 0 && x->offset ==0 ) {
469
- ci->flag |= MARKFREE;
470
- WRITE (ci.get ());
471
- ci->flag &= ~MARKFREE;
472
- ci->offset = 0 ;
473
- }
460
+ WRITE (x);
461
+ // root check
462
+ if (x->n == 0 && x->offset ==0 ) {
463
+ ci->flag |= MARKFREE;
474
464
WRITE (ci.get ());
475
- delete_op (ci. get (), k) ;
476
- return ;
465
+ ci-> flag &= ~MARKFREE ;
466
+ ci-> offset = 0 ;
477
467
}
468
+ WRITE (ci.get ());
469
+ delete_op (ci.get (), k);
470
+ return ;
478
471
}
479
- } else {
480
- delete_op (ci.get (), k);
481
472
}
482
473
}
483
474
@@ -496,11 +487,23 @@ namespace alg {
496
487
x->n = x->n - 1 ;
497
488
}
498
489
490
+ /* *
491
+ * allocate empty node struct
492
+ */
493
+ void * ALLOCBLK () {
494
+ node x = new node_t ;
495
+ x->n = 0 ;
496
+ x->offset = 0 ;
497
+ x->flag = 0 ;
498
+ memset (x->key , 0 , sizeof (x->key ));
499
+ memset (x->c , 0 , sizeof (x->c ));
500
+ return x;
501
+ }
499
502
/* *
500
503
* Load the root block
501
504
*/
502
505
node ROOT () {
503
- void *root = allocate_node ();
506
+ void *root = ALLOCBLK ();
504
507
lseek (fd, 0 , SEEK_SET);
505
508
read (fd, root, BLOCKSIZE);
506
509
return (node)root;
@@ -510,7 +513,7 @@ namespace alg {
510
513
* Read a 4K-block from disk, and returns the node struct.
511
514
*/
512
515
node READ (node x, int32_t i) {
513
- void *xi = allocate_node ();
516
+ void *xi = ALLOCBLK ();
514
517
if (i >=0 && i <= x->n ) {
515
518
lseek (fd, x->c [i], SEEK_SET);
516
519
read (fd, xi, BLOCKSIZE);
0 commit comments