@@ -73,7 +73,7 @@ namespace alg {
7373fd = open (path, O_RDWR|O_CREAT, 0640 );
7474if (fd == -1 )
7575return ;
76- node x = (node)allocate_node ();
76+ node x = (node)ALLOCBLK ();
7777int n = read (fd,x,BLOCKSIZE);
7878if (n != BLOCKSIZE) {// init new btree
7979x->flag |= LEAF;
@@ -97,7 +97,7 @@ namespace alg {
9797r->flag &= ~ONDISK;
9898WRITE (r);
9999// new root
100- node s = (node)allocate_node ();
100+ node s = (node)ALLOCBLK ();
101101s->flag &= ~LEAF;
102102s->flag |= ONDISK;// write to offset 0
103103s->offset = 0 ;
@@ -143,9 +143,9 @@ namespace alg {
143143 */
144144void insert_nonfull (node x, int32_t k) {
145145int32_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
149149i = i - 1 ;
150150}
151151x->key [i+1 ] = k;
@@ -156,38 +156,26 @@ namespace alg {
156156i = i-1 ;
157157}
158158i=i+1 ;
159- node xi = READ (x, i);
159+ node xi = READ (x, i);// insert the key into one child.
160160if (xi->n == 2 *T-1 ) {
161161split_child (x, i);
162162if (k > x->key [i]) {
163163i = i+1 ;
164164}
165- // reload x[i] after split_child(will modify child x[i])
165+ // NOTICE!
166+ // reload x[i] after split_child.
166167xi = READ (x, i);
167168}
168169insert_nonfull (xi, k);
169170delete xi;
170171}
171172}
172173
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-
186174/* *
187175 * split a node into 2.
188176 */
189177void 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 ());
191179std::auto_ptr<node_t > y (READ (x, i));
192180z->flag &= ~LEAF;
193181z->flag |= (y->flag & LEAF);
@@ -258,11 +246,13 @@ namespace alg {
258246}
259247}
260248
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+ */
261253void 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.
264254int 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 .
266256x->key [j] = x->key [j+1 ];
267257}
268258x->n = x->n - 1 ;
@@ -346,138 +336,139 @@ namespace alg {
346336
347337void case3 (node x, int32_t i, int32_t k) {
348338std::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+
349344// case 3a.
350345// If x.c[i] has only t - 1 keys but has an immediate sibling with at least t keys,
351346// give x.c[i] an extra key by moving a key from x down into x.c[i], moving a
352347// key from x.c[i]’s immediate left or right sibling up into x, and moving the
353348// 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+
360415int 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];
363419}
364420
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];
367423}
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 ;
374427WRITE (ci.get ());
375428WRITE (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+ }
376436WRITE (left.get ());
377- delete_op (ci .get (), k);
437+ delete_op (left .get (), k);
378438return ;
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);
389446
390447int 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];
393451}
394452
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];
397455}
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 ;
402459WRITE (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;
474464WRITE (ci.get ());
475- delete_op (ci. get (), k) ;
476- return ;
465+ ci-> flag &= ~MARKFREE ;
466+ ci-> offset = 0 ;
477467}
468+ WRITE (ci.get ());
469+ delete_op (ci.get (), k);
470+ return ;
478471}
479- } else {
480- delete_op (ci.get (), k);
481472}
482473}
483474
@@ -496,11 +487,23 @@ namespace alg {
496487x->n = x->n - 1 ;
497488}
498489
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+ }
499502/* *
500503 * Load the root block
501504 */
502505node ROOT () {
503- void *root = allocate_node ();
506+ void *root = ALLOCBLK ();
504507lseek (fd, 0 , SEEK_SET);
505508read (fd, root, BLOCKSIZE);
506509return (node)root;
@@ -510,7 +513,7 @@ namespace alg {
510513 * Read a 4K-block from disk, and returns the node struct.
511514 */
512515node READ (node x, int32_t i) {
513- void *xi = allocate_node ();
516+ void *xi = ALLOCBLK ();
514517if (i >=0 && i <= x->n ) {
515518lseek (fd, x->c [i], SEEK_SET);
516519read (fd, xi, BLOCKSIZE);
0 commit comments