21
21
#ifndef __BTREE_H__
22
22
#define __BTREE_H__
23
23
24
+ #include < stdio.h>
25
+ #include < iostream>
24
26
#include < stdint.h>
25
27
#include < stdlib.h>
26
28
#include < string.h>
@@ -107,7 +109,6 @@ namespace alg {
107
109
}
108
110
109
111
void DeleteKey (int32_t k) {
110
- node x = m_root;
111
112
delete_op (m_root, k);
112
113
}
113
114
@@ -240,6 +241,7 @@ namespace alg {
240
241
x->key [j] = x->key [j+1 ];
241
242
}
242
243
WRITE (x);
244
+ printf (" case1" );
243
245
return ;
244
246
} else {
245
247
// case 2a:
@@ -249,13 +251,14 @@ namespace alg {
249
251
// (We can find k0 and delete it in a single downward pass.)
250
252
std::auto_ptr<node_t > y (READ (x, i));
251
253
if (y->n >= T) {
254
+ printf (" case2a" );
252
255
int32_t k0 = y->key [y->n -1 ];
253
256
x->key [i] = k0;
254
257
WRITE (x);
255
258
delete_op (y.get (), k0);
256
259
return ;
257
260
}
258
-
261
+
259
262
// case 2b.
260
263
// If y has fewer than t keys, then, symmetrically, examine
261
264
// the child z that follows k in node x. If z has at least t keys,
@@ -264,6 +267,7 @@ namespace alg {
264
267
// and delete it in a single downward pass.)
265
268
std::auto_ptr<node_t > z (READ (x, i+1 ));
266
269
if (z->n >= T) {
270
+ printf (" case2b" );
267
271
int32_t k0 = z->key [0 ];
268
272
x->key [i] = k0;
269
273
WRITE (x);
@@ -277,6 +281,7 @@ namespace alg {
277
281
// pointer to z, and y now contains 2t - 1 keys.
278
282
// Then free z and recursively delete k from y.
279
283
if (y->n == T-1 && z->n == T-1 ) {
284
+ printf (" case2c" );
280
285
// merge k & z into y
281
286
y->key [y->n ] = k;
282
287
@@ -308,6 +313,7 @@ namespace alg {
308
313
delete_op (y.get (), k);
309
314
return ;
310
315
}
316
+ printf (" other in case2" );
311
317
312
318
}
313
319
} else {
@@ -321,15 +327,17 @@ namespace alg {
321
327
// appropriate child pointer from the sibling into x.c[i].
322
328
if (ci->n == T-1 ) {
323
329
std::auto_ptr<node_t > left (READ (x, i-1 ));
324
- if (i-1 >=0 && left->n > T) {
330
+ printf (" case 3a: %d %d\n " , left->n , i-1 );
331
+ if (i-1 >=0 && left->n >= T) {
332
+ printf (" case3a, left" );
325
333
// right shift keys and childs of x.c[i] to make place for a key
326
334
// right shift ci childs
327
335
int j;
328
- for (j=ci->n -1 ;j>0 ;j++ ) {
336
+ for (j=ci->n -1 ;j>0 ;j-- ) {
329
337
ci->key [j] = ci->key [j-1 ];
330
338
}
331
339
332
- for (j=ci->n ;j>0 ;j++ ) {
340
+ for (j=ci->n ;j>0 ;j-- ) {
333
341
ci->c [j] = ci->c [j-1 ];
334
342
}
335
343
ci->n = ci->n +1 ;
@@ -347,7 +355,9 @@ namespace alg {
347
355
348
356
// case 3a. right sibling
349
357
std::auto_ptr<node_t > right (READ (x, i+1 ));
350
- if (i+1 <ci->n && right->n > T) {
358
+ printf (" case 3a-r: %d %d\n " , right->n , i+1 );
359
+ if (i+1 <=x->n && right->n >= T) {
360
+ printf (" case3a, right" );
351
361
ci->key [ci->n ] = x->key [i]; // append key from x
352
362
ci->c [ci->n +1 ] = right->c [0 ]; // append child from right
353
363
ci->n = ci->n +1 ;
@@ -374,63 +384,128 @@ namespace alg {
374
384
// If x.c[i] and both of x.c[i]’s immediate siblings have t-1 keys, merge x.c[i]
375
385
// with one sibling, which involves moving a key from x down into the new
376
386
// merged node to become the median key for that node.
377
- if (left->n == T-1 && right->n == T-1 ) {
378
- // copy x[i] to left
379
- left->key [left->n ] = x->key [i];
380
- left->n = left->n + 1 ;
381
-
382
- // remove key[i] from x and also the child
383
- int j;
384
- for (j=i;j<x->n -1 ;j++) {
385
- x->key [j] = x->key [j+1 ];
386
- }
387
-
388
- for (j=i;j<x->n ;j++) {
389
- x->c [j] = x->c [j+1 ];
387
+ if ((i-1 <0 ||left->n == T-1 ) && (i+1 <=x->n || right->n == T-1 )) {
388
+ std::cerr << " case3b in" ;
389
+ if (left->n == T-1 ) {
390
+ std::cerr<<" case3b, left" ;
391
+ // copy x[i] to left
392
+ left->key [left->n ] = x->key [i];
393
+ left->n = left->n + 1 ;
394
+
395
+ // remove key[i] from x and also the child
396
+ // shrink the size & set the child-0 to left
397
+ int j;
398
+ for (j=i;j<x->n -1 ;j++) {
399
+ x->key [j] = x->key [j+1 ];
400
+ }
401
+
402
+ for (j=i;j<x->n ;j++) {
403
+ x->c [j] = x->c [j+1 ];
404
+ }
405
+ x->n = x->n - 1 ;
406
+ x->c [0 ] = left->offset ;
407
+
408
+ // append x.c[i] into left sibling
409
+ for (j=0 ;j<ci->n ;j++) {
410
+ left->key [left->n + j] = ci->key [j];
411
+ }
412
+
413
+ for (j=0 ;j<ci->n +1 ;j++) {
414
+ left->c [left->n + j] = ci->c [j];
415
+ }
416
+ left->n += ci->n ; // left became 2T-1
417
+ ci->flag |= MARKFREE; // free ci
418
+ WRITE (ci.get ());
419
+ WRITE (x);
420
+
421
+ // root check
422
+ if (x->n == 0 && x == m_root) {
423
+ left->flag |= MARKFREE;
424
+ WRITE (left.get ());
425
+ left->flag &= ~MARKFREE;
426
+ left->offset = 0 ; // set to the first block
427
+ WRITE (left.get ());
428
+ free (m_root);
429
+ m_root = DUP (left.get ());
430
+ } else {
431
+ WRITE (left.get ());
432
+ }
433
+
434
+ delete_op (left.get (), k);
435
+ return ;
436
+ } else if (right->n == T-1 ) {
437
+ std::cerr<<" case3b, right" ;
438
+ // copy x[i] to x.c[i]
439
+ ci->key [x->n ] = x->key [i];
440
+ ci->n = x->n + 1 ;
441
+
442
+ // remove key[i] from x and also the child
443
+ // shrink the size & set the child-0 to ci
444
+ int j;
445
+ for (j=i;j<x->n -1 ;j++) {
446
+ x->key [j] = x->key [j+1 ];
447
+ }
448
+
449
+ for (j=i;j<x->n ;j++) {
450
+ x->c [j] = x->c [j+1 ];
451
+ }
452
+ x->n = x->n - 1 ;
453
+ x->c [0 ] = ci->offset ;
454
+
455
+ // append right sibling into x.c[i]
456
+ for (j=0 ;j<ci->n ;j++) {
457
+ ci->key [ci->n + j] =right->key [j];
458
+ }
459
+
460
+ for (j=0 ;j<ci->n +1 ;j++) {
461
+ ci->c [ci->n + j] = right->c [j];
462
+ }
463
+ ci->n += right->n ; // ci became 2T-1
464
+ right->flag |= MARKFREE; // free right
465
+ WRITE (right.get ());
466
+ WRITE (x);
467
+
468
+ // root check,
469
+ // free the old block , and make root the first block of the file
470
+ if (x->n == 0 && x == m_root) {
471
+ ci->flag |= MARKFREE;
472
+ WRITE (ci.get ());
473
+ ci->flag &= ~MARKFREE;
474
+ ci->offset = 0 ;
475
+ WRITE (ci.get ());
476
+ free (m_root);
477
+ m_root = DUP (ci.get ());
478
+ } else {
479
+ WRITE (ci.get ());
480
+ }
481
+
482
+ delete_op (ci.get (), k);
483
+ return ;
390
484
}
391
-
392
- // point child-0 to left
393
- x->c [0 ] = left->offset ;
394
-
395
- // append x.c[i] into left sibling
396
- for (j=0 ;j<ci->n ;j++) {
397
- left->key [left->n + j] = ci->key [j];
398
- }
399
-
400
- for (j=0 ;j<ci->n +1 ;j++) {
401
- left->c [j+left->n ] = ci->c [j];
402
- }
403
- left->n += ci->n ; // left became 2T-1
404
- ci->flag |= MARKFREE; // free ci
405
- WRITE (ci.get ());
406
- WRITE (x);
407
-
408
- // root check
409
- if (x->n == 0 ) {
410
- m_root = left.get (); // free the old block , and
411
- left->flag |= MARKFREE; // make root the first block of the file
412
- WRITE (left.get ());
413
- left->flag &= ~MARKFREE;
414
- left->offset = 0 ;
415
- }
416
-
417
- WRITE (left.get ());
418
- delete_op (left.get (), k);
419
485
}
420
486
}
421
-
422
- return ;
423
487
}
424
488
}
425
489
426
490
491
+ /* *
492
+ * duplicate the node
493
+ */
494
+ node DUP (node x) {
495
+ void *n = allocate_node ();
496
+ memcpy (n, x, BLOCKSIZE);
497
+ return (node)n;
498
+ }
499
+
427
500
/* *
428
501
* Read a 4K-block from disk, and returns the node struct.
429
502
*/
430
503
node READ (node x, int32_t i) {
431
504
void *xi = allocate_node ();
432
- lseek (fd, x->c [i], SEEK_SET);
433
- read (fd, xi, BLOCKSIZE);
505
+ if (i >=0 || i <= x->n ) {
506
+ lseek (fd, x->c [i], SEEK_SET);
507
+ read (fd, xi, BLOCKSIZE);
508
+ }
434
509
return (node)xi;
435
510
}
436
511
0 commit comments