@@ -434,73 +434,81 @@ static cog_object* _wraptab(cog_object* tree) {
434
434
return tab ;
435
435
}
436
436
437
+ // TODO: use binary search tree instead of binary path tree which is super weird
438
+
437
439
static cog_object * _iou_helper (cog_object * tree , cog_object * key , cog_object * val , int64_t hash ) {
438
440
if (!tree ) {
439
441
// we got to the end without finding a existing node, so add a new one
440
- cog_printf ("DEBUG: New node with %O: %O\n" , key , val );
442
+ // cog_printf("DEBUG: New node with %O: %O\n", key, val);
441
443
return _treenode (key , val , NULL , NULL );
442
444
}
443
- bool is_left = hash & 1 ;
444
- int64_t rest_hash = hash >> 1 ;
445
445
if (cog_equal (tree -> TKEY , key )) {
446
446
// update this node
447
- cog_printf ("DEBUG: Update node with %O: %O\n" , key , val );
447
+ // cog_printf("DEBUG: Update node with %O: %O\n", key, val);
448
448
return _treenode (tree -> TKEY , val , tree -> TRIGHT , tree -> TLEFT );
449
449
}
450
450
// need to recurse
451
- printf ("->%s" , is_left ? "left" : "right" );
452
- fflush (stdout );
453
- cog_object * newnode = _treenode (tree -> TKEY , tree -> TVAL , tree -> TRIGHT , tree -> TLEFT );
454
- if (is_left ) newnode -> TLEFT = _iou_helper (newnode -> TLEFT , key , val , rest_hash );
455
- else newnode -> TRIGHT = _iou_helper (newnode -> TRIGHT , key , val , rest_hash );
456
- return newnode ;
451
+ bool is_left = hash < (cog_hash (tree -> TKEY )-> as_int );
452
+ // printf("->%s", is_left ? "left" : "right");
453
+ // fflush(stdout);
454
+ if (is_left ) return _treenode (tree -> TKEY , tree -> TVAL , _iou_helper (tree -> TLEFT , key , val , hash ), tree -> TRIGHT );
455
+ else return _treenode (tree -> TKEY , tree -> TVAL , tree -> TLEFT , _iou_helper (tree -> TRIGHT , key , val , hash ));
456
+ }
457
+
458
+ static cog_object * _succ (cog_object * tree ) {
459
+ tree = tree -> TRIGHT ;
460
+ while (tree != NULL && tree -> TLEFT != NULL )
461
+ tree = tree -> TLEFT ;
462
+ return tree ;
457
463
}
458
464
459
465
static cog_object * _rem_helper (cog_object * tree , cog_object * key , int64_t hash ) {
460
466
if (!tree ) return NULL ;
461
- bool is_left = hash & 1 ;
462
- int64_t rest_hash = hash >> 1 ;
463
- cog_object * newtree ;
464
467
465
468
if (cog_equal (key , tree -> TKEY )) {
466
469
// this node is what needs to be deleted
467
- if (!tree -> TLEFT && !tree -> TRIGHT ) newtree = NULL ; // leaf node gets deleted
468
- // else just pick which side to delete. I chose right first else left
469
- else if (tree -> TRIGHT ) newtree = _treenode (tree -> TRIGHT -> TKEY , tree -> TRIGHT -> TVAL , tree -> TLEFT , tree -> TRIGHT -> TRIGHT );
470
- else newtree = _treenode (tree -> TLEFT -> TKEY , tree -> TLEFT -> TVAL , tree -> TLEFT -> TLEFT , tree -> TRIGHT );
470
+ // No children
471
+ if (!tree -> TLEFT && !tree -> TRIGHT ) return NULL ;
472
+ // if only one child, then just become that one
473
+ else if (tree -> TRIGHT && !tree -> TLEFT ) return tree -> TRIGHT ;
474
+ else if (tree -> TLEFT && !tree -> TRIGHT ) return tree -> TLEFT ;
475
+ else {
476
+ // two children
477
+ cog_object * next = _succ (tree );
478
+ return _treenode (next -> TKEY , next -> TVAL , tree -> TLEFT , _rem_helper (tree -> TRIGHT , next -> TKEY , cog_hash (next -> TKEY )-> as_int ));
479
+ }
471
480
} else {
472
481
// it's another node that needs to be deleted
473
- if (is_left ) newtree = _treenode (tree -> TKEY , tree -> TVAL , _rem_helper (tree -> TLEFT , key , rest_hash ), tree -> TRIGHT );
474
- else newtree = _treenode (tree -> TKEY , tree -> TVAL , tree -> TLEFT , _rem_helper (tree -> TRIGHT , key , rest_hash ));
482
+ bool is_left = hash < (cog_hash (tree -> TKEY )-> as_int );
483
+ if (is_left ) return _treenode (tree -> TKEY , tree -> TVAL , _rem_helper (tree -> TLEFT , key , hash ), tree -> TRIGHT );
484
+ else return _treenode (tree -> TKEY , tree -> TVAL , tree -> TLEFT , _rem_helper (tree -> TRIGHT , key , hash ));
475
485
}
476
- return newtree ;
477
486
}
478
487
479
488
cog_object * cog_table_get (cog_object * tab , cog_object * key , bool * found ) {
480
489
assert (tab && tab -> type == & cog_ot_table );
481
490
cog_object * tree = tab -> next ; // get the internal tree
482
491
int64_t hash = cog_hash (key )-> as_int ;
483
- cog_printf ("DEBUG: getting with hash %llX, tree is: %O\n" , hash , tree );
492
+ // cog_printf("DEBUG: getting with hash %llX, tree is: %O\n", hash, tree);
484
493
while (tree ) {
485
- cog_printf ("DEBUG: looking at key %O\n" , tree -> TKEY );
494
+ // cog_printf("DEBUG: looking at key %O\n", tree->TKEY);
486
495
if (cog_equal (tree -> TKEY , key )) {
487
496
* found = true;
488
497
return tree -> TVAL ;
489
498
}
490
- bool is_left = hash & 1 ;
491
- hash = hash >> 1 ;
499
+ bool is_left = hash < (cog_hash (tree -> TKEY )-> as_int );
492
500
if (is_left ) tree = tree -> TLEFT ;
493
501
else tree = tree -> TRIGHT ;
494
- printf ("%s->" , is_left ? "left" : "right" );
495
- fflush (stdout );
502
+ // printf("%s->", is_left ? "left" : "right");
503
+ // fflush(stdout);
496
504
}
497
505
* found = false;
498
506
return NULL ;
499
507
}
500
508
501
509
cog_object * cog_table_insert_or_update (cog_object * tab , cog_object * key , cog_object * val ) {
502
510
assert (tab && tab -> type == & cog_ot_table );
503
- cog_printf ("DEBUG: adding key %O to table\n" , key );
511
+ // cog_printf("DEBUG: adding key %O to table\n", key);
504
512
return _wraptab (_iou_helper (tab -> next , key , val , cog_hash (key )-> as_int ));
505
513
}
506
514
0 commit comments