diff --git a/html/hb__tree_8c.html b/html/hb__tree_8c.html index 2586eb0..cf4bd96 100644 --- a/html/hb__tree_8c.html +++ b/html/hb__tree_8c.html @@ -356,7 +356,7 @@

-

Definition at line 604 of file hb_tree.c.

+

Definition at line 603 of file hb_tree.c.

Here is the call graph for this function:
@@ -426,7 +426,7 @@

-

Definition at line 652 of file hb_tree.c.

+

Definition at line 651 of file hb_tree.c.

Here is the call graph for this function:
@@ -456,7 +456,7 @@

-

Definition at line 654 of file hb_tree.c.

+

Definition at line 653 of file hb_tree.c.

Here is the call graph for this function:
@@ -486,7 +486,7 @@

-

Definition at line 645 of file hb_tree.c.

+

Definition at line 644 of file hb_tree.c.

Here is the call graph for this function:
@@ -518,7 +518,7 @@

-

Definition at line 617 of file hb_tree.c.

+

Definition at line 616 of file hb_tree.c.

Here is the call graph for this function:
@@ -548,7 +548,7 @@

-

Definition at line 619 of file hb_tree.c.

+

Definition at line 618 of file hb_tree.c.

Here is the call graph for this function:
@@ -578,7 +578,7 @@

-

Definition at line 653 of file hb_tree.c.

+

Definition at line 652 of file hb_tree.c.

Here is the call graph for this function:
@@ -608,7 +608,7 @@

-

Definition at line 646 of file hb_tree.c.

+

Definition at line 645 of file hb_tree.c.

Here is the call graph for this function:
@@ -640,7 +640,7 @@

-

Definition at line 593 of file hb_tree.c.

+

Definition at line 592 of file hb_tree.c.

@@ -660,7 +660,7 @@

-

Definition at line 621 of file hb_tree.c.

+

Definition at line 620 of file hb_tree.c.

@@ -690,7 +690,7 @@

-

Definition at line 633 of file hb_tree.c.

+

Definition at line 632 of file hb_tree.c.

@@ -710,7 +710,7 @@

-

Definition at line 627 of file hb_tree.c.

+

Definition at line 626 of file hb_tree.c.

@@ -740,7 +740,7 @@

-

Definition at line 639 of file hb_tree.c.

+

Definition at line 638 of file hb_tree.c.

@@ -760,7 +760,7 @@

-

Definition at line 657 of file hb_tree.c.

+

Definition at line 656 of file hb_tree.c.

@@ -790,7 +790,7 @@

-

Definition at line 647 of file hb_tree.c.

+

Definition at line 646 of file hb_tree.c.

Here is the call graph for this function:
@@ -832,7 +832,7 @@

-

Definition at line 650 of file hb_tree.c.

+

Definition at line 649 of file hb_tree.c.

Here is the call graph for this function:
@@ -874,7 +874,7 @@

-

Definition at line 651 of file hb_tree.c.

+

Definition at line 650 of file hb_tree.c.

Here is the call graph for this function:
@@ -916,7 +916,7 @@

-

Definition at line 648 of file hb_tree.c.

+

Definition at line 647 of file hb_tree.c.

Here is the call graph for this function:
@@ -958,7 +958,7 @@

-

Definition at line 649 of file hb_tree.c.

+

Definition at line 648 of file hb_tree.c.

Here is the call graph for this function:
@@ -990,7 +990,7 @@

-

Definition at line 618 of file hb_tree.c.

+

Definition at line 617 of file hb_tree.c.

Here is the call graph for this function:
@@ -1050,7 +1050,7 @@

-

Definition at line 495 of file hb_tree.c.

+

Definition at line 494 of file hb_tree.c.

Here is the call graph for this function:
@@ -1150,7 +1150,7 @@

-

Definition at line 497 of file hb_tree.c.

+

Definition at line 496 of file hb_tree.c.

Here is the call graph for this function:
@@ -1180,7 +1180,7 @@

-

Definition at line 496 of file hb_tree.c.

+

Definition at line 495 of file hb_tree.c.

Here is the call graph for this function:
@@ -1240,7 +1240,7 @@

-

Definition at line 451 of file hb_tree.c.

+

Definition at line 450 of file hb_tree.c.

Here is the call graph for this function:
@@ -1502,7 +1502,7 @@

-

Definition at line 468 of file hb_tree.c.

+

Definition at line 467 of file hb_tree.c.

Here is the call graph for this function:
@@ -1534,7 +1534,7 @@

-

Definition at line 498 of file hb_tree.c.

+

Definition at line 497 of file hb_tree.c.

Here is the call graph for this function:
@@ -1580,7 +1580,7 @@

-

Definition at line 462 of file hb_tree.c.

+

Definition at line 461 of file hb_tree.c.

Here is the call graph for this function:
@@ -1615,7 +1615,7 @@

-

Definition at line 584 of file hb_tree.c.

+

Definition at line 583 of file hb_tree.c.

diff --git a/html/hb__tree_8c_source.html b/html/hb__tree_8c_source.html index 8e7f35e..dcf261e 100644 --- a/html/hb__tree_8c_source.html +++ b/html/hb__tree_8c_source.html @@ -501,288 +501,287 @@
401 rotate_rl(tree, p);
402 } else {
403 rotations += 1;
-
404 if (rotate_l(tree, p))
-
405 break;
-
406 }
-
407 node = PARENT(p);
-
408 } else if (BAL_NEG(p)) { /* else if p->balance == -1 */
-
409 p->bal &= ~BAL_MASK; /* p->balance <- 0 */
-
410 node = p;
-
411 } else { /* else, p->balance == 0 */
-
412 ASSERT((p->bal & BAL_MASK) == 0);
-
413 p->bal |= 1; /* p->balance <- +1 */
-
414 break;
-
415 }
-
416 } else {
-
417 ASSERT(p->rlink == node);
-
418 if (BAL_NEG(p)) { /* if p->balance == -1 */
-
419 if (BAL_POS(p->llink)) { /* if p->llink->balance == +1 */
-
420 rotations += 2;
-
421 rotate_lr(tree, p);
-
422 } else {
-
423 rotations += 1;
-
424 if (rotate_r(tree, p))
-
425 break;
-
426 }
-
427 node = PARENT(p);
-
428 } else if (BAL_POS(p)) { /* else if p->balance == +1 */
-
429 p->bal &= ~BAL_MASK; /* p->balance <- 0 */
-
430 node = p;
-
431 } else { /* else, p->balance == 0 */
-
432 ASSERT((p->bal & BAL_MASK) == 0);
-
433 p->bal |= 2; /* p->balance <- -1 */
-
434 break;
-
435 }
-
436 }
-
437
-
438 if (!(p = PARENT(node)))
-
439 break;
-
440 if (p->llink == node) {
-
441 left = true;
-
442 } else {
-
443 ASSERT(p->rlink == node);
-
444 left = false;
-
445 }
-
446 }
-
447 tree->rotation_count += rotations;
-
448}
-
449
- -
-
451hb_tree_remove(hb_tree* tree, const void* key)
-
452{
-
453 hb_node* node = tree_search_node(tree, key);
-
454 if (!node)
-
455 return (dict_remove_result) { NULL, NULL, false };
-
456 const dict_remove_result result = { node->key, node->datum, true };
-
457 remove_node(tree, node);
-
458 return result;
-
459}
+
404 if (rotate_l(tree, p)) break;
+
405 }
+
406 node = PARENT(p);
+
407 } else if (BAL_NEG(p)) { /* else if p->balance == -1 */
+
408 p->bal &= ~BAL_MASK; /* p->balance <- 0 */
+
409 node = p;
+
410 } else { /* else, p->balance == 0 */
+
411 ASSERT((p->bal & BAL_MASK) == 0);
+
412 p->bal |= 1; /* p->balance <- +1 */
+
413 break;
+
414 }
+
415 } else {
+
416 ASSERT(p->rlink == node);
+
417 if (BAL_NEG(p)) { /* if p->balance == -1 */
+
418 if (BAL_POS(p->llink)) { /* if p->llink->balance == +1 */
+
419 rotations += 2;
+
420 rotate_lr(tree, p);
+
421 } else {
+
422 rotations += 1;
+
423 if (rotate_r(tree, p))
+
424 break;
+
425 }
+
426 node = PARENT(p);
+
427 } else if (BAL_POS(p)) { /* else if p->balance == +1 */
+
428 p->bal &= ~BAL_MASK; /* p->balance <- 0 */
+
429 node = p;
+
430 } else { /* else, p->balance == 0 */
+
431 ASSERT((p->bal & BAL_MASK) == 0);
+
432 p->bal |= 2; /* p->balance <- -1 */
+
433 break;
+
434 }
+
435 }
+
436
+
437 if (!(p = PARENT(node)))
+
438 break;
+
439 if (p->llink == node) {
+
440 left = true;
+
441 } else {
+
442 ASSERT(p->rlink == node);
+
443 left = false;
+
444 }
+
445 }
+
446 tree->rotation_count += rotations;
+
447}
+
448
+ +
+
450hb_tree_remove(hb_tree* tree, const void* key)
+
451{
+
452 hb_node* node = tree_search_node(tree, key);
+
453 if (!node)
+
454 return (dict_remove_result) { NULL, NULL, false };
+
455 const dict_remove_result result = { node->key, node->datum, true };
+
456 remove_node(tree, node);
+
457 return result;
+
458}
-
460
-
461size_t
-
- -
463{
-
464 return tree_traverse(tree, visit, user_data);
-
465}
+
459
+
460size_t
+
+ +
462{
+
463 return tree_traverse(tree, visit, user_data);
+
464}
-
466
-
467bool
-
-
468hb_tree_select(hb_tree *tree, size_t n, const void **key, void **datum)
-
469{
-
470 if (n >= tree->count) {
-
471 if (key)
-
472 *key = NULL;
-
473 if (datum)
-
474 *datum = NULL;
-
475 return false;
-
476 }
-
477 hb_node* node;
-
478 if (n >= tree->count / 2) {
-
479 node = tree_node_max(tree->root);
-
480 n = tree->count - 1 - n;
-
481 while (n--)
-
482 node = node_prev(node);
-
483 } else {
-
484 node = tree_node_min(tree->root);
-
485 while (n--)
-
486 node = node_next(node);
-
487 }
-
488 if (key)
-
489 *key = node->key;
-
490 if (datum)
-
491 *datum = node->datum;
-
492 return true;
-
493}
+
465
+
466bool
+
+
467hb_tree_select(hb_tree *tree, size_t n, const void **key, void **datum)
+
468{
+
469 if (n >= tree->count) {
+
470 if (key)
+
471 *key = NULL;
+
472 if (datum)
+
473 *datum = NULL;
+
474 return false;
+
475 }
+
476 hb_node* node;
+
477 if (n >= tree->count / 2) {
+
478 node = tree_node_max(tree->root);
+
479 n = tree->count - 1 - n;
+
480 while (n--)
+
481 node = node_prev(node);
+
482 } else {
+
483 node = tree_node_min(tree->root);
+
484 while (n--)
+
485 node = node_next(node);
+
486 }
+
487 if (key)
+
488 *key = node->key;
+
489 if (datum)
+
490 *datum = node->datum;
+
491 return true;
+
492}
-
494
-
495size_t hb_tree_count(const hb_tree* tree) { return tree_count(tree); }
- - - -
499
-
500static hb_node*
-
501node_new(void* key)
-
502{
-
503 hb_node* node = MALLOC(sizeof(*node));
-
504 if (node) {
-
505 ASSERT((((intptr_t)node) & 3) == 0); /* Ensure malloc returns aligned result. */
-
506 node->key = key;
-
507 node->datum = NULL;
-
508 node->bal = 0; /* also initializes parent to NULL */
-
509 node->llink = NULL;
-
510 node->rlink = NULL;
-
511 }
-
512 return node;
-
513}
-
514
-
515static hb_node*
-
516node_prev(hb_node* node)
-
517{
-
518 if (node->llink)
-
519 return tree_node_max(node->llink);
-
520 hb_node* parent = PARENT(node);
-
521 while (parent && parent->llink == node) {
-
522 node = parent;
-
523 parent = PARENT(parent);
-
524 }
-
525 return parent;
-
526}
-
527
-
528static hb_node*
-
529node_next(hb_node* node)
-
530{
-
531 if (node->rlink)
-
532 return tree_node_min(node->rlink);
-
533 hb_node* parent = PARENT(node);
-
534 while (parent && parent->rlink == node) {
-
535 node = parent;
-
536 parent = PARENT(parent);
-
537 }
-
538 return parent;
-
539}
-
540
-
541static bool
-
542node_verify(const hb_tree* tree, const hb_node* parent, const hb_node* node,
-
543 unsigned* height, size_t *count)
-
544{
-
545 if (!parent) {
-
546 VERIFY(tree->root == node);
-
547 } else {
-
548 if (parent->llink == node) {
-
549 if (node)
-
550 VERIFY(tree->cmp_func(parent->key, node->key) > 0);
-
551 } else {
-
552 ASSERT(parent->rlink == node);
-
553 if (node)
-
554 VERIFY(tree->cmp_func(parent->key, node->key) < 0);
-
555 }
-
556 }
-
557 if (node) {
-
558 int bal = node->bal & BAL_MASK;
-
559 VERIFY(bal >= 0);
-
560 VERIFY(bal <= 2);
-
561 if (bal == 2) {
-
562 VERIFY(node->llink != NULL);
-
563 bal = -1;
-
564 } else if (bal == 1) {
-
565 VERIFY(node->rlink != NULL);
-
566 }
-
567 VERIFY(PARENT(node) == parent);
-
568 unsigned lheight, rheight;
-
569 if (!node_verify(tree, node, node->llink, &lheight, count) ||
-
570 !node_verify(tree, node, node->rlink, &rheight, count))
-
571 return false;
-
572 VERIFY(bal == (int)rheight - (int)lheight);
-
573 if (height)
-
574 *height = MAX(lheight, rheight) + 1;
-
575 *count += 1;
-
576 } else {
-
577 if (height)
-
578 *height = 0;
-
579 }
-
580 return true;
-
581}
-
582
-
583bool
-
- -
585{
-
586 size_t count = 0;
-
587 bool verified = node_verify(tree, NULL, tree->root, NULL, &count);
-
588 VERIFY(tree->count == count);
-
589 return verified;
-
590}
+
493
+
494size_t hb_tree_count(const hb_tree* tree) { return tree_count(tree); }
+ + + +
498
+
499static hb_node*
+
500node_new(void* key)
+
501{
+
502 hb_node* node = MALLOC(sizeof(*node));
+
503 if (node) {
+
504 ASSERT((((intptr_t)node) & 3) == 0); /* Ensure malloc returns aligned result. */
+
505 node->key = key;
+
506 node->datum = NULL;
+
507 node->bal = 0; /* also initializes parent to NULL */
+
508 node->llink = NULL;
+
509 node->rlink = NULL;
+
510 }
+
511 return node;
+
512}
+
513
+
514static hb_node*
+
515node_prev(hb_node* node)
+
516{
+
517 if (node->llink)
+
518 return tree_node_max(node->llink);
+
519 hb_node* parent = PARENT(node);
+
520 while (parent && parent->llink == node) {
+
521 node = parent;
+
522 parent = PARENT(parent);
+
523 }
+
524 return parent;
+
525}
+
526
+
527static hb_node*
+
528node_next(hb_node* node)
+
529{
+
530 if (node->rlink)
+
531 return tree_node_min(node->rlink);
+
532 hb_node* parent = PARENT(node);
+
533 while (parent && parent->rlink == node) {
+
534 node = parent;
+
535 parent = PARENT(parent);
+
536 }
+
537 return parent;
+
538}
+
539
+
540static bool
+
541node_verify(const hb_tree* tree, const hb_node* parent, const hb_node* node,
+
542 unsigned* height, size_t *count)
+
543{
+
544 if (!parent) {
+
545 VERIFY(tree->root == node);
+
546 } else {
+
547 if (parent->llink == node) {
+
548 if (node)
+
549 VERIFY(tree->cmp_func(parent->key, node->key) > 0);
+
550 } else {
+
551 ASSERT(parent->rlink == node);
+
552 if (node)
+
553 VERIFY(tree->cmp_func(parent->key, node->key) < 0);
+
554 }
+
555 }
+
556 if (node) {
+
557 int bal = node->bal & BAL_MASK;
+
558 VERIFY(bal >= 0);
+
559 VERIFY(bal <= 2);
+
560 if (bal == 2) {
+
561 VERIFY(node->llink != NULL);
+
562 bal = -1;
+
563 } else if (bal == 1) {
+
564 VERIFY(node->rlink != NULL);
+
565 }
+
566 VERIFY(PARENT(node) == parent);
+
567 unsigned lheight, rheight;
+
568 if (!node_verify(tree, node, node->llink, &lheight, count) ||
+
569 !node_verify(tree, node, node->rlink, &rheight, count))
+
570 return false;
+
571 VERIFY(bal == (int)rheight - (int)lheight);
+
572 if (height)
+
573 *height = MAX(lheight, rheight) + 1;
+
574 *count += 1;
+
575 } else {
+
576 if (height)
+
577 *height = 0;
+
578 }
+
579 return true;
+
580}
+
581
+
582bool
+
+ +
584{
+
585 size_t count = 0;
+
586 bool verified = node_verify(tree, NULL, tree->root, NULL, &count);
+
587 VERIFY(tree->count == count);
+
588 return verified;
+
589}
-
591
-
592hb_itor*
-
- -
594{
-
595 hb_itor* itor = MALLOC(sizeof(*itor));
-
596 if (itor) {
-
597 itor->tree = tree;
-
598 itor->node = NULL;
-
599 }
-
600 return itor;
-
601}
+
590
+
591hb_itor*
+
+ +
593{
+
594 hb_itor* itor = MALLOC(sizeof(*itor));
+
595 if (itor) {
+
596 itor->tree = tree;
+
597 itor->node = NULL;
+
598 }
+
599 return itor;
+
600}
-
602
- -
- -
605{
-
606 dict_itor* itor = MALLOC(sizeof(*itor));
-
607 if (itor) {
-
608 if (!(itor->_itor = hb_itor_new(tree))) {
-
609 FREE(itor);
-
610 return NULL;
-
611 }
-
612 itor->_vtable = &hb_tree_itor_vtable;
-
613 }
-
614 return itor;
-
615}
+
601
+ +
+ +
604{
+
605 dict_itor* itor = MALLOC(sizeof(*itor));
+
606 if (itor) {
+
607 if (!(itor->_itor = hb_itor_new(tree))) {
+
608 FREE(itor);
+
609 return NULL;
+
610 }
+
611 itor->_vtable = &hb_tree_itor_vtable;
+
612 }
+
613 return itor;
+
614}
-
616
- -
618bool hb_itor_valid(const hb_itor* itor) { return tree_iterator_valid(itor); }
- -
620
-
- -
622 if (itor->node)
-
623 itor->node = node_next(itor->node);
-
624 return itor->node != NULL;
-
625}
+
615
+ +
617bool hb_itor_valid(const hb_itor* itor) { return tree_iterator_valid(itor); }
+ +
619
+
+ +
621 if (itor->node)
+
622 itor->node = node_next(itor->node);
+
623 return itor->node != NULL;
+
624}
-
626
-
- -
628 if (itor->node)
-
629 itor->node = node_prev(itor->node);
-
630 return itor->node != NULL;
-
631}
+
625
+
+ +
627 if (itor->node)
+
628 itor->node = node_prev(itor->node);
+
629 return itor->node != NULL;
+
630}
-
632
-
-
633bool hb_itor_nextn(hb_itor* itor, size_t count) {
-
634 while (itor->node && count--)
-
635 itor->node = node_next(itor->node);
-
636 return itor->node != NULL;
-
637}
+
631
+
+
632bool hb_itor_nextn(hb_itor* itor, size_t count) {
+
633 while (itor->node && count--)
+
634 itor->node = node_next(itor->node);
+
635 return itor->node != NULL;
+
636}
-
638
-
-
639bool hb_itor_prevn(hb_itor* itor, size_t count) {
-
640 while (itor->node && count--)
-
641 itor->node = node_prev(itor->node);
-
642 return itor->node != NULL;
-
643}
+
637
+
+
638bool hb_itor_prevn(hb_itor* itor, size_t count) {
+
639 while (itor->node && count--)
+
640 itor->node = node_prev(itor->node);
+
641 return itor->node != NULL;
+
642}
-
644
-
645bool hb_itor_first(hb_itor* itor) { return tree_iterator_first(itor); }
-
646bool hb_itor_last(hb_itor* itor) { return tree_iterator_last(itor); }
-
647bool hb_itor_search(hb_itor* itor, const void* key) { return tree_iterator_search_ge(itor, key); }
-
648bool hb_itor_search_le(hb_itor* itor, const void* key) { return tree_iterator_search_le(itor, key); }
-
649bool hb_itor_search_lt(hb_itor* itor, const void* key) { return tree_iterator_search_lt(itor, key); }
-
650bool hb_itor_search_ge(hb_itor* itor, const void* key) { return tree_iterator_search_ge(itor, key); }
-
651bool hb_itor_search_gt(hb_itor* itor, const void* key) { return tree_iterator_search_gt(itor, key); }
-
652int hb_itor_compare(const hb_itor* i1, const hb_itor* i2) { return tree_iterator_compare(i1, i2); }
-
653const void* hb_itor_key(const hb_itor* itor) { return tree_iterator_key(itor); }
-
654void** hb_itor_datum(hb_itor* itor) { return tree_iterator_datum(itor); }
-
655
-
656bool
-
- -
658{
-
659 if (!itor->node)
-
660 return false;
-
661 remove_node(itor->tree, itor->node);
-
662 itor->node = NULL;
-
663 return true;
-
664}
+
643
+
644bool hb_itor_first(hb_itor* itor) { return tree_iterator_first(itor); }
+
645bool hb_itor_last(hb_itor* itor) { return tree_iterator_last(itor); }
+
646bool hb_itor_search(hb_itor* itor, const void* key) { return tree_iterator_search_ge(itor, key); }
+
647bool hb_itor_search_le(hb_itor* itor, const void* key) { return tree_iterator_search_le(itor, key); }
+
648bool hb_itor_search_lt(hb_itor* itor, const void* key) { return tree_iterator_search_lt(itor, key); }
+
649bool hb_itor_search_ge(hb_itor* itor, const void* key) { return tree_iterator_search_ge(itor, key); }
+
650bool hb_itor_search_gt(hb_itor* itor, const void* key) { return tree_iterator_search_gt(itor, key); }
+
651int hb_itor_compare(const hb_itor* i1, const hb_itor* i2) { return tree_iterator_compare(i1, i2); }
+
652const void* hb_itor_key(const hb_itor* itor) { return tree_iterator_key(itor); }
+
653void** hb_itor_datum(hb_itor* itor) { return tree_iterator_datum(itor); }
+
654
+
655bool
+
+ +
657{
+
658 if (!itor->node)
+
659 return false;
+
660 remove_node(itor->tree, itor->node);
+
661 itor->node = NULL;
+
662 return true;
+
663}
dict_remove_result(* dict_remove_func)(void *obj, const void *key)
Definition dict.h:90
int(* dict_compare_func)(const void *, const void *)
Definition dict.h:54
@@ -818,48 +817,48 @@
#define MALLOC(n)
#define SWAP(a, b, v)
#define MAX(a, b)
-
bool hb_itor_search(hb_itor *itor, const void *key)
Definition hb_tree.c:647
-
dict_itor * hb_dict_itor_new(hb_tree *tree)
Definition hb_tree.c:604
+
bool hb_itor_search(hb_itor *itor, const void *key)
Definition hb_tree.c:646
+
dict_itor * hb_dict_itor_new(hb_tree *tree)
Definition hb_tree.c:603
size_t hb_tree_clear(hb_tree *tree, dict_delete_func delete_func)
Definition hb_tree.c:142
#define BAL_POS(node)
Definition hb_tree.c:48
-
bool hb_itor_search_gt(hb_itor *itor, const void *key)
Definition hb_tree.c:651
+
bool hb_itor_search_gt(hb_itor *itor, const void *key)
Definition hb_tree.c:650
void ** hb_tree_search_lt(hb_tree *tree, const void *key)
Definition hb_tree.c:358
#define PARENT(node)
Definition hb_tree.c:47
void ** hb_tree_search(hb_tree *tree, const void *key)
Definition hb_tree.c:356
#define BAL_NEG(node)
Definition hb_tree.c:49
-
bool hb_tree_select(hb_tree *tree, size_t n, const void **key, void **datum)
Definition hb_tree.c:468
+
bool hb_tree_select(hb_tree *tree, size_t n, const void **key, void **datum)
Definition hb_tree.c:467
dict * hb_dict_new(dict_compare_func cmp_func)
Definition hb_tree.c:121
-
bool hb_itor_search_ge(hb_itor *itor, const void *key)
Definition hb_tree.c:650
-
void hb_itor_free(hb_itor *itor)
Definition hb_tree.c:617
-
hb_itor * hb_itor_new(hb_tree *tree)
Definition hb_tree.c:593
-
bool hb_itor_search_lt(hb_itor *itor, const void *key)
Definition hb_tree.c:649
-
bool hb_itor_prev(hb_itor *itor)
Definition hb_tree.c:627
+
bool hb_itor_search_ge(hb_itor *itor, const void *key)
Definition hb_tree.c:649
+
void hb_itor_free(hb_itor *itor)
Definition hb_tree.c:616
+
hb_itor * hb_itor_new(hb_tree *tree)
Definition hb_tree.c:592
+
bool hb_itor_search_lt(hb_itor *itor, const void *key)
Definition hb_tree.c:648
+
bool hb_itor_prev(hb_itor *itor)
Definition hb_tree.c:626
void ** hb_tree_search_gt(hb_tree *tree, const void *key)
Definition hb_tree.c:360
hb_tree * hb_tree_new(dict_compare_func cmp_func)
Definition hb_tree.c:106
-
void hb_itor_invalidate(hb_itor *itor)
Definition hb_tree.c:619
-
size_t hb_tree_count(const hb_tree *tree)
Definition hb_tree.c:495
-
bool hb_itor_valid(const hb_itor *itor)
Definition hb_tree.c:618
-
size_t hb_tree_min_path_length(const hb_tree *tree)
Definition hb_tree.c:496
+
void hb_itor_invalidate(hb_itor *itor)
Definition hb_tree.c:618
+
size_t hb_tree_count(const hb_tree *tree)
Definition hb_tree.c:494
+
bool hb_itor_valid(const hb_itor *itor)
Definition hb_tree.c:617
+
size_t hb_tree_min_path_length(const hb_tree *tree)
Definition hb_tree.c:495
dict_insert_result hb_tree_insert(hb_tree *tree, void *key)
Definition hb_tree.c:278
void ** hb_tree_search_ge(hb_tree *tree, const void *key)
Definition hb_tree.c:359
-
bool hb_itor_nextn(hb_itor *itor, size_t count)
Definition hb_tree.c:633
+
bool hb_itor_nextn(hb_itor *itor, size_t count)
Definition hb_tree.c:632
#define BAL_MASK
Definition hb_tree.c:46
-
bool hb_itor_remove(hb_itor *itor)
Definition hb_tree.c:657
+
bool hb_itor_remove(hb_itor *itor)
Definition hb_tree.c:656
size_t hb_tree_free(hb_tree *tree, dict_delete_func delete_func)
Definition hb_tree.c:135
-
dict_remove_result hb_tree_remove(hb_tree *tree, const void *key)
Definition hb_tree.c:451
-
size_t hb_tree_max_path_length(const hb_tree *tree)
Definition hb_tree.c:497
-
int hb_itor_compare(const hb_itor *i1, const hb_itor *i2)
Definition hb_tree.c:652
-
bool hb_itor_last(hb_itor *itor)
Definition hb_tree.c:646
-
bool hb_itor_prevn(hb_itor *itor, size_t count)
Definition hb_tree.c:639
-
void ** hb_itor_datum(hb_itor *itor)
Definition hb_tree.c:654
-
bool hb_itor_next(hb_itor *itor)
Definition hb_tree.c:621
-
const void * hb_itor_key(const hb_itor *itor)
Definition hb_tree.c:653
-
bool hb_itor_search_le(hb_itor *itor, const void *key)
Definition hb_tree.c:648
-
bool hb_tree_verify(const hb_tree *tree)
Definition hb_tree.c:584
-
bool hb_itor_first(hb_itor *itor)
Definition hb_tree.c:645
-
size_t hb_tree_traverse(hb_tree *tree, dict_visit_func visit, void *user_data)
Definition hb_tree.c:462
+
dict_remove_result hb_tree_remove(hb_tree *tree, const void *key)
Definition hb_tree.c:450
+
size_t hb_tree_max_path_length(const hb_tree *tree)
Definition hb_tree.c:496
+
int hb_itor_compare(const hb_itor *i1, const hb_itor *i2)
Definition hb_tree.c:651
+
bool hb_itor_last(hb_itor *itor)
Definition hb_tree.c:645
+
bool hb_itor_prevn(hb_itor *itor, size_t count)
Definition hb_tree.c:638
+
void ** hb_itor_datum(hb_itor *itor)
Definition hb_tree.c:653
+
bool hb_itor_next(hb_itor *itor)
Definition hb_tree.c:620
+
const void * hb_itor_key(const hb_itor *itor)
Definition hb_tree.c:652
+
bool hb_itor_search_le(hb_itor *itor, const void *key)
Definition hb_tree.c:647
+
bool hb_tree_verify(const hb_tree *tree)
Definition hb_tree.c:583
+
bool hb_itor_first(hb_itor *itor)
Definition hb_tree.c:644
+
size_t hb_tree_traverse(hb_tree *tree, dict_visit_func visit, void *user_data)
Definition hb_tree.c:461
void ** hb_tree_search_le(hb_tree *tree, const void *key)
Definition hb_tree.c:357
-
size_t hb_tree_total_path_length(const hb_tree *tree)
Definition hb_tree.c:498
+
size_t hb_tree_total_path_length(const hb_tree *tree)
Definition hb_tree.c:497
diff --git a/html/hb__tree_8h.html b/html/hb__tree_8h.html index e1764fd..6e1688b 100644 --- a/html/hb__tree_8h.html +++ b/html/hb__tree_8h.html @@ -338,7 +338,7 @@

-

Definition at line 604 of file hb_tree.c.

+

Definition at line 603 of file hb_tree.c.

Here is the call graph for this function:
@@ -408,7 +408,7 @@

-

Definition at line 652 of file hb_tree.c.

+

Definition at line 651 of file hb_tree.c.

Here is the call graph for this function:
@@ -438,7 +438,7 @@

-

Definition at line 654 of file hb_tree.c.

+

Definition at line 653 of file hb_tree.c.

Here is the call graph for this function:
@@ -468,7 +468,7 @@

-

Definition at line 645 of file hb_tree.c.

+

Definition at line 644 of file hb_tree.c.

Here is the call graph for this function:
@@ -500,7 +500,7 @@

-

Definition at line 617 of file hb_tree.c.

+

Definition at line 616 of file hb_tree.c.

Here is the call graph for this function:
@@ -530,7 +530,7 @@

-

Definition at line 619 of file hb_tree.c.

+

Definition at line 618 of file hb_tree.c.

Here is the call graph for this function:
@@ -560,7 +560,7 @@

-

Definition at line 653 of file hb_tree.c.

+

Definition at line 652 of file hb_tree.c.

Here is the call graph for this function:
@@ -590,7 +590,7 @@

-

Definition at line 646 of file hb_tree.c.

+

Definition at line 645 of file hb_tree.c.

Here is the call graph for this function:
@@ -622,7 +622,7 @@

-

Definition at line 593 of file hb_tree.c.

+

Definition at line 592 of file hb_tree.c.

@@ -642,7 +642,7 @@

-

Definition at line 621 of file hb_tree.c.

+

Definition at line 620 of file hb_tree.c.

@@ -672,7 +672,7 @@

-

Definition at line 633 of file hb_tree.c.

+

Definition at line 632 of file hb_tree.c.

@@ -692,7 +692,7 @@

-

Definition at line 627 of file hb_tree.c.

+

Definition at line 626 of file hb_tree.c.

@@ -722,7 +722,7 @@

-

Definition at line 639 of file hb_tree.c.

+

Definition at line 638 of file hb_tree.c.

@@ -742,7 +742,7 @@

-

Definition at line 657 of file hb_tree.c.

+

Definition at line 656 of file hb_tree.c.

@@ -772,7 +772,7 @@

-

Definition at line 647 of file hb_tree.c.

+

Definition at line 646 of file hb_tree.c.

Here is the call graph for this function:
@@ -814,7 +814,7 @@

-

Definition at line 650 of file hb_tree.c.

+

Definition at line 649 of file hb_tree.c.

Here is the call graph for this function:
@@ -856,7 +856,7 @@

-

Definition at line 651 of file hb_tree.c.

+

Definition at line 650 of file hb_tree.c.

Here is the call graph for this function:
@@ -898,7 +898,7 @@

-

Definition at line 648 of file hb_tree.c.

+

Definition at line 647 of file hb_tree.c.

Here is the call graph for this function:
@@ -940,7 +940,7 @@

-

Definition at line 649 of file hb_tree.c.

+

Definition at line 648 of file hb_tree.c.

Here is the call graph for this function:
@@ -972,7 +972,7 @@

-

Definition at line 618 of file hb_tree.c.

+

Definition at line 617 of file hb_tree.c.

Here is the call graph for this function:
@@ -1032,7 +1032,7 @@

-

Definition at line 495 of file hb_tree.c.

+

Definition at line 494 of file hb_tree.c.

Here is the call graph for this function:
@@ -1132,7 +1132,7 @@

-

Definition at line 497 of file hb_tree.c.

+

Definition at line 496 of file hb_tree.c.

Here is the call graph for this function:
@@ -1162,7 +1162,7 @@

-

Definition at line 496 of file hb_tree.c.

+

Definition at line 495 of file hb_tree.c.

Here is the call graph for this function:
@@ -1222,7 +1222,7 @@

-

Definition at line 451 of file hb_tree.c.

+

Definition at line 450 of file hb_tree.c.

Here is the call graph for this function:
@@ -1484,7 +1484,7 @@

-

Definition at line 468 of file hb_tree.c.

+

Definition at line 467 of file hb_tree.c.

Here is the call graph for this function:
@@ -1516,7 +1516,7 @@

-

Definition at line 498 of file hb_tree.c.

+

Definition at line 497 of file hb_tree.c.

Here is the call graph for this function:
@@ -1562,7 +1562,7 @@

-

Definition at line 462 of file hb_tree.c.

+

Definition at line 461 of file hb_tree.c.

Here is the call graph for this function:
@@ -1597,7 +1597,7 @@

-

Definition at line 584 of file hb_tree.c.

+

Definition at line 583 of file hb_tree.c.

diff --git a/html/hb__tree_8h_source.html b/html/hb__tree_8h_source.html index 121a198..f9f417b 100644 --- a/html/hb__tree_8h_source.html +++ b/html/hb__tree_8h_source.html @@ -173,44 +173,44 @@
void(* dict_delete_func)(void *, void *)
Definition dict.h:57
#define END_DECL
Definition dict.h:36
bool(* dict_visit_func)(const void *, void *, void *)
Definition dict.h:59
-
bool hb_itor_search(hb_itor *itor, const void *key)
Definition hb_tree.c:647
-
dict_itor * hb_dict_itor_new(hb_tree *tree)
Definition hb_tree.c:604
+
bool hb_itor_search(hb_itor *itor, const void *key)
Definition hb_tree.c:646
+
dict_itor * hb_dict_itor_new(hb_tree *tree)
Definition hb_tree.c:603
size_t hb_tree_clear(hb_tree *tree, dict_delete_func delete_func)
Definition hb_tree.c:142
-
bool hb_itor_search_gt(hb_itor *itor, const void *key)
Definition hb_tree.c:651
+
bool hb_itor_search_gt(hb_itor *itor, const void *key)
Definition hb_tree.c:650
void ** hb_tree_search_lt(hb_tree *tree, const void *key)
Definition hb_tree.c:358
void ** hb_tree_search(hb_tree *tree, const void *key)
Definition hb_tree.c:356
-
bool hb_tree_select(hb_tree *tree, size_t n, const void **key, void **datum)
Definition hb_tree.c:468
+
bool hb_tree_select(hb_tree *tree, size_t n, const void **key, void **datum)
Definition hb_tree.c:467
dict * hb_dict_new(dict_compare_func cmp_func)
Definition hb_tree.c:121
-
bool hb_itor_search_ge(hb_itor *itor, const void *key)
Definition hb_tree.c:650
-
hb_itor * hb_itor_new(hb_tree *tree)
Definition hb_tree.c:593
-
bool hb_itor_search_lt(hb_itor *itor, const void *key)
Definition hb_tree.c:649
-
bool hb_itor_prev(hb_itor *itor)
Definition hb_tree.c:627
+
bool hb_itor_search_ge(hb_itor *itor, const void *key)
Definition hb_tree.c:649
+
hb_itor * hb_itor_new(hb_tree *tree)
Definition hb_tree.c:592
+
bool hb_itor_search_lt(hb_itor *itor, const void *key)
Definition hb_tree.c:648
+
bool hb_itor_prev(hb_itor *itor)
Definition hb_tree.c:626
void ** hb_tree_search_gt(hb_tree *tree, const void *key)
Definition hb_tree.c:360
hb_tree * hb_tree_new(dict_compare_func cmp_func)
Definition hb_tree.c:106
-
void hb_itor_invalidate(hb_itor *itor)
Definition hb_tree.c:619
-
size_t hb_tree_count(const hb_tree *tree)
Definition hb_tree.c:495
-
bool hb_itor_valid(const hb_itor *itor)
Definition hb_tree.c:618
-
size_t hb_tree_min_path_length(const hb_tree *tree)
Definition hb_tree.c:496
+
void hb_itor_invalidate(hb_itor *itor)
Definition hb_tree.c:618
+
size_t hb_tree_count(const hb_tree *tree)
Definition hb_tree.c:494
+
bool hb_itor_valid(const hb_itor *itor)
Definition hb_tree.c:617
+
size_t hb_tree_min_path_length(const hb_tree *tree)
Definition hb_tree.c:495
dict_insert_result hb_tree_insert(hb_tree *tree, void *key)
Definition hb_tree.c:278
void ** hb_tree_search_ge(hb_tree *tree, const void *key)
Definition hb_tree.c:359
-
bool hb_itor_nextn(hb_itor *itor, size_t count)
Definition hb_tree.c:633
-
bool hb_itor_remove(hb_itor *itor)
Definition hb_tree.c:657
-
void hb_itor_free(hb_itor *tree)
Definition hb_tree.c:617
+
bool hb_itor_nextn(hb_itor *itor, size_t count)
Definition hb_tree.c:632
+
bool hb_itor_remove(hb_itor *itor)
Definition hb_tree.c:656
+
void hb_itor_free(hb_itor *tree)
Definition hb_tree.c:616
size_t hb_tree_free(hb_tree *tree, dict_delete_func delete_func)
Definition hb_tree.c:135
-
dict_remove_result hb_tree_remove(hb_tree *tree, const void *key)
Definition hb_tree.c:451
-
size_t hb_tree_max_path_length(const hb_tree *tree)
Definition hb_tree.c:497
-
int hb_itor_compare(const hb_itor *i1, const hb_itor *i2)
Definition hb_tree.c:652
-
bool hb_itor_last(hb_itor *itor)
Definition hb_tree.c:646
-
bool hb_itor_prevn(hb_itor *itor, size_t count)
Definition hb_tree.c:639
-
void ** hb_itor_datum(hb_itor *itor)
Definition hb_tree.c:654
-
bool hb_itor_next(hb_itor *itor)
Definition hb_tree.c:621
-
const void * hb_itor_key(const hb_itor *itor)
Definition hb_tree.c:653
-
bool hb_itor_search_le(hb_itor *itor, const void *key)
Definition hb_tree.c:648
-
bool hb_tree_verify(const hb_tree *tree)
Definition hb_tree.c:584
-
bool hb_itor_first(hb_itor *itor)
Definition hb_tree.c:645
-
size_t hb_tree_traverse(hb_tree *tree, dict_visit_func visit, void *user_data)
Definition hb_tree.c:462
+
dict_remove_result hb_tree_remove(hb_tree *tree, const void *key)
Definition hb_tree.c:450
+
size_t hb_tree_max_path_length(const hb_tree *tree)
Definition hb_tree.c:496
+
int hb_itor_compare(const hb_itor *i1, const hb_itor *i2)
Definition hb_tree.c:651
+
bool hb_itor_last(hb_itor *itor)
Definition hb_tree.c:645
+
bool hb_itor_prevn(hb_itor *itor, size_t count)
Definition hb_tree.c:638
+
void ** hb_itor_datum(hb_itor *itor)
Definition hb_tree.c:653
+
bool hb_itor_next(hb_itor *itor)
Definition hb_tree.c:620
+
const void * hb_itor_key(const hb_itor *itor)
Definition hb_tree.c:652
+
bool hb_itor_search_le(hb_itor *itor, const void *key)
Definition hb_tree.c:647
+
bool hb_tree_verify(const hb_tree *tree)
Definition hb_tree.c:583
+
bool hb_itor_first(hb_itor *itor)
Definition hb_tree.c:644
+
size_t hb_tree_traverse(hb_tree *tree, dict_visit_func visit, void *user_data)
Definition hb_tree.c:461
void ** hb_tree_search_le(hb_tree *tree, const void *key)
Definition hb_tree.c:357
-
size_t hb_tree_total_path_length(const hb_tree *tree)
Definition hb_tree.c:498
+
size_t hb_tree_total_path_length(const hb_tree *tree)
Definition hb_tree.c:497
diff --git a/html/skiplist_8c.html b/html/skiplist_8c.html index f1b3ca1..4926cc4 100644 --- a/html/skiplist_8c.html +++ b/html/skiplist_8c.html @@ -293,7 +293,7 @@

-

Definition at line 408 of file skiplist.c.

+

Definition at line 409 of file skiplist.c.

@@ -313,7 +313,7 @@

-

Definition at line 439 of file skiplist.c.

+

Definition at line 440 of file skiplist.c.

@@ -333,7 +333,7 @@

-

Definition at line 511 of file skiplist.c.

+

Definition at line 512 of file skiplist.c.

Here is the call graph for this function:
@@ -453,7 +453,7 @@

-

Definition at line 183 of file skiplist.c.

+

Definition at line 184 of file skiplist.c.

@@ -483,7 +483,7 @@

-

Definition at line 642 of file skiplist.c.

+

Definition at line 643 of file skiplist.c.

@@ -503,7 +503,7 @@

-

Definition at line 636 of file skiplist.c.

+

Definition at line 637 of file skiplist.c.

@@ -523,7 +523,7 @@

-

Definition at line 577 of file skiplist.c.

+

Definition at line 578 of file skiplist.c.

@@ -543,7 +543,7 @@

-

Definition at line 525 of file skiplist.c.

+

Definition at line 526 of file skiplist.c.

@@ -563,7 +563,7 @@

-

Definition at line 537 of file skiplist.c.

+

Definition at line 538 of file skiplist.c.

@@ -583,7 +583,7 @@

-

Definition at line 630 of file skiplist.c.

+

Definition at line 631 of file skiplist.c.

@@ -603,7 +603,7 @@

-

Definition at line 583 of file skiplist.c.

+

Definition at line 584 of file skiplist.c.

@@ -623,7 +623,7 @@

-

Definition at line 500 of file skiplist.c.

+

Definition at line 501 of file skiplist.c.

@@ -643,7 +643,7 @@

-

Definition at line 543 of file skiplist.c.

+

Definition at line 544 of file skiplist.c.

@@ -673,7 +673,7 @@

-

Definition at line 559 of file skiplist.c.

+

Definition at line 560 of file skiplist.c.

Here is the call graph for this function:
@@ -703,7 +703,7 @@

-

Definition at line 551 of file skiplist.c.

+

Definition at line 552 of file skiplist.c.

@@ -733,7 +733,7 @@

-

Definition at line 568 of file skiplist.c.

+

Definition at line 569 of file skiplist.c.

Here is the call graph for this function:
@@ -763,7 +763,7 @@

-

Definition at line 653 of file skiplist.c.

+

Definition at line 654 of file skiplist.c.

Here is the call graph for this function:
@@ -803,7 +803,7 @@

-

Definition at line 600 of file skiplist.c.

+

Definition at line 601 of file skiplist.c.

@@ -833,7 +833,7 @@

-

Definition at line 618 of file skiplist.c.

+

Definition at line 619 of file skiplist.c.

@@ -863,7 +863,7 @@

-

Definition at line 624 of file skiplist.c.

+

Definition at line 625 of file skiplist.c.

@@ -893,7 +893,7 @@

-

Definition at line 606 of file skiplist.c.

+

Definition at line 607 of file skiplist.c.

@@ -923,7 +923,7 @@

-

Definition at line 612 of file skiplist.c.

+

Definition at line 613 of file skiplist.c.

@@ -943,7 +943,7 @@

-

Definition at line 531 of file skiplist.c.

+

Definition at line 532 of file skiplist.c.

@@ -979,7 +979,7 @@

-

Definition at line 484 of file skiplist.c.

+

Definition at line 485 of file skiplist.c.

@@ -1039,7 +1039,7 @@

-

Definition at line 362 of file skiplist.c.

+

Definition at line 363 of file skiplist.c.

@@ -1069,7 +1069,7 @@

-

Definition at line 327 of file skiplist.c.

+

Definition at line 328 of file skiplist.c.

@@ -1099,7 +1099,7 @@

-

Definition at line 348 of file skiplist.c.

+

Definition at line 349 of file skiplist.c.

@@ -1129,7 +1129,7 @@

-

Definition at line 355 of file skiplist.c.

+

Definition at line 356 of file skiplist.c.

@@ -1159,7 +1159,7 @@

-

Definition at line 334 of file skiplist.c.

+

Definition at line 335 of file skiplist.c.

@@ -1189,7 +1189,7 @@

-

Definition at line 341 of file skiplist.c.

+

Definition at line 342 of file skiplist.c.

@@ -1225,7 +1225,7 @@

-

Definition at line 428 of file skiplist.c.

+

Definition at line 429 of file skiplist.c.

@@ -1245,7 +1245,7 @@

-

Definition at line 445 of file skiplist.c.

+

Definition at line 446 of file skiplist.c.

diff --git a/html/skiplist_8c_source.html b/html/skiplist_8c_source.html index 016441e..3f4f545 100644 --- a/html/skiplist_8c_source.html +++ b/html/skiplist_8c_source.html @@ -268,582 +268,583 @@
172 if (update[0]->link && update[0]->link[0])
173 update[0]->link[0]->prev = x;
174 for (unsigned k = 0; k < nlinks; k++) {
-
175 ASSERT(update[k]->link_count > k);
-
176 x->link[k] = update[k]->link[k];
-
177 update[k]->link[k] = x;
-
178 }
-
179 ++list->count;
-
180}
-
181
- -
-
183skiplist_insert(skiplist* list, void* key)
-
184{
-
185 skip_node* x = list->head;
-
186 skip_node* update[MAX_LINK] = { 0 };
-
187 for (unsigned k = list->top_link+1; k-->0; ) {
-
188 ASSERT(x->link_count > k);
-
189 for (;;) {
-
190 skip_node* const y = x->link[k];
-
191 if (!y)
-
192 break;
-
193 const int cmp = list->cmp_func(key, y->key);
-
194 if (cmp < 0) {
-
195 while (k > 0 && x->link[k - 1] == y)
-
196 update[k--] = x;
-
197 break;
-
198 } else if (cmp == 0)
-
199 return (dict_insert_result) { &y->datum, false };
-
200 x = y;
-
201 }
-
202 update[k] = x;
-
203 }
-
204
-
205 x = node_new(key, rand_link_count(list));
-
206 if (!x)
-
207 return (dict_insert_result) { NULL, false };
-
208 node_insert(list, x, update);
-
209 return (dict_insert_result) { &x->datum, true };
-
210}
-
-
211
-
212static inline skip_node*
-
213node_search(skiplist* list, const void* key)
-
214{
-
215 skip_node* x = list->head;
-
216 for (unsigned k = list->top_link+1; k-->0;) {
-
217 for (;;) {
-
218 skip_node* const y = x->link[k];
-
219 if (!y)
-
220 break;
-
221 const int cmp = list->cmp_func(key, y->key);
-
222 if (cmp < 0) {
-
223 while (k > 0 && x->link[k - 1] == y)
-
224 k--;
-
225 break;
-
226 } else if (cmp == 0)
-
227 return y;
-
228 x = y;
-
229 }
-
230 }
-
231 return NULL;
-
232}
-
233
-
234static inline skip_node*
-
235node_search_le(skiplist* list, const void* key)
-
236{
-
237 skip_node* x = list->head;
-
238 for (unsigned k = list->top_link+1; k-->0;) {
-
239 for (;;) {
-
240 skip_node* const y = x->link[k];
-
241 if (!y)
-
242 break;
-
243 const int cmp = list->cmp_func(key, y->key);
-
244 if (cmp < 0) {
-
245 while (k > 0 && x->link[k - 1] == y)
-
246 k--;
-
247 break;
-
248 } else if (cmp == 0)
-
249 return y;
-
250 x = y;
-
251 }
-
252 }
-
253 return x == list->head ? NULL : x;
-
254}
-
255
-
256static inline skip_node*
-
257node_search_lt(skiplist* list, const void* key)
-
258{
-
259 skip_node* x = list->head;
-
260 for (unsigned k = list->top_link+1; k-->0;) {
-
261 for (;;) {
-
262 skip_node* const y = x->link[k];
-
263 if (!y)
-
264 break;
-
265 const int cmp = list->cmp_func(key, y->key);
-
266 if (cmp < 0) {
-
267 while (k > 0 && x->link[k - 1] == y)
-
268 k--;
-
269 break;
-
270 } else if (cmp == 0)
-
271 return y->prev;
-
272 x = y;
-
273 }
-
274 }
-
275 return x == list->head ? NULL : x;
-
276}
-
277
-
278static inline skip_node*
-
279node_search_ge(skiplist* list, const void* key)
-
280{
-
281 skip_node* x = list->head;
-
282 skip_node* ret = NULL;
-
283 for (unsigned k = list->top_link+1; k-->0;) {
-
284 for (;;) {
-
285 skip_node* const y = x->link[k];
-
286 if (!y)
-
287 break;
-
288 const int cmp = list->cmp_func(key, y->key);
-
289 if (cmp < 0) {
-
290 ret = y;
-
291 while (k > 0 && x->link[k - 1] == y)
-
292 k--;
-
293 break;
-
294 } else if (cmp == 0)
-
295 return y;
-
296 x = y;
-
297 }
-
298 }
-
299 return ret;
-
300}
-
301
-
302static inline skip_node*
-
303node_search_gt(skiplist* list, const void* key)
-
304{
-
305 skip_node* x = list->head;
-
306 skip_node* ret = NULL;
-
307 for (unsigned k = list->top_link+1; k-->0;) {
-
308 for (;;) {
-
309 skip_node* const y = x->link[k];
-
310 if (!y)
-
311 break;
-
312 const int cmp = list->cmp_func(key, y->key);
-
313 if (cmp < 0) {
-
314 ret = y;
-
315 while (k > 0 && x->link[k - 1] == y)
-
316 k--;
-
317 break;
-
318 } else if (cmp == 0)
-
319 return y->link[0];
-
320 x = y;
-
321 }
-
322 }
-
323 return ret;
-
324}
-
325
-
326void**
-
-
327skiplist_search(skiplist* list, const void* key)
-
328{
-
329 skip_node* x = node_search(list, key);
-
330 return x ? &x->datum : NULL;
-
331}
-
-
332
-
333void**
-
-
334skiplist_search_le(skiplist* list, const void* key)
-
335{
-
336 skip_node* x = node_search_le(list, key);
-
337 return x ? &x->datum : NULL;
-
338}
-
-
339
-
340void**
-
-
341skiplist_search_lt(skiplist* list, const void* key)
-
342{
-
343 skip_node* x = node_search_lt(list, key);
-
344 return x ? &x->datum : NULL;
-
345}
-
-
346
-
347void**
-
-
348skiplist_search_ge(skiplist* list, const void* key)
-
349{
-
350 skip_node* x = node_search_ge(list, key);
-
351 return x ? &x->datum : NULL;
-
352}
-
-
353
-
354void**
-
-
355skiplist_search_gt(skiplist* list, const void* key)
-
356{
-
357 skip_node* x = node_search_gt(list, key);
-
358 return x ? &x->datum : NULL;
-
359}
-
-
360
- -
-
362skiplist_remove(skiplist* list, const void* key)
-
363{
-
364 skip_node* x = list->head;
-
365 skip_node* update[MAX_LINK] = { 0 };
-
366 bool found = false;
-
367 for (unsigned k = list->top_link+1; k-->0;) {
-
368 ASSERT(x->link_count > k);
-
369 for (;;) {
-
370 skip_node* const y = x->link[k];
-
371 if (!y)
-
372 break;
-
373 const int cmp = list->cmp_func(key, y->key);
-
374 if (cmp > 0)
-
375 x = y;
-
376 else {
-
377 while (k > 0 && x->link[k - 1] == y)
-
378 update[k--] = x;
-
379 if (cmp == 0)
-
380 found = true;
-
381 break;
-
382 }
-
383 }
-
384 update[k] = x;
-
385 }
-
386 if (!found)
-
387 return (dict_remove_result) { NULL, NULL, false };
-
388 x = x->link[0];
-
389 for (unsigned k = 0; k <= list->top_link; k++) {
-
390 ASSERT(update[k] != NULL);
-
391 ASSERT(update[k]->link_count > k);
-
392 if (update[k]->link[k] != x) break;
-
393 update[k]->link[k] = x->link[k];
-
394 }
-
395 if (x->prev)
-
396 x->prev->link[0] = x->link[0];
-
397 if (x->link[0])
-
398 x->link[0]->prev = x->prev;
-
399 dict_remove_result result = { x->key, x->datum, true };
-
400 FREE(x);
-
401 while (list->top_link > 0 && !list->head->link[list->top_link-1])
-
402 list->top_link--;
-
403 list->count--;
-
404 return result;
-
405}
-
-
406
-
407size_t
-
- -
409{
-
410 skip_node* node = list->head->link[0];
-
411 while (node) {
-
412 skip_node* next = node->link[0];
-
413 if (delete_func) delete_func(node->key, node->datum);
-
414 FREE(node);
-
415 node = next;
-
416 }
-
417
-
418 const size_t count = list->count;
-
419 list->count = 0;
-
420 list->head->link[list->top_link] = NULL;
-
421 while (list->top_link)
-
422 list->head->link[--list->top_link] = NULL;
-
423
-
424 return count;
-
425}
-
-
426
-
427size_t
-
-
428skiplist_traverse(skiplist* list, dict_visit_func visit, void* user_data)
-
429{
-
430 size_t count = 0;
-
431 for (skip_node* node = list->head->link[0]; node; node = node->link[0]) {
-
432 ++count;
-
433 if (!visit(node->key, node->datum, user_data)) break;
-
434 }
-
435 return count;
-
436}
-
-
437
-
438size_t
-
- -
440{
-
441 return list->count;
-
442}
-
-
443
-
444bool
-
- -
446{
-
447 if (list->count == 0) {
-
448 VERIFY(list->top_link == 0);
-
449 } else {
-
450 VERIFY(list->top_link > 0);
-
451 }
-
452 VERIFY(list->top_link < list->max_link);
-
453 for (unsigned i = 0; i < list->top_link; ++i) {
-
454 VERIFY(list->head->link[i] != NULL);
-
455 }
-
456 for (unsigned i = list->top_link; i < list->max_link; ++i) {
-
457 VERIFY(list->head->link[i] == NULL);
-
458 }
-
459 unsigned observed_top_link = 0;
-
460
-
461 skip_node* prev = NULL;
-
462 skip_node* node = list->head->link[0];
-
463 while (node) {
-
464 if (observed_top_link < node->link_count)
-
465 observed_top_link = node->link_count;
-
466
-
467 VERIFY(node->prev == prev);
-
468 VERIFY(node->link_count >= 1);
-
469 VERIFY(node->link_count <= list->top_link);
-
470 for (unsigned k = 0; k < node->link_count; k++) {
-
471 if (node->link[k]) {
-
472 VERIFY(node->link[k]->link_count >= k);
-
473 }
-
474 }
-
475
-
476 prev = node;
-
477 node = node->link[0];
-
478 }
-
479 VERIFY(list->top_link == observed_top_link);
-
480 return true;
-
481}
-
-
482
-
483size_t
-
-
484skiplist_link_count_histogram(const skiplist* list, size_t counts[], size_t ncounts)
-
485{
-
486 for (size_t i = 0; i < ncounts; ++i)
-
487 counts[i] = 0;
-
488
-
489 size_t max_num_links = 0;
-
490 for (const skip_node* node = list->head->link[0]; node; node = node->link[0]) {
-
491 if (max_num_links < node->link_count)
-
492 max_num_links = node->link_count;
-
493 if (ncounts > node->link_count)
-
494 counts[node->link_count]++;
-
495 }
-
496 return max_num_links;
-
497}
-
-
498
- -
- -
501{
-
502 skiplist_itor* itor = MALLOC(sizeof(*itor));
-
503 if (itor) {
-
504 itor->list = list;
-
505 itor->node = NULL;
-
506 }
-
507 return itor;
-
508}
-
-
509
- -
- -
512{
-
513 dict_itor* itor = MALLOC(sizeof(*itor));
-
514 if (itor) {
-
515 if (!(itor->_itor = skiplist_itor_new(list))) {
-
516 FREE(itor);
-
517 return NULL;
-
518 }
-
519 itor->_vtable = &skiplist_itor_vtable;
-
520 }
-
521 return itor;
-
522}
-
-
523
-
524void
-
- -
526{
-
527 FREE(itor);
-
528}
-
-
529
-
530bool
-
- -
532{
-
533 return itor->node != NULL;
-
534}
-
-
535
-
536void
-
- -
538{
-
539 itor->node = NULL;
-
540}
-
-
541
-
542bool
-
- -
544{
-
545 if (itor->node)
-
546 itor->node = itor->node->link[0];
-
547 return itor->node != NULL;
-
548}
-
-
549
-
550bool
-
- -
552{
-
553 if (itor->node)
-
554 itor->node = itor->node->prev;
-
555 return itor->node != NULL;
-
556}
-
-
557
-
558bool
-
- -
560{
-
561 while (count--)
-
562 if (!skiplist_itor_next(itor))
-
563 return false;
-
564 return itor->node != NULL;
-
565}
-
-
566
-
567bool
-
- -
569{
-
570 while (count--)
-
571 if (!skiplist_itor_prev(itor))
-
572 return false;
-
573 return itor->node != NULL;
-
574}
-
-
575
-
576bool
-
- -
578{
-
579 return (itor->node = itor->list->head->link[0]) != NULL;
-
580}
-
-
581
-
582bool
-
- -
584{
-
585 skip_node* x = itor->list->head;
-
586 for (unsigned k = itor->list->top_link; k-->0;) {
-
587 while (x->link[k])
-
588 x = x->link[k];
-
589 }
-
590 if (x == itor->list->head) {
-
591 itor->node = NULL;
-
592 return false;
-
593 } else {
-
594 itor->node = x;
-
595 return true;
-
596 }
-
597}
-
-
598
-
599bool
-
-
600skiplist_itor_search(skiplist_itor* itor, const void* key)
-
601{
-
602 return (itor->node = node_search(itor->list, key)) != NULL;
-
603}
-
-
604
-
605bool
-
- -
607{
-
608 return (itor->node = node_search_le(itor->list, key)) != NULL;
-
609}
-
-
610
-
611bool
-
- -
613{
-
614 return (itor->node = node_search_lt(itor->list, key)) != NULL;
-
615}
-
-
616
-
617bool
-
- -
619{
-
620 return (itor->node = node_search_ge(itor->list, key)) != NULL;
-
621}
-
-
622
-
623bool
-
- -
625{
-
626 return (itor->node = node_search_gt(itor->list, key)) != NULL;
-
627}
-
-
628
-
629const void*
-
- -
631{
-
632 return itor->node ? itor->node->key : NULL;
-
633}
-
-
634
-
635void**
-
- -
637{
-
638 return itor->node ? &itor->node->datum : NULL;
-
639}
-
-
640
-
641int
-
- -
643{
-
644 ASSERT(itor1->list == itor2->list);
-
645 if (!itor1->node)
-
646 return !itor2->node ? 0 : -1;
-
647 if (!itor2->node)
-
648 return 1;
-
649 return itor1->list->cmp_func(itor1->node->key, itor2->node->key);
-
650}
-
-
651
-
652bool
-
- -
654{
-
655 if (!itor->node)
-
656 return false;
-
657 /* XXX make this smarter */
-
658 dict_remove_result result = skiplist_remove(itor->list, itor->node->key);
-
659 ASSERT(result.removed);
-
660 itor->node = NULL;
-
661 return true;
-
662}
-
-
663
-
664static inline skip_node*
-
665node_new(void* key, unsigned link_count)
-
666{
-
667 ASSERT(link_count >= 1);
-
668
-
669 skip_node* node = MALLOC(sizeof(*node) +
-
670 sizeof(node->link[0]) * link_count);
-
671 if (node) {
-
672 node->key = key;
-
673 node->datum = NULL;
-
674 node->prev = NULL;
-
675 node->link_count = link_count;
-
676 memset(node->link, 0, sizeof(node->link[0]) * link_count);
-
677 }
-
678 return node;
-
679}
-
680
-
681static inline unsigned
-
682rand_link_count(skiplist* list)
-
683{
-
684 unsigned count = (unsigned) __builtin_ctz(dict_rand()) / 2 + 1;
-
685 return (count >= list->max_link) ? list->max_link - 1 : count;
-
686}
+
175 ASSERT(!update[k]);
+
176 ASSERT(update[k]->link_count > k);
+
177 x->link[k] = update[k]->link[k];
+
178 update[k]->link[k] = x;
+
179 }
+
180 ++list->count;
+
181}
+
182
+ +
+
184skiplist_insert(skiplist* list, void* key)
+
185{
+
186 skip_node* x = list->head;
+
187 skip_node* update[MAX_LINK] = { 0 };
+
188 for (unsigned k = list->top_link+1; k-->0; ) {
+
189 ASSERT(x->link_count > k);
+
190 for (;;) {
+
191 skip_node* const y = x->link[k];
+
192 if (!y)
+
193 break;
+
194 const int cmp = list->cmp_func(key, y->key);
+
195 if (cmp < 0) {
+
196 while (k > 0 && x->link[k - 1] == y)
+
197 update[k--] = x;
+
198 break;
+
199 } else if (cmp == 0)
+
200 return (dict_insert_result) { &y->datum, false };
+
201 x = y;
+
202 }
+
203 update[k] = x;
+
204 }
+
205
+
206 x = node_new(key, rand_link_count(list));
+
207 if (!x)
+
208 return (dict_insert_result) { NULL, false };
+
209 node_insert(list, x, update);
+
210 return (dict_insert_result) { &x->datum, true };
+
211}
+
+
212
+
213static inline skip_node*
+
214node_search(skiplist* list, const void* key)
+
215{
+
216 skip_node* x = list->head;
+
217 for (unsigned k = list->top_link+1; k-->0;) {
+
218 for (;;) {
+
219 skip_node* const y = x->link[k];
+
220 if (!y)
+
221 break;
+
222 const int cmp = list->cmp_func(key, y->key);
+
223 if (cmp < 0) {
+
224 while (k > 0 && x->link[k - 1] == y)
+
225 k--;
+
226 break;
+
227 } else if (cmp == 0)
+
228 return y;
+
229 x = y;
+
230 }
+
231 }
+
232 return NULL;
+
233}
+
234
+
235static inline skip_node*
+
236node_search_le(skiplist* list, const void* key)
+
237{
+
238 skip_node* x = list->head;
+
239 for (unsigned k = list->top_link+1; k-->0;) {
+
240 for (;;) {
+
241 skip_node* const y = x->link[k];
+
242 if (!y)
+
243 break;
+
244 const int cmp = list->cmp_func(key, y->key);
+
245 if (cmp < 0) {
+
246 while (k > 0 && x->link[k - 1] == y)
+
247 k--;
+
248 break;
+
249 } else if (cmp == 0)
+
250 return y;
+
251 x = y;
+
252 }
+
253 }
+
254 return x == list->head ? NULL : x;
+
255}
+
256
+
257static inline skip_node*
+
258node_search_lt(skiplist* list, const void* key)
+
259{
+
260 skip_node* x = list->head;
+
261 for (unsigned k = list->top_link+1; k-->0;) {
+
262 for (;;) {
+
263 skip_node* const y = x->link[k];
+
264 if (!y)
+
265 break;
+
266 const int cmp = list->cmp_func(key, y->key);
+
267 if (cmp < 0) {
+
268 while (k > 0 && x->link[k - 1] == y)
+
269 k--;
+
270 break;
+
271 } else if (cmp == 0)
+
272 return y->prev;
+
273 x = y;
+
274 }
+
275 }
+
276 return x == list->head ? NULL : x;
+
277}
+
278
+
279static inline skip_node*
+
280node_search_ge(skiplist* list, const void* key)
+
281{
+
282 skip_node* x = list->head;
+
283 skip_node* ret = NULL;
+
284 for (unsigned k = list->top_link+1; k-->0;) {
+
285 for (;;) {
+
286 skip_node* const y = x->link[k];
+
287 if (!y)
+
288 break;
+
289 const int cmp = list->cmp_func(key, y->key);
+
290 if (cmp < 0) {
+
291 ret = y;
+
292 while (k > 0 && x->link[k - 1] == y)
+
293 k--;
+
294 break;
+
295 } else if (cmp == 0)
+
296 return y;
+
297 x = y;
+
298 }
+
299 }
+
300 return ret;
+
301}
+
302
+
303static inline skip_node*
+
304node_search_gt(skiplist* list, const void* key)
+
305{
+
306 skip_node* x = list->head;
+
307 skip_node* ret = NULL;
+
308 for (unsigned k = list->top_link+1; k-->0;) {
+
309 for (;;) {
+
310 skip_node* const y = x->link[k];
+
311 if (!y)
+
312 break;
+
313 const int cmp = list->cmp_func(key, y->key);
+
314 if (cmp < 0) {
+
315 ret = y;
+
316 while (k > 0 && x->link[k - 1] == y)
+
317 k--;
+
318 break;
+
319 } else if (cmp == 0)
+
320 return y->link[0];
+
321 x = y;
+
322 }
+
323 }
+
324 return ret;
+
325}
+
326
+
327void**
+
+
328skiplist_search(skiplist* list, const void* key)
+
329{
+
330 skip_node* x = node_search(list, key);
+
331 return x ? &x->datum : NULL;
+
332}
+
+
333
+
334void**
+
+
335skiplist_search_le(skiplist* list, const void* key)
+
336{
+
337 skip_node* x = node_search_le(list, key);
+
338 return x ? &x->datum : NULL;
+
339}
+
+
340
+
341void**
+
+
342skiplist_search_lt(skiplist* list, const void* key)
+
343{
+
344 skip_node* x = node_search_lt(list, key);
+
345 return x ? &x->datum : NULL;
+
346}
+
+
347
+
348void**
+
+
349skiplist_search_ge(skiplist* list, const void* key)
+
350{
+
351 skip_node* x = node_search_ge(list, key);
+
352 return x ? &x->datum : NULL;
+
353}
+
+
354
+
355void**
+
+
356skiplist_search_gt(skiplist* list, const void* key)
+
357{
+
358 skip_node* x = node_search_gt(list, key);
+
359 return x ? &x->datum : NULL;
+
360}
+
+
361
+ +
+
363skiplist_remove(skiplist* list, const void* key)
+
364{
+
365 skip_node* x = list->head;
+
366 skip_node* update[MAX_LINK] = { 0 };
+
367 bool found = false;
+
368 for (unsigned k = list->top_link+1; k-->0;) {
+
369 ASSERT(x->link_count > k);
+
370 for (;;) {
+
371 skip_node* const y = x->link[k];
+
372 if (!y)
+
373 break;
+
374 const int cmp = list->cmp_func(key, y->key);
+
375 if (cmp > 0)
+
376 x = y;
+
377 else {
+
378 while (k > 0 && x->link[k - 1] == y)
+
379 update[k--] = x;
+
380 if (cmp == 0)
+
381 found = true;
+
382 break;
+
383 }
+
384 }
+
385 update[k] = x;
+
386 }
+
387 if (!found)
+
388 return (dict_remove_result) { NULL, NULL, false };
+
389 x = x->link[0];
+
390 for (unsigned k = 0; k <= list->top_link; k++) {
+
391 ASSERT(update[k] != NULL);
+
392 ASSERT(update[k]->link_count > k);
+
393 if (update[k]->link[k] != x) break;
+
394 update[k]->link[k] = x->link[k];
+
395 }
+
396 if (x->prev)
+
397 x->prev->link[0] = x->link[0];
+
398 if (x->link[0])
+
399 x->link[0]->prev = x->prev;
+
400 dict_remove_result result = { x->key, x->datum, true };
+
401 FREE(x);
+
402 while (list->top_link > 0 && !list->head->link[list->top_link-1])
+
403 list->top_link--;
+
404 list->count--;
+
405 return result;
+
406}
+
+
407
+
408size_t
+
+ +
410{
+
411 skip_node* node = list->head->link[0];
+
412 while (node) {
+
413 skip_node* next = node->link[0];
+
414 if (delete_func) delete_func(node->key, node->datum);
+
415 FREE(node);
+
416 node = next;
+
417 }
+
418
+
419 const size_t count = list->count;
+
420 list->count = 0;
+
421 list->head->link[list->top_link] = NULL;
+
422 while (list->top_link)
+
423 list->head->link[--list->top_link] = NULL;
+
424
+
425 return count;
+
426}
+
+
427
+
428size_t
+
+
429skiplist_traverse(skiplist* list, dict_visit_func visit, void* user_data)
+
430{
+
431 size_t count = 0;
+
432 for (skip_node* node = list->head->link[0]; node; node = node->link[0]) {
+
433 ++count;
+
434 if (!visit(node->key, node->datum, user_data)) break;
+
435 }
+
436 return count;
+
437}
+
+
438
+
439size_t
+
+ +
441{
+
442 return list->count;
+
443}
+
+
444
+
445bool
+
+ +
447{
+
448 if (list->count == 0) {
+
449 VERIFY(list->top_link == 0);
+
450 } else {
+
451 VERIFY(list->top_link > 0);
+
452 }
+
453 VERIFY(list->top_link < list->max_link);
+
454 for (unsigned i = 0; i < list->top_link; ++i) {
+
455 VERIFY(list->head->link[i] != NULL);
+
456 }
+
457 for (unsigned i = list->top_link; i < list->max_link; ++i) {
+
458 VERIFY(list->head->link[i] == NULL);
+
459 }
+
460 unsigned observed_top_link = 0;
+
461
+
462 skip_node* prev = NULL;
+
463 skip_node* node = list->head->link[0];
+
464 while (node) {
+
465 if (observed_top_link < node->link_count)
+
466 observed_top_link = node->link_count;
+
467
+
468 VERIFY(node->prev == prev);
+
469 VERIFY(node->link_count >= 1);
+
470 VERIFY(node->link_count <= list->top_link);
+
471 for (unsigned k = 0; k < node->link_count; k++) {
+
472 if (node->link[k]) {
+
473 VERIFY(node->link[k]->link_count >= k);
+
474 }
+
475 }
+
476
+
477 prev = node;
+
478 node = node->link[0];
+
479 }
+
480 VERIFY(list->top_link == observed_top_link);
+
481 return true;
+
482}
+
+
483
+
484size_t
+
+
485skiplist_link_count_histogram(const skiplist* list, size_t counts[], size_t ncounts)
+
486{
+
487 for (size_t i = 0; i < ncounts; ++i)
+
488 counts[i] = 0;
+
489
+
490 size_t max_num_links = 0;
+
491 for (const skip_node* node = list->head->link[0]; node; node = node->link[0]) {
+
492 if (max_num_links < node->link_count)
+
493 max_num_links = node->link_count;
+
494 if (ncounts > node->link_count)
+
495 counts[node->link_count]++;
+
496 }
+
497 return max_num_links;
+
498}
+
+
499
+ +
+ +
502{
+
503 skiplist_itor* itor = MALLOC(sizeof(*itor));
+
504 if (itor) {
+
505 itor->list = list;
+
506 itor->node = NULL;
+
507 }
+
508 return itor;
+
509}
+
+
510
+ +
+ +
513{
+
514 dict_itor* itor = MALLOC(sizeof(*itor));
+
515 if (itor) {
+
516 if (!(itor->_itor = skiplist_itor_new(list))) {
+
517 FREE(itor);
+
518 return NULL;
+
519 }
+
520 itor->_vtable = &skiplist_itor_vtable;
+
521 }
+
522 return itor;
+
523}
+
+
524
+
525void
+
+ +
527{
+
528 FREE(itor);
+
529}
+
+
530
+
531bool
+
+ +
533{
+
534 return itor->node != NULL;
+
535}
+
+
536
+
537void
+
+ +
539{
+
540 itor->node = NULL;
+
541}
+
+
542
+
543bool
+
+ +
545{
+
546 if (itor->node)
+
547 itor->node = itor->node->link[0];
+
548 return itor->node != NULL;
+
549}
+
+
550
+
551bool
+
+ +
553{
+
554 if (itor->node)
+
555 itor->node = itor->node->prev;
+
556 return itor->node != NULL;
+
557}
+
+
558
+
559bool
+
+ +
561{
+
562 while (count--)
+
563 if (!skiplist_itor_next(itor))
+
564 return false;
+
565 return itor->node != NULL;
+
566}
+
+
567
+
568bool
+
+ +
570{
+
571 while (count--)
+
572 if (!skiplist_itor_prev(itor))
+
573 return false;
+
574 return itor->node != NULL;
+
575}
+
+
576
+
577bool
+
+ +
579{
+
580 return (itor->node = itor->list->head->link[0]) != NULL;
+
581}
+
+
582
+
583bool
+
+ +
585{
+
586 skip_node* x = itor->list->head;
+
587 for (unsigned k = itor->list->top_link; k-->0;) {
+
588 while (x->link[k])
+
589 x = x->link[k];
+
590 }
+
591 if (x == itor->list->head) {
+
592 itor->node = NULL;
+
593 return false;
+
594 } else {
+
595 itor->node = x;
+
596 return true;
+
597 }
+
598}
+
+
599
+
600bool
+
+
601skiplist_itor_search(skiplist_itor* itor, const void* key)
+
602{
+
603 return (itor->node = node_search(itor->list, key)) != NULL;
+
604}
+
+
605
+
606bool
+
+ +
608{
+
609 return (itor->node = node_search_le(itor->list, key)) != NULL;
+
610}
+
+
611
+
612bool
+
+ +
614{
+
615 return (itor->node = node_search_lt(itor->list, key)) != NULL;
+
616}
+
+
617
+
618bool
+
+ +
620{
+
621 return (itor->node = node_search_ge(itor->list, key)) != NULL;
+
622}
+
+
623
+
624bool
+
+ +
626{
+
627 return (itor->node = node_search_gt(itor->list, key)) != NULL;
+
628}
+
+
629
+
630const void*
+
+ +
632{
+
633 return itor->node ? itor->node->key : NULL;
+
634}
+
+
635
+
636void**
+
+ +
638{
+
639 return itor->node ? &itor->node->datum : NULL;
+
640}
+
+
641
+
642int
+
+ +
644{
+
645 ASSERT(itor1->list == itor2->list);
+
646 if (!itor1->node)
+
647 return !itor2->node ? 0 : -1;
+
648 if (!itor2->node)
+
649 return 1;
+
650 return itor1->list->cmp_func(itor1->node->key, itor2->node->key);
+
651}
+
+
652
+
653bool
+
+ +
655{
+
656 if (!itor->node)
+
657 return false;
+
658 /* XXX make this smarter */
+
659 dict_remove_result result = skiplist_remove(itor->list, itor->node->key);
+
660 ASSERT(result.removed);
+
661 itor->node = NULL;
+
662 return true;
+
663}
+
+
664
+
665static inline skip_node*
+
666node_new(void* key, unsigned link_count)
+
667{
+
668 ASSERT(link_count >= 1);
+
669
+
670 skip_node* node = MALLOC(sizeof(*node) +
+
671 sizeof(node->link[0]) * link_count);
+
672 if (node) {
+
673 node->key = key;
+
674 node->datum = NULL;
+
675 node->prev = NULL;
+
676 node->link_count = link_count;
+
677 memset(node->link, 0, sizeof(node->link[0]) * link_count);
+
678 }
+
679 return node;
+
680}
+
681
+
682static inline unsigned
+
683rand_link_count(skiplist* list)
+
684{
+
685 unsigned count = (unsigned) __builtin_ctz(dict_rand()) / 2 + 1;
+
686 return (count >= list->max_link) ? list->max_link - 1 : count;
+
687}
dict_remove_result(* dict_remove_func)(void *obj, const void *key)
Definition dict.h:90
int(* dict_compare_func)(const void *, const void *)
Definition dict.h:54
bool(* dict_select_func)(void *obj, size_t n, const void **key, void **datum)
Definition dict.h:93
@@ -876,42 +877,42 @@
#define ASSERT(expr)
#define VERIFY(expr)
#define MALLOC(n)
-
bool skiplist_itor_search_le(skiplist_itor *itor, const void *key)
Definition skiplist.c:606
-
size_t skiplist_traverse(skiplist *list, dict_visit_func visit, void *user_data)
Definition skiplist.c:428
+
bool skiplist_itor_search_le(skiplist_itor *itor, const void *key)
Definition skiplist.c:607
+
size_t skiplist_traverse(skiplist *list, dict_visit_func visit, void *user_data)
Definition skiplist.c:429
skiplist * skiplist_new(dict_compare_func cmp_func, unsigned max_link)
Definition skiplist.c:111
-
bool skiplist_itor_search_gt(skiplist_itor *itor, const void *key)
Definition skiplist.c:624
-
bool skiplist_itor_remove(skiplist_itor *itor)
Definition skiplist.c:653
-
void ** skiplist_search_le(skiplist *list, const void *key)
Definition skiplist.c:334
-
void ** skiplist_search(skiplist *list, const void *key)
Definition skiplist.c:327
-
bool skiplist_itor_search(skiplist_itor *itor, const void *key)
Definition skiplist.c:600
-
bool skiplist_verify(const skiplist *list)
Definition skiplist.c:445
-
bool skiplist_itor_first(skiplist_itor *itor)
Definition skiplist.c:577
-
bool skiplist_itor_next(skiplist_itor *itor)
Definition skiplist.c:543
-
bool skiplist_itor_prevn(skiplist_itor *itor, size_t count)
Definition skiplist.c:568
+
bool skiplist_itor_search_gt(skiplist_itor *itor, const void *key)
Definition skiplist.c:625
+
bool skiplist_itor_remove(skiplist_itor *itor)
Definition skiplist.c:654
+
void ** skiplist_search_le(skiplist *list, const void *key)
Definition skiplist.c:335
+
void ** skiplist_search(skiplist *list, const void *key)
Definition skiplist.c:328
+
bool skiplist_itor_search(skiplist_itor *itor, const void *key)
Definition skiplist.c:601
+
bool skiplist_verify(const skiplist *list)
Definition skiplist.c:446
+
bool skiplist_itor_first(skiplist_itor *itor)
Definition skiplist.c:578
+
bool skiplist_itor_next(skiplist_itor *itor)
Definition skiplist.c:544
+
bool skiplist_itor_prevn(skiplist_itor *itor, size_t count)
Definition skiplist.c:569
size_t skiplist_free(skiplist *list, dict_delete_func delete_func)
Definition skiplist.c:149
-
void skiplist_itor_invalidate(skiplist_itor *itor)
Definition skiplist.c:537
-
const void * skiplist_itor_key(const skiplist_itor *itor)
Definition skiplist.c:630
-
void ** skiplist_search_gt(skiplist *list, const void *key)
Definition skiplist.c:355
-
bool skiplist_itor_search_lt(skiplist_itor *itor, const void *key)
Definition skiplist.c:612
-
bool skiplist_itor_valid(const skiplist_itor *itor)
Definition skiplist.c:531
+
void skiplist_itor_invalidate(skiplist_itor *itor)
Definition skiplist.c:538
+
const void * skiplist_itor_key(const skiplist_itor *itor)
Definition skiplist.c:631
+
void ** skiplist_search_gt(skiplist *list, const void *key)
Definition skiplist.c:356
+
bool skiplist_itor_search_lt(skiplist_itor *itor, const void *key)
Definition skiplist.c:613
+
bool skiplist_itor_valid(const skiplist_itor *itor)
Definition skiplist.c:532
dict * skiplist_dict_new(dict_compare_func cmp_func, unsigned max_link)
Definition skiplist.c:135
-
void ** skiplist_search_ge(skiplist *list, const void *key)
Definition skiplist.c:348
-
bool skiplist_itor_search_ge(skiplist_itor *itor, const void *key)
Definition skiplist.c:618
-
int skiplist_itor_compare(const skiplist_itor *itor1, const skiplist_itor *itor2)
Definition skiplist.c:642
-
void ** skiplist_itor_datum(skiplist_itor *itor)
Definition skiplist.c:636
-
dict_itor * skiplist_dict_itor_new(skiplist *list)
Definition skiplist.c:511
-
void ** skiplist_search_lt(skiplist *list, const void *key)
Definition skiplist.c:341
+
void ** skiplist_search_ge(skiplist *list, const void *key)
Definition skiplist.c:349
+
bool skiplist_itor_search_ge(skiplist_itor *itor, const void *key)
Definition skiplist.c:619
+
int skiplist_itor_compare(const skiplist_itor *itor1, const skiplist_itor *itor2)
Definition skiplist.c:643
+
void ** skiplist_itor_datum(skiplist_itor *itor)
Definition skiplist.c:637
+
dict_itor * skiplist_dict_itor_new(skiplist *list)
Definition skiplist.c:512
+
void ** skiplist_search_lt(skiplist *list, const void *key)
Definition skiplist.c:342
#define MAX_LINK
Definition skiplist.c:47
-
void skiplist_itor_free(skiplist_itor *itor)
Definition skiplist.c:525
-
dict_insert_result skiplist_insert(skiplist *list, void *key)
Definition skiplist.c:183
-
bool skiplist_itor_nextn(skiplist_itor *itor, size_t count)
Definition skiplist.c:559
-
skiplist_itor * skiplist_itor_new(skiplist *list)
Definition skiplist.c:500
-
size_t skiplist_clear(skiplist *list, dict_delete_func delete_func)
Definition skiplist.c:408
-
size_t skiplist_count(const skiplist *list)
Definition skiplist.c:439
-
dict_remove_result skiplist_remove(skiplist *list, const void *key)
Definition skiplist.c:362
-
bool skiplist_itor_last(skiplist_itor *itor)
Definition skiplist.c:583
-
size_t skiplist_link_count_histogram(const skiplist *list, size_t counts[], size_t ncounts)
Definition skiplist.c:484
-
bool skiplist_itor_prev(skiplist_itor *itor)
Definition skiplist.c:551
+
void skiplist_itor_free(skiplist_itor *itor)
Definition skiplist.c:526
+
dict_insert_result skiplist_insert(skiplist *list, void *key)
Definition skiplist.c:184
+
bool skiplist_itor_nextn(skiplist_itor *itor, size_t count)
Definition skiplist.c:560
+
skiplist_itor * skiplist_itor_new(skiplist *list)
Definition skiplist.c:501
+
size_t skiplist_clear(skiplist *list, dict_delete_func delete_func)
Definition skiplist.c:409
+
size_t skiplist_count(const skiplist *list)
Definition skiplist.c:440
+
dict_remove_result skiplist_remove(skiplist *list, const void *key)
Definition skiplist.c:363
+
bool skiplist_itor_last(skiplist_itor *itor)
Definition skiplist.c:584
+
size_t skiplist_link_count_histogram(const skiplist *list, size_t counts[], size_t ncounts)
Definition skiplist.c:485
+
bool skiplist_itor_prev(skiplist_itor *itor)
Definition skiplist.c:552
diff --git a/html/skiplist_8h.html b/html/skiplist_8h.html index 4cd0d45..0edf572 100644 --- a/html/skiplist_8h.html +++ b/html/skiplist_8h.html @@ -342,7 +342,7 @@

-

Definition at line 408 of file skiplist.c.

+

Definition at line 409 of file skiplist.c.

@@ -362,7 +362,7 @@

-

Definition at line 439 of file skiplist.c.

+

Definition at line 440 of file skiplist.c.

@@ -382,7 +382,7 @@

-

Definition at line 511 of file skiplist.c.

+

Definition at line 512 of file skiplist.c.

Here is the call graph for this function:
@@ -502,7 +502,7 @@

-

Definition at line 183 of file skiplist.c.

+

Definition at line 184 of file skiplist.c.

@@ -532,7 +532,7 @@

-

Definition at line 642 of file skiplist.c.

+

Definition at line 643 of file skiplist.c.

@@ -552,7 +552,7 @@

-

Definition at line 636 of file skiplist.c.

+

Definition at line 637 of file skiplist.c.

@@ -572,7 +572,7 @@

-

Definition at line 577 of file skiplist.c.

+

Definition at line 578 of file skiplist.c.

@@ -592,7 +592,7 @@

-

Definition at line 525 of file skiplist.c.

+

Definition at line 526 of file skiplist.c.

@@ -612,7 +612,7 @@

-

Definition at line 537 of file skiplist.c.

+

Definition at line 538 of file skiplist.c.

@@ -632,7 +632,7 @@

-

Definition at line 630 of file skiplist.c.

+

Definition at line 631 of file skiplist.c.

@@ -652,7 +652,7 @@

-

Definition at line 583 of file skiplist.c.

+

Definition at line 584 of file skiplist.c.

@@ -672,7 +672,7 @@

-

Definition at line 500 of file skiplist.c.

+

Definition at line 501 of file skiplist.c.

@@ -692,7 +692,7 @@

-

Definition at line 543 of file skiplist.c.

+

Definition at line 544 of file skiplist.c.

@@ -722,7 +722,7 @@

-

Definition at line 559 of file skiplist.c.

+

Definition at line 560 of file skiplist.c.

Here is the call graph for this function:
@@ -752,7 +752,7 @@

-

Definition at line 551 of file skiplist.c.

+

Definition at line 552 of file skiplist.c.

@@ -782,7 +782,7 @@

-

Definition at line 568 of file skiplist.c.

+

Definition at line 569 of file skiplist.c.

Here is the call graph for this function:
@@ -812,7 +812,7 @@

-

Definition at line 653 of file skiplist.c.

+

Definition at line 654 of file skiplist.c.

Here is the call graph for this function:
@@ -852,7 +852,7 @@

-

Definition at line 600 of file skiplist.c.

+

Definition at line 601 of file skiplist.c.

@@ -882,7 +882,7 @@

-

Definition at line 618 of file skiplist.c.

+

Definition at line 619 of file skiplist.c.

@@ -912,7 +912,7 @@

-

Definition at line 624 of file skiplist.c.

+

Definition at line 625 of file skiplist.c.

@@ -942,7 +942,7 @@

-

Definition at line 606 of file skiplist.c.

+

Definition at line 607 of file skiplist.c.

@@ -972,7 +972,7 @@

-

Definition at line 612 of file skiplist.c.

+

Definition at line 613 of file skiplist.c.

@@ -992,7 +992,7 @@

-

Definition at line 531 of file skiplist.c.

+

Definition at line 532 of file skiplist.c.

@@ -1028,7 +1028,7 @@

-

Definition at line 484 of file skiplist.c.

+

Definition at line 485 of file skiplist.c.

@@ -1088,7 +1088,7 @@

-

Definition at line 362 of file skiplist.c.

+

Definition at line 363 of file skiplist.c.

@@ -1118,7 +1118,7 @@

-

Definition at line 327 of file skiplist.c.

+

Definition at line 328 of file skiplist.c.

@@ -1148,7 +1148,7 @@

-

Definition at line 348 of file skiplist.c.

+

Definition at line 349 of file skiplist.c.

@@ -1178,7 +1178,7 @@

-

Definition at line 355 of file skiplist.c.

+

Definition at line 356 of file skiplist.c.

@@ -1208,7 +1208,7 @@

-

Definition at line 334 of file skiplist.c.

+

Definition at line 335 of file skiplist.c.

@@ -1238,7 +1238,7 @@

-

Definition at line 341 of file skiplist.c.

+

Definition at line 342 of file skiplist.c.

@@ -1274,7 +1274,7 @@

-

Definition at line 428 of file skiplist.c.

+

Definition at line 429 of file skiplist.c.

@@ -1294,7 +1294,7 @@

-

Definition at line 445 of file skiplist.c.

+

Definition at line 446 of file skiplist.c.

diff --git a/html/skiplist_8h_source.html b/html/skiplist_8h_source.html index 3f199d6..780e28d 100644 --- a/html/skiplist_8h_source.html +++ b/html/skiplist_8h_source.html @@ -178,41 +178,41 @@
void(* dict_delete_func)(void *, void *)
Definition dict.h:57
#define END_DECL
Definition dict.h:36
bool(* dict_visit_func)(const void *, void *, void *)
Definition dict.h:59
-
void skiplist_itor_free(skiplist_itor *)
Definition skiplist.c:525
-
bool skiplist_itor_search_le(skiplist_itor *itor, const void *key)
Definition skiplist.c:606
-
size_t skiplist_traverse(skiplist *list, dict_visit_func visit, void *user_data)
Definition skiplist.c:428
+
void skiplist_itor_free(skiplist_itor *)
Definition skiplist.c:526
+
bool skiplist_itor_search_le(skiplist_itor *itor, const void *key)
Definition skiplist.c:607
+
size_t skiplist_traverse(skiplist *list, dict_visit_func visit, void *user_data)
Definition skiplist.c:429
skiplist * skiplist_new(dict_compare_func cmp_func, unsigned max_link)
Definition skiplist.c:111
-
bool skiplist_itor_search_gt(skiplist_itor *itor, const void *key)
Definition skiplist.c:624
-
bool skiplist_itor_remove(skiplist_itor *itor)
Definition skiplist.c:653
-
void ** skiplist_search_le(skiplist *list, const void *key)
Definition skiplist.c:334
-
void ** skiplist_search(skiplist *list, const void *key)
Definition skiplist.c:327
-
bool skiplist_itor_search(skiplist_itor *itor, const void *key)
Definition skiplist.c:600
-
bool skiplist_verify(const skiplist *list)
Definition skiplist.c:445
-
bool skiplist_itor_first(skiplist_itor *itor)
Definition skiplist.c:577
-
int skiplist_itor_compare(const skiplist_itor *it1, const skiplist_itor *it2)
Definition skiplist.c:642
-
bool skiplist_itor_next(skiplist_itor *itor)
Definition skiplist.c:543
-
bool skiplist_itor_prevn(skiplist_itor *itor, size_t count)
Definition skiplist.c:568
+
bool skiplist_itor_search_gt(skiplist_itor *itor, const void *key)
Definition skiplist.c:625
+
bool skiplist_itor_remove(skiplist_itor *itor)
Definition skiplist.c:654
+
void ** skiplist_search_le(skiplist *list, const void *key)
Definition skiplist.c:335
+
void ** skiplist_search(skiplist *list, const void *key)
Definition skiplist.c:328
+
bool skiplist_itor_search(skiplist_itor *itor, const void *key)
Definition skiplist.c:601
+
bool skiplist_verify(const skiplist *list)
Definition skiplist.c:446
+
bool skiplist_itor_first(skiplist_itor *itor)
Definition skiplist.c:578
+
int skiplist_itor_compare(const skiplist_itor *it1, const skiplist_itor *it2)
Definition skiplist.c:643
+
bool skiplist_itor_next(skiplist_itor *itor)
Definition skiplist.c:544
+
bool skiplist_itor_prevn(skiplist_itor *itor, size_t count)
Definition skiplist.c:569
size_t skiplist_free(skiplist *list, dict_delete_func delete_func)
Definition skiplist.c:149
-
void skiplist_itor_invalidate(skiplist_itor *itor)
Definition skiplist.c:537
-
const void * skiplist_itor_key(const skiplist_itor *itor)
Definition skiplist.c:630
-
void ** skiplist_search_gt(skiplist *list, const void *key)
Definition skiplist.c:355
-
bool skiplist_itor_search_lt(skiplist_itor *itor, const void *key)
Definition skiplist.c:612
-
bool skiplist_itor_valid(const skiplist_itor *itor)
Definition skiplist.c:531
+
void skiplist_itor_invalidate(skiplist_itor *itor)
Definition skiplist.c:538
+
const void * skiplist_itor_key(const skiplist_itor *itor)
Definition skiplist.c:631
+
void ** skiplist_search_gt(skiplist *list, const void *key)
Definition skiplist.c:356
+
bool skiplist_itor_search_lt(skiplist_itor *itor, const void *key)
Definition skiplist.c:613
+
bool skiplist_itor_valid(const skiplist_itor *itor)
Definition skiplist.c:532
dict * skiplist_dict_new(dict_compare_func cmp_func, unsigned max_link)
Definition skiplist.c:135
-
void ** skiplist_search_ge(skiplist *list, const void *key)
Definition skiplist.c:348
-
bool skiplist_itor_search_ge(skiplist_itor *itor, const void *key)
Definition skiplist.c:618
-
void ** skiplist_itor_datum(skiplist_itor *itor)
Definition skiplist.c:636
-
dict_itor * skiplist_dict_itor_new(skiplist *list)
Definition skiplist.c:511
-
void ** skiplist_search_lt(skiplist *list, const void *key)
Definition skiplist.c:341
-
dict_insert_result skiplist_insert(skiplist *list, void *key)
Definition skiplist.c:183
-
bool skiplist_itor_nextn(skiplist_itor *itor, size_t count)
Definition skiplist.c:559
-
skiplist_itor * skiplist_itor_new(skiplist *list)
Definition skiplist.c:500
-
size_t skiplist_clear(skiplist *list, dict_delete_func delete_func)
Definition skiplist.c:408
-
size_t skiplist_count(const skiplist *list)
Definition skiplist.c:439
-
dict_remove_result skiplist_remove(skiplist *list, const void *key)
Definition skiplist.c:362
-
bool skiplist_itor_last(skiplist_itor *itor)
Definition skiplist.c:583
-
size_t skiplist_link_count_histogram(const skiplist *list, size_t counts[], size_t ncounts)
Definition skiplist.c:484
-
bool skiplist_itor_prev(skiplist_itor *itor)
Definition skiplist.c:551
+
void ** skiplist_search_ge(skiplist *list, const void *key)
Definition skiplist.c:349
+
bool skiplist_itor_search_ge(skiplist_itor *itor, const void *key)
Definition skiplist.c:619
+
void ** skiplist_itor_datum(skiplist_itor *itor)
Definition skiplist.c:637
+
dict_itor * skiplist_dict_itor_new(skiplist *list)
Definition skiplist.c:512
+
void ** skiplist_search_lt(skiplist *list, const void *key)
Definition skiplist.c:342
+
dict_insert_result skiplist_insert(skiplist *list, void *key)
Definition skiplist.c:184
+
bool skiplist_itor_nextn(skiplist_itor *itor, size_t count)
Definition skiplist.c:560
+
skiplist_itor * skiplist_itor_new(skiplist *list)
Definition skiplist.c:501
+
size_t skiplist_clear(skiplist *list, dict_delete_func delete_func)
Definition skiplist.c:409
+
size_t skiplist_count(const skiplist *list)
Definition skiplist.c:440
+
dict_remove_result skiplist_remove(skiplist *list, const void *key)
Definition skiplist.c:363
+
bool skiplist_itor_last(skiplist_itor *itor)
Definition skiplist.c:584
+
size_t skiplist_link_count_histogram(const skiplist *list, size_t counts[], size_t ncounts)
Definition skiplist.c:485
+
bool skiplist_itor_prev(skiplist_itor *itor)
Definition skiplist.c:552
diff --git a/xml/hb__tree_8c.xml b/xml/hb__tree_8c.xml index 8e2c8f0..40dd1a5 100644 --- a/xml/hb__tree_8c.xml +++ b/xml/hb__tree_8c.xml @@ -278,7 +278,7 @@ - + hb_node * @@ -295,7 +295,7 @@ - + hb_node * @@ -312,7 +312,7 @@ - + bool @@ -345,7 +345,7 @@ - + hb_tree * @@ -694,7 +694,7 @@ - + dict_remove_result @@ -715,7 +715,7 @@ - + hb_node::datum hb_node::key tree_search_node @@ -743,7 +743,7 @@ - + tree_traverse @@ -773,7 +773,7 @@ - + tree::count hb_node::datum hb_node::key @@ -796,7 +796,7 @@ - + tree_count @@ -814,7 +814,7 @@ - + tree_min_path_length @@ -832,7 +832,7 @@ - + tree_max_path_length @@ -850,7 +850,7 @@ - + tree_total_path_length @@ -868,7 +868,7 @@ - + tree::count tree::root VERIFY @@ -888,7 +888,7 @@ - + MALLOC hb_itor::node hb_itor::tree @@ -908,11 +908,11 @@ - + dict_itor::_itor dict_itor::_vtable FREE - hb_itor_new + hb_itor_new MALLOC @@ -930,7 +930,7 @@ - + tree_iterator_free @@ -948,7 +948,7 @@ - + tree_iterator_valid @@ -966,7 +966,7 @@ - + tree_iterator_invalidate @@ -984,7 +984,7 @@ - + hb_itor::node @@ -1002,7 +1002,7 @@ - + hb_itor::node @@ -1024,7 +1024,7 @@ - + hb_itor::node @@ -1046,7 +1046,7 @@ - + hb_itor::node @@ -1064,7 +1064,7 @@ - + tree_iterator_first @@ -1082,7 +1082,7 @@ - + tree_iterator_last @@ -1104,7 +1104,7 @@ - + tree_iterator_search_ge @@ -1126,7 +1126,7 @@ - + tree_iterator_search_le @@ -1148,7 +1148,7 @@ - + tree_iterator_search_lt @@ -1170,7 +1170,7 @@ - + tree_iterator_search_ge @@ -1192,7 +1192,7 @@ - + tree_iterator_search_gt @@ -1214,7 +1214,7 @@ - + tree_iterator_compare @@ -1232,7 +1232,7 @@ - + tree_iterator_key @@ -1250,7 +1250,7 @@ - + tree_iterator_datum @@ -1268,7 +1268,7 @@ - + hb_itor::node hb_itor::tree @@ -1681,267 +1681,266 @@ rotate_rl(tree,p); }else{ rotations+=1; -if(rotate_l(tree,p)) -break; -} -node=PARENT(p); -}elseif(BAL_NEG(p)){/*elseifp->balance==-1*/ -p->bal&=~BAL_MASK;/*p->balance<-0*/ -node=p; -}else{/*else,p->balance==0*/ -ASSERT((p->bal&BAL_MASK)==0); -p->bal|=1;/*p->balance<-+1*/ -break; -} -}else{ -ASSERT(p->rlink==node); -if(BAL_NEG(p)){/*ifp->balance==-1*/ -if(BAL_POS(p->llink)){/*ifp->llink->balance==+1*/ -rotations+=2; -rotate_lr(tree,p); -}else{ -rotations+=1; -if(rotate_r(tree,p)) -break; -} -node=PARENT(p); -}elseif(BAL_POS(p)){/*elseifp->balance==+1*/ -p->bal&=~BAL_MASK;/*p->balance<-0*/ -node=p; -}else{/*else,p->balance==0*/ -ASSERT((p->bal&BAL_MASK)==0); -p->bal|=2;/*p->balance<--1*/ -break; -} -} - -if(!(p=PARENT(node))) -break; -if(p->llink==node){ -left=true; -}else{ -ASSERT(p->rlink==node); -left=false; -} -} -tree->rotation_count+=rotations; -} - -dict_remove_result -hb_tree_remove(hb_tree*tree,constvoid*key) -{ -hb_node*node=tree_search_node(tree,key); -if(!node) -return(dict_remove_result){NULL,NULL,false}; -constdict_remove_resultresult={node->key,node->datum,true}; -remove_node(tree,node); -returnresult; -} - -size_t -hb_tree_traverse(hb_tree*tree,dict_visit_funcvisit,void*user_data) -{ -returntree_traverse(tree,visit,user_data); -} - -bool -hb_tree_select(hb_tree*tree,size_tn,constvoid**key,void**datum) -{ -if(n>=tree->count){ -if(key) -*key=NULL; -if(datum) -*datum=NULL; -returnfalse; -} -hb_node*node; -if(n>=tree->count/2){ -node=tree_node_max(tree->root); -n=tree->count-1-n; -while(n--) -node=node_prev(node); -}else{ -node=tree_node_min(tree->root); -while(n--) -node=node_next(node); -} -if(key) -*key=node->key; -if(datum) -*datum=node->datum; -returntrue; -} - -size_thb_tree_count(consthb_tree*tree){returntree_count(tree);} -size_thb_tree_min_path_length(consthb_tree*tree){returntree_min_path_length(tree);} -size_thb_tree_max_path_length(consthb_tree*tree){returntree_max_path_length(tree);} -size_thb_tree_total_path_length(consthb_tree*tree){returntree_total_path_length(tree);} - -statichb_node* -node_new(void*key) -{ -hb_node*node=MALLOC(sizeof(*node)); -if(node){ -ASSERT((((intptr_t)node)&3)==0);/*Ensuremallocreturnsalignedresult.*/ -node->key=key; -node->datum=NULL; -node->bal=0;/*alsoinitializesparenttoNULL*/ -node->llink=NULL; -node->rlink=NULL; -} -returnnode; -} - -statichb_node* -node_prev(hb_node*node) -{ -if(node->llink) -returntree_node_max(node->llink); -hb_node*parent=PARENT(node); -while(parent&&parent->llink==node){ -node=parent; -parent=PARENT(parent); -} -returnparent; -} - -statichb_node* -node_next(hb_node*node) -{ -if(node->rlink) -returntree_node_min(node->rlink); -hb_node*parent=PARENT(node); -while(parent&&parent->rlink==node){ -node=parent; -parent=PARENT(parent); -} -returnparent; -} - -staticbool -node_verify(consthb_tree*tree,consthb_node*parent,consthb_node*node, -unsigned*height,size_t*count) -{ -if(!parent){ -VERIFY(tree->root==node); -}else{ -if(parent->llink==node){ -if(node) -VERIFY(tree->cmp_func(parent->key,node->key)>0); -}else{ -ASSERT(parent->rlink==node); -if(node) -VERIFY(tree->cmp_func(parent->key,node->key)<0); -} -} -if(node){ -intbal=node->bal&BAL_MASK; -VERIFY(bal>=0); -VERIFY(bal<=2); -if(bal==2){ -VERIFY(node->llink!=NULL); -bal=-1; -}elseif(bal==1){ -VERIFY(node->rlink!=NULL); -} -VERIFY(PARENT(node)==parent); -unsignedlheight,rheight; -if(!node_verify(tree,node,node->llink,&lheight,count)|| -!node_verify(tree,node,node->rlink,&rheight,count)) -returnfalse; -VERIFY(bal==(int)rheight-(int)lheight); -if(height) -*height=MAX(lheight,rheight)+1; -*count+=1; -}else{ -if(height) -*height=0; -} -returntrue; -} - -bool -hb_tree_verify(consthb_tree*tree) -{ -size_tcount=0; -boolverified=node_verify(tree,NULL,tree->root,NULL,&count); -VERIFY(tree->count==count); -returnverified; -} - -hb_itor* -hb_itor_new(hb_tree*tree) -{ -hb_itor*itor=MALLOC(sizeof(*itor)); -if(itor){ -itor->tree=tree; -itor->node=NULL; -} -returnitor; -} - -dict_itor* -hb_dict_itor_new(hb_tree*tree) -{ -dict_itor*itor=MALLOC(sizeof(*itor)); -if(itor){ -if(!(itor->_itor=hb_itor_new(tree))){ -FREE(itor); -returnNULL; -} -itor->_vtable=&hb_tree_itor_vtable; -} -returnitor; -} - -voidhb_itor_free(hb_itor*itor){tree_iterator_free(itor);} -boolhb_itor_valid(consthb_itor*itor){returntree_iterator_valid(itor);} -voidhb_itor_invalidate(hb_itor*itor){tree_iterator_invalidate(itor);} - -boolhb_itor_next(hb_itor*itor){ -if(itor->node) -itor->node=node_next(itor->node); -returnitor->node!=NULL; -} - -boolhb_itor_prev(hb_itor*itor){ -if(itor->node) -itor->node=node_prev(itor->node); -returnitor->node!=NULL; -} - -boolhb_itor_nextn(hb_itor*itor,size_tcount){ -while(itor->node&&count--) -itor->node=node_next(itor->node); -returnitor->node!=NULL; -} - -boolhb_itor_prevn(hb_itor*itor,size_tcount){ -while(itor->node&&count--) -itor->node=node_prev(itor->node); -returnitor->node!=NULL; -} - -boolhb_itor_first(hb_itor*itor){returntree_iterator_first(itor);} -boolhb_itor_last(hb_itor*itor){returntree_iterator_last(itor);} -boolhb_itor_search(hb_itor*itor,constvoid*key){returntree_iterator_search_ge(itor,key);} -boolhb_itor_search_le(hb_itor*itor,constvoid*key){returntree_iterator_search_le(itor,key);} -boolhb_itor_search_lt(hb_itor*itor,constvoid*key){returntree_iterator_search_lt(itor,key);} -boolhb_itor_search_ge(hb_itor*itor,constvoid*key){returntree_iterator_search_ge(itor,key);} -boolhb_itor_search_gt(hb_itor*itor,constvoid*key){returntree_iterator_search_gt(itor,key);} -inthb_itor_compare(consthb_itor*i1,consthb_itor*i2){returntree_iterator_compare(i1,i2);} -constvoid*hb_itor_key(consthb_itor*itor){returntree_iterator_key(itor);} -void**hb_itor_datum(hb_itor*itor){returntree_iterator_datum(itor);} - -bool -hb_itor_remove(hb_itor*itor) -{ -if(!itor->node) -returnfalse; -remove_node(itor->tree,itor->node); -itor->node=NULL; -returntrue; -} +if(rotate_l(tree,p))break; +} +node=PARENT(p); +}elseif(BAL_NEG(p)){/*elseifp->balance==-1*/ +p->bal&=~BAL_MASK;/*p->balance<-0*/ +node=p; +}else{/*else,p->balance==0*/ +ASSERT((p->bal&BAL_MASK)==0); +p->bal|=1;/*p->balance<-+1*/ +break; +} +}else{ +ASSERT(p->rlink==node); +if(BAL_NEG(p)){/*ifp->balance==-1*/ +if(BAL_POS(p->llink)){/*ifp->llink->balance==+1*/ +rotations+=2; +rotate_lr(tree,p); +}else{ +rotations+=1; +if(rotate_r(tree,p)) +break; +} +node=PARENT(p); +}elseif(BAL_POS(p)){/*elseifp->balance==+1*/ +p->bal&=~BAL_MASK;/*p->balance<-0*/ +node=p; +}else{/*else,p->balance==0*/ +ASSERT((p->bal&BAL_MASK)==0); +p->bal|=2;/*p->balance<--1*/ +break; +} +} + +if(!(p=PARENT(node))) +break; +if(p->llink==node){ +left=true; +}else{ +ASSERT(p->rlink==node); +left=false; +} +} +tree->rotation_count+=rotations; +} + +dict_remove_result +hb_tree_remove(hb_tree*tree,constvoid*key) +{ +hb_node*node=tree_search_node(tree,key); +if(!node) +return(dict_remove_result){NULL,NULL,false}; +constdict_remove_resultresult={node->key,node->datum,true}; +remove_node(tree,node); +returnresult; +} + +size_t +hb_tree_traverse(hb_tree*tree,dict_visit_funcvisit,void*user_data) +{ +returntree_traverse(tree,visit,user_data); +} + +bool +hb_tree_select(hb_tree*tree,size_tn,constvoid**key,void**datum) +{ +if(n>=tree->count){ +if(key) +*key=NULL; +if(datum) +*datum=NULL; +returnfalse; +} +hb_node*node; +if(n>=tree->count/2){ +node=tree_node_max(tree->root); +n=tree->count-1-n; +while(n--) +node=node_prev(node); +}else{ +node=tree_node_min(tree->root); +while(n--) +node=node_next(node); +} +if(key) +*key=node->key; +if(datum) +*datum=node->datum; +returntrue; +} + +size_thb_tree_count(consthb_tree*tree){returntree_count(tree);} +size_thb_tree_min_path_length(consthb_tree*tree){returntree_min_path_length(tree);} +size_thb_tree_max_path_length(consthb_tree*tree){returntree_max_path_length(tree);} +size_thb_tree_total_path_length(consthb_tree*tree){returntree_total_path_length(tree);} + +statichb_node* +node_new(void*key) +{ +hb_node*node=MALLOC(sizeof(*node)); +if(node){ +ASSERT((((intptr_t)node)&3)==0);/*Ensuremallocreturnsalignedresult.*/ +node->key=key; +node->datum=NULL; +node->bal=0;/*alsoinitializesparenttoNULL*/ +node->llink=NULL; +node->rlink=NULL; +} +returnnode; +} + +statichb_node* +node_prev(hb_node*node) +{ +if(node->llink) +returntree_node_max(node->llink); +hb_node*parent=PARENT(node); +while(parent&&parent->llink==node){ +node=parent; +parent=PARENT(parent); +} +returnparent; +} + +statichb_node* +node_next(hb_node*node) +{ +if(node->rlink) +returntree_node_min(node->rlink); +hb_node*parent=PARENT(node); +while(parent&&parent->rlink==node){ +node=parent; +parent=PARENT(parent); +} +returnparent; +} + +staticbool +node_verify(consthb_tree*tree,consthb_node*parent,consthb_node*node, +unsigned*height,size_t*count) +{ +if(!parent){ +VERIFY(tree->root==node); +}else{ +if(parent->llink==node){ +if(node) +VERIFY(tree->cmp_func(parent->key,node->key)>0); +}else{ +ASSERT(parent->rlink==node); +if(node) +VERIFY(tree->cmp_func(parent->key,node->key)<0); +} +} +if(node){ +intbal=node->bal&BAL_MASK; +VERIFY(bal>=0); +VERIFY(bal<=2); +if(bal==2){ +VERIFY(node->llink!=NULL); +bal=-1; +}elseif(bal==1){ +VERIFY(node->rlink!=NULL); +} +VERIFY(PARENT(node)==parent); +unsignedlheight,rheight; +if(!node_verify(tree,node,node->llink,&lheight,count)|| +!node_verify(tree,node,node->rlink,&rheight,count)) +returnfalse; +VERIFY(bal==(int)rheight-(int)lheight); +if(height) +*height=MAX(lheight,rheight)+1; +*count+=1; +}else{ +if(height) +*height=0; +} +returntrue; +} + +bool +hb_tree_verify(consthb_tree*tree) +{ +size_tcount=0; +boolverified=node_verify(tree,NULL,tree->root,NULL,&count); +VERIFY(tree->count==count); +returnverified; +} + +hb_itor* +hb_itor_new(hb_tree*tree) +{ +hb_itor*itor=MALLOC(sizeof(*itor)); +if(itor){ +itor->tree=tree; +itor->node=NULL; +} +returnitor; +} + +dict_itor* +hb_dict_itor_new(hb_tree*tree) +{ +dict_itor*itor=MALLOC(sizeof(*itor)); +if(itor){ +if(!(itor->_itor=hb_itor_new(tree))){ +FREE(itor); +returnNULL; +} +itor->_vtable=&hb_tree_itor_vtable; +} +returnitor; +} + +voidhb_itor_free(hb_itor*itor){tree_iterator_free(itor);} +boolhb_itor_valid(consthb_itor*itor){returntree_iterator_valid(itor);} +voidhb_itor_invalidate(hb_itor*itor){tree_iterator_invalidate(itor);} + +boolhb_itor_next(hb_itor*itor){ +if(itor->node) +itor->node=node_next(itor->node); +returnitor->node!=NULL; +} + +boolhb_itor_prev(hb_itor*itor){ +if(itor->node) +itor->node=node_prev(itor->node); +returnitor->node!=NULL; +} + +boolhb_itor_nextn(hb_itor*itor,size_tcount){ +while(itor->node&&count--) +itor->node=node_next(itor->node); +returnitor->node!=NULL; +} + +boolhb_itor_prevn(hb_itor*itor,size_tcount){ +while(itor->node&&count--) +itor->node=node_prev(itor->node); +returnitor->node!=NULL; +} + +boolhb_itor_first(hb_itor*itor){returntree_iterator_first(itor);} +boolhb_itor_last(hb_itor*itor){returntree_iterator_last(itor);} +boolhb_itor_search(hb_itor*itor,constvoid*key){returntree_iterator_search_ge(itor,key);} +boolhb_itor_search_le(hb_itor*itor,constvoid*key){returntree_iterator_search_le(itor,key);} +boolhb_itor_search_lt(hb_itor*itor,constvoid*key){returntree_iterator_search_lt(itor,key);} +boolhb_itor_search_ge(hb_itor*itor,constvoid*key){returntree_iterator_search_ge(itor,key);} +boolhb_itor_search_gt(hb_itor*itor,constvoid*key){returntree_iterator_search_gt(itor,key);} +inthb_itor_compare(consthb_itor*i1,consthb_itor*i2){returntree_iterator_compare(i1,i2);} +constvoid*hb_itor_key(consthb_itor*itor){returntree_iterator_key(itor);} +void**hb_itor_datum(hb_itor*itor){returntree_iterator_datum(itor);} + +bool +hb_itor_remove(hb_itor*itor) +{ +if(!itor->node) +returnfalse; +remove_node(itor->tree,itor->node); +itor->node=NULL; +returntrue; +} diff --git a/xml/hb__tree_8h.xml b/xml/hb__tree_8h.xml index 323d764..c3f7204 100644 --- a/xml/hb__tree_8h.xml +++ b/xml/hb__tree_8h.xml @@ -548,7 +548,7 @@ - + hb_node::datum hb_node::key tree_search_node @@ -606,7 +606,7 @@ - + tree_traverse @@ -636,7 +636,7 @@ - + tree::count hb_node::datum hb_node::key @@ -659,7 +659,7 @@ - + tree_count @@ -677,7 +677,7 @@ - + tree_min_path_length @@ -695,7 +695,7 @@ - + tree_max_path_length @@ -713,7 +713,7 @@ - + tree_total_path_length @@ -731,7 +731,7 @@ - + tree::count tree::root VERIFY @@ -751,7 +751,7 @@ - + MALLOC hb_itor::node hb_itor::tree @@ -771,11 +771,11 @@ - + dict_itor::_itor dict_itor::_vtable FREE - hb_itor_new + hb_itor_new MALLOC @@ -793,7 +793,7 @@ - + tree_iterator_free @@ -811,7 +811,7 @@ - + tree_iterator_valid @@ -829,7 +829,7 @@ - + tree_iterator_invalidate @@ -847,7 +847,7 @@ - + hb_itor::node @@ -865,7 +865,7 @@ - + hb_itor::node @@ -887,7 +887,7 @@ - + hb_itor::node @@ -909,7 +909,7 @@ - + hb_itor::node @@ -927,7 +927,7 @@ - + tree_iterator_first @@ -945,7 +945,7 @@ - + tree_iterator_last @@ -967,7 +967,7 @@ - + tree_iterator_search_ge @@ -989,7 +989,7 @@ - + tree_iterator_search_le @@ -1011,7 +1011,7 @@ - + tree_iterator_search_lt @@ -1033,7 +1033,7 @@ - + tree_iterator_search_ge @@ -1055,7 +1055,7 @@ - + tree_iterator_search_gt @@ -1073,7 +1073,7 @@ - + tree_iterator_key @@ -1091,7 +1091,7 @@ - + tree_iterator_datum @@ -1113,7 +1113,7 @@ - + tree_iterator_compare @@ -1131,7 +1131,7 @@ - + hb_itor::node hb_itor::tree diff --git a/xml/skiplist_8c.xml b/xml/skiplist_8c.xml index f019afc..e2c784a 100644 --- a/xml/skiplist_8c.xml +++ b/xml/skiplist_8c.xml @@ -243,7 +243,7 @@ - + void @@ -268,7 +268,7 @@ - + skip_node * @@ -289,7 +289,7 @@ - + skip_node * @@ -310,7 +310,7 @@ - + skip_node * @@ -331,7 +331,7 @@ - + skip_node * @@ -352,7 +352,7 @@ - + skip_node * @@ -373,7 +373,7 @@ - + unsigned @@ -390,7 +390,7 @@ - + skiplist * @@ -470,7 +470,7 @@ FREE skiplist::head - skiplist_clear + skiplist_clear dict_insert_result @@ -491,7 +491,7 @@ - + ASSERT skiplist::cmp_func skip_node::datum @@ -521,7 +521,7 @@ - + skip_node::datum @@ -543,7 +543,7 @@ - + skip_node::datum @@ -565,7 +565,7 @@ - + skip_node::datum @@ -587,7 +587,7 @@ - + skip_node::datum @@ -609,7 +609,7 @@ - + skip_node::datum @@ -631,7 +631,7 @@ - + ASSERT skiplist::cmp_func skiplist::count @@ -664,7 +664,7 @@ - + skiplist::count skip_node::datum FREE @@ -696,7 +696,7 @@ - + skiplist::head skip_node::link @@ -715,7 +715,7 @@ - + skiplist::count @@ -733,7 +733,7 @@ - + skiplist::count skiplist::head skip_node::link @@ -767,7 +767,7 @@ - + skiplist::head skip_node::link @@ -786,7 +786,7 @@ - + skiplist_itor::list MALLOC skiplist_itor::node @@ -806,12 +806,12 @@ - + dict_itor::_itor dict_itor::_vtable FREE MALLOC - skiplist_itor_new + skiplist_itor_new void @@ -828,7 +828,7 @@ - + FREE @@ -846,7 +846,7 @@ - + skiplist_itor::node @@ -864,7 +864,7 @@ - + skiplist_itor::node @@ -882,7 +882,7 @@ - + skip_node::link skiplist_itor::node @@ -901,7 +901,7 @@ - + skiplist_itor::node skip_node::prev @@ -924,9 +924,9 @@ - + skiplist_itor::node - skiplist_itor_next + skiplist_itor_next bool @@ -947,9 +947,9 @@ - + skiplist_itor::node - skiplist_itor_prev + skiplist_itor_prev bool @@ -966,7 +966,7 @@ - + skiplist::head skip_node::link skiplist_itor::list @@ -987,7 +987,7 @@ - + skiplist::head skip_node::link skiplist_itor::list @@ -1013,7 +1013,7 @@ - + skiplist_itor::list skiplist_itor::node @@ -1036,7 +1036,7 @@ - + skiplist_itor::list skiplist_itor::node @@ -1059,7 +1059,7 @@ - + skiplist_itor::list skiplist_itor::node @@ -1082,7 +1082,7 @@ - + skiplist_itor::list skiplist_itor::node @@ -1105,7 +1105,7 @@ - + skiplist_itor::list skiplist_itor::node @@ -1124,7 +1124,7 @@ - + skip_node::key skiplist_itor::node @@ -1143,7 +1143,7 @@ - + skip_node::datum skiplist_itor::node @@ -1166,7 +1166,7 @@ - + ASSERT skiplist::cmp_func skip_node::key @@ -1188,13 +1188,13 @@ - + ASSERT skip_node::key skiplist_itor::list skiplist_itor::node dict_remove_result::removed - skiplist_remove + skiplist_remove @@ -1376,518 +1376,519 @@ if(update[0]->link&&update[0]->link[0]) update[0]->link[0]->prev=x; for(unsignedk=0;k<nlinks;k++){ -ASSERT(update[k]->link_count>k); -x->link[k]=update[k]->link[k]; -update[k]->link[k]=x; -} -++list->count; -} - -dict_insert_result -skiplist_insert(skiplist*list,void*key) -{ -skip_node*x=list->head; -skip_node*update[MAX_LINK]={0}; -for(unsignedk=list->top_link+1;k-->0;){ -ASSERT(x->link_count>k); -for(;;){ -skip_node*consty=x->link[k]; -if(!y) -break; -constintcmp=list->cmp_func(key,y->key); -if(cmp<0){ -while(k>0&&x->link[k-1]==y) -update[k--]=x; -break; -}elseif(cmp==0) -return(dict_insert_result){&y->datum,false}; -x=y; -} -update[k]=x; -} - -x=node_new(key,rand_link_count(list)); -if(!x) -return(dict_insert_result){NULL,false}; -node_insert(list,x,update); -return(dict_insert_result){&x->datum,true}; -} - -staticinlineskip_node* -node_search(skiplist*list,constvoid*key) -{ -skip_node*x=list->head; -for(unsignedk=list->top_link+1;k-->0;){ -for(;;){ -skip_node*consty=x->link[k]; -if(!y) -break; -constintcmp=list->cmp_func(key,y->key); -if(cmp<0){ -while(k>0&&x->link[k-1]==y) -k--; -break; -}elseif(cmp==0) -returny; -x=y; -} -} -returnNULL; -} - -staticinlineskip_node* -node_search_le(skiplist*list,constvoid*key) -{ -skip_node*x=list->head; -for(unsignedk=list->top_link+1;k-->0;){ -for(;;){ -skip_node*consty=x->link[k]; -if(!y) -break; -constintcmp=list->cmp_func(key,y->key); -if(cmp<0){ -while(k>0&&x->link[k-1]==y) -k--; -break; -}elseif(cmp==0) -returny; -x=y; -} -} -returnx==list->head?NULL:x; -} - -staticinlineskip_node* -node_search_lt(skiplist*list,constvoid*key) -{ -skip_node*x=list->head; -for(unsignedk=list->top_link+1;k-->0;){ -for(;;){ -skip_node*consty=x->link[k]; -if(!y) -break; -constintcmp=list->cmp_func(key,y->key); -if(cmp<0){ -while(k>0&&x->link[k-1]==y) -k--; -break; -}elseif(cmp==0) -returny->prev; -x=y; -} -} -returnx==list->head?NULL:x; -} - -staticinlineskip_node* -node_search_ge(skiplist*list,constvoid*key) -{ -skip_node*x=list->head; -skip_node*ret=NULL; -for(unsignedk=list->top_link+1;k-->0;){ -for(;;){ -skip_node*consty=x->link[k]; -if(!y) -break; -constintcmp=list->cmp_func(key,y->key); -if(cmp<0){ -ret=y; -while(k>0&&x->link[k-1]==y) -k--; -break; -}elseif(cmp==0) -returny; -x=y; -} -} -returnret; -} - -staticinlineskip_node* -node_search_gt(skiplist*list,constvoid*key) -{ -skip_node*x=list->head; -skip_node*ret=NULL; -for(unsignedk=list->top_link+1;k-->0;){ -for(;;){ -skip_node*consty=x->link[k]; -if(!y) -break; -constintcmp=list->cmp_func(key,y->key); -if(cmp<0){ -ret=y; -while(k>0&&x->link[k-1]==y) -k--; -break; -}elseif(cmp==0) -returny->link[0]; -x=y; -} -} -returnret; -} - -void** -skiplist_search(skiplist*list,constvoid*key) -{ -skip_node*x=node_search(list,key); -returnx?&x->datum:NULL; -} - -void** -skiplist_search_le(skiplist*list,constvoid*key) -{ -skip_node*x=node_search_le(list,key); -returnx?&x->datum:NULL; -} - -void** -skiplist_search_lt(skiplist*list,constvoid*key) -{ -skip_node*x=node_search_lt(list,key); -returnx?&x->datum:NULL; -} - -void** -skiplist_search_ge(skiplist*list,constvoid*key) -{ -skip_node*x=node_search_ge(list,key); -returnx?&x->datum:NULL; -} - -void** -skiplist_search_gt(skiplist*list,constvoid*key) -{ -skip_node*x=node_search_gt(list,key); -returnx?&x->datum:NULL; -} - -dict_remove_result -skiplist_remove(skiplist*list,constvoid*key) -{ -skip_node*x=list->head; -skip_node*update[MAX_LINK]={0}; -boolfound=false; -for(unsignedk=list->top_link+1;k-->0;){ -ASSERT(x->link_count>k); -for(;;){ -skip_node*consty=x->link[k]; -if(!y) -break; -constintcmp=list->cmp_func(key,y->key); -if(cmp>0) -x=y; -else{ -while(k>0&&x->link[k-1]==y) -update[k--]=x; -if(cmp==0) -found=true; -break; -} -} -update[k]=x; -} -if(!found) -return(dict_remove_result){NULL,NULL,false}; -x=x->link[0]; -for(unsignedk=0;k<=list->top_link;k++){ -ASSERT(update[k]!=NULL); -ASSERT(update[k]->link_count>k); -if(update[k]->link[k]!=x)break; -update[k]->link[k]=x->link[k]; -} -if(x->prev) -x->prev->link[0]=x->link[0]; -if(x->link[0]) -x->link[0]->prev=x->prev; -dict_remove_resultresult={x->key,x->datum,true}; -FREE(x); -while(list->top_link>0&&!list->head->link[list->top_link-1]) -list->top_link--; -list->count--; -returnresult; -} - -size_t -skiplist_clear(skiplist*list,dict_delete_funcdelete_func) -{ -skip_node*node=list->head->link[0]; -while(node){ -skip_node*next=node->link[0]; -if(delete_func)delete_func(node->key,node->datum); -FREE(node); -node=next; -} - -constsize_tcount=list->count; -list->count=0; -list->head->link[list->top_link]=NULL; -while(list->top_link) -list->head->link[--list->top_link]=NULL; - -returncount; -} - -size_t -skiplist_traverse(skiplist*list,dict_visit_funcvisit,void*user_data) -{ -size_tcount=0; -for(skip_node*node=list->head->link[0];node;node=node->link[0]){ -++count; -if(!visit(node->key,node->datum,user_data))break; -} -returncount; -} - -size_t -skiplist_count(constskiplist*list) -{ -returnlist->count; -} - -bool -skiplist_verify(constskiplist*list) -{ -if(list->count==0){ -VERIFY(list->top_link==0); -}else{ -VERIFY(list->top_link>0); -} -VERIFY(list->top_link<list->max_link); -for(unsignedi=0;i<list->top_link;++i){ -VERIFY(list->head->link[i]!=NULL); -} -for(unsignedi=list->top_link;i<list->max_link;++i){ -VERIFY(list->head->link[i]==NULL); -} -unsignedobserved_top_link=0; - -skip_node*prev=NULL; -skip_node*node=list->head->link[0]; -while(node){ -if(observed_top_link<node->link_count) -observed_top_link=node->link_count; - -VERIFY(node->prev==prev); -VERIFY(node->link_count>=1); -VERIFY(node->link_count<=list->top_link); -for(unsignedk=0;k<node->link_count;k++){ -if(node->link[k]){ -VERIFY(node->link[k]->link_count>=k); -} -} - -prev=node; -node=node->link[0]; -} -VERIFY(list->top_link==observed_top_link); -returntrue; -} - -size_t -skiplist_link_count_histogram(constskiplist*list,size_tcounts[],size_tncounts) -{ -for(size_ti=0;i<ncounts;++i) -counts[i]=0; - -size_tmax_num_links=0; -for(constskip_node*node=list->head->link[0];node;node=node->link[0]){ -if(max_num_links<node->link_count) -max_num_links=node->link_count; -if(ncounts>node->link_count) -counts[node->link_count]++; -} -returnmax_num_links; -} - -skiplist_itor* -skiplist_itor_new(skiplist*list) -{ -skiplist_itor*itor=MALLOC(sizeof(*itor)); -if(itor){ -itor->list=list; -itor->node=NULL; -} -returnitor; -} - -dict_itor* -skiplist_dict_itor_new(skiplist*list) -{ -dict_itor*itor=MALLOC(sizeof(*itor)); -if(itor){ -if(!(itor->_itor=skiplist_itor_new(list))){ -FREE(itor); -returnNULL; -} -itor->_vtable=&skiplist_itor_vtable; -} -returnitor; -} - -void -skiplist_itor_free(skiplist_itor*itor) -{ -FREE(itor); -} - -bool -skiplist_itor_valid(constskiplist_itor*itor) -{ -returnitor->node!=NULL; -} - -void -skiplist_itor_invalidate(skiplist_itor*itor) -{ -itor->node=NULL; -} - -bool -skiplist_itor_next(skiplist_itor*itor) -{ -if(itor->node) -itor->node=itor->node->link[0]; -returnitor->node!=NULL; -} - -bool -skiplist_itor_prev(skiplist_itor*itor) -{ -if(itor->node) -itor->node=itor->node->prev; -returnitor->node!=NULL; -} - -bool -skiplist_itor_nextn(skiplist_itor*itor,size_tcount) -{ -while(count--) -if(!skiplist_itor_next(itor)) -returnfalse; -returnitor->node!=NULL; -} - -bool -skiplist_itor_prevn(skiplist_itor*itor,size_tcount) -{ -while(count--) -if(!skiplist_itor_prev(itor)) -returnfalse; -returnitor->node!=NULL; -} - -bool -skiplist_itor_first(skiplist_itor*itor) -{ -return(itor->node=itor->list->head->link[0])!=NULL; -} - -bool -skiplist_itor_last(skiplist_itor*itor) -{ -skip_node*x=itor->list->head; -for(unsignedk=itor->list->top_link;k-->0;){ -while(x->link[k]) -x=x->link[k]; -} -if(x==itor->list->head){ -itor->node=NULL; -returnfalse; -}else{ -itor->node=x; -returntrue; -} -} - -bool -skiplist_itor_search(skiplist_itor*itor,constvoid*key) -{ -return(itor->node=node_search(itor->list,key))!=NULL; -} - -bool -skiplist_itor_search_le(skiplist_itor*itor,constvoid*key) -{ -return(itor->node=node_search_le(itor->list,key))!=NULL; -} - -bool -skiplist_itor_search_lt(skiplist_itor*itor,constvoid*key) -{ -return(itor->node=node_search_lt(itor->list,key))!=NULL; -} - -bool -skiplist_itor_search_ge(skiplist_itor*itor,constvoid*key) -{ -return(itor->node=node_search_ge(itor->list,key))!=NULL; -} - -bool -skiplist_itor_search_gt(skiplist_itor*itor,constvoid*key) -{ -return(itor->node=node_search_gt(itor->list,key))!=NULL; -} - -constvoid* -skiplist_itor_key(constskiplist_itor*itor) -{ -returnitor->node?itor->node->key:NULL; -} - -void** -skiplist_itor_datum(skiplist_itor*itor) -{ -returnitor->node?&itor->node->datum:NULL; -} - -int -skiplist_itor_compare(constskiplist_itor*itor1,constskiplist_itor*itor2) -{ -ASSERT(itor1->list==itor2->list); -if(!itor1->node) -return!itor2->node?0:-1; -if(!itor2->node) -return1; -returnitor1->list->cmp_func(itor1->node->key,itor2->node->key); -} - -bool -skiplist_itor_remove(skiplist_itor*itor) -{ -if(!itor->node) -returnfalse; -/*XXXmakethissmarter*/ -dict_remove_resultresult=skiplist_remove(itor->list,itor->node->key); -ASSERT(result.removed); -itor->node=NULL; -returntrue; -} - -staticinlineskip_node* -node_new(void*key,unsignedlink_count) -{ -ASSERT(link_count>=1); - -skip_node*node=MALLOC(sizeof(*node)+ -sizeof(node->link[0])*link_count); -if(node){ -node->key=key; -node->datum=NULL; -node->prev=NULL; -node->link_count=link_count; -memset(node->link,0,sizeof(node->link[0])*link_count); -} -returnnode; -} - -staticinlineunsigned -rand_link_count(skiplist*list) -{ -unsignedcount=(unsigned)__builtin_ctz(dict_rand())/2+1; -return(count>=list->max_link)?list->max_link-1:count; -} +ASSERT(!update[k]); +ASSERT(update[k]->link_count>k); +x->link[k]=update[k]->link[k]; +update[k]->link[k]=x; +} +++list->count; +} + +dict_insert_result +skiplist_insert(skiplist*list,void*key) +{ +skip_node*x=list->head; +skip_node*update[MAX_LINK]={0}; +for(unsignedk=list->top_link+1;k-->0;){ +ASSERT(x->link_count>k); +for(;;){ +skip_node*consty=x->link[k]; +if(!y) +break; +constintcmp=list->cmp_func(key,y->key); +if(cmp<0){ +while(k>0&&x->link[k-1]==y) +update[k--]=x; +break; +}elseif(cmp==0) +return(dict_insert_result){&y->datum,false}; +x=y; +} +update[k]=x; +} + +x=node_new(key,rand_link_count(list)); +if(!x) +return(dict_insert_result){NULL,false}; +node_insert(list,x,update); +return(dict_insert_result){&x->datum,true}; +} + +staticinlineskip_node* +node_search(skiplist*list,constvoid*key) +{ +skip_node*x=list->head; +for(unsignedk=list->top_link+1;k-->0;){ +for(;;){ +skip_node*consty=x->link[k]; +if(!y) +break; +constintcmp=list->cmp_func(key,y->key); +if(cmp<0){ +while(k>0&&x->link[k-1]==y) +k--; +break; +}elseif(cmp==0) +returny; +x=y; +} +} +returnNULL; +} + +staticinlineskip_node* +node_search_le(skiplist*list,constvoid*key) +{ +skip_node*x=list->head; +for(unsignedk=list->top_link+1;k-->0;){ +for(;;){ +skip_node*consty=x->link[k]; +if(!y) +break; +constintcmp=list->cmp_func(key,y->key); +if(cmp<0){ +while(k>0&&x->link[k-1]==y) +k--; +break; +}elseif(cmp==0) +returny; +x=y; +} +} +returnx==list->head?NULL:x; +} + +staticinlineskip_node* +node_search_lt(skiplist*list,constvoid*key) +{ +skip_node*x=list->head; +for(unsignedk=list->top_link+1;k-->0;){ +for(;;){ +skip_node*consty=x->link[k]; +if(!y) +break; +constintcmp=list->cmp_func(key,y->key); +if(cmp<0){ +while(k>0&&x->link[k-1]==y) +k--; +break; +}elseif(cmp==0) +returny->prev; +x=y; +} +} +returnx==list->head?NULL:x; +} + +staticinlineskip_node* +node_search_ge(skiplist*list,constvoid*key) +{ +skip_node*x=list->head; +skip_node*ret=NULL; +for(unsignedk=list->top_link+1;k-->0;){ +for(;;){ +skip_node*consty=x->link[k]; +if(!y) +break; +constintcmp=list->cmp_func(key,y->key); +if(cmp<0){ +ret=y; +while(k>0&&x->link[k-1]==y) +k--; +break; +}elseif(cmp==0) +returny; +x=y; +} +} +returnret; +} + +staticinlineskip_node* +node_search_gt(skiplist*list,constvoid*key) +{ +skip_node*x=list->head; +skip_node*ret=NULL; +for(unsignedk=list->top_link+1;k-->0;){ +for(;;){ +skip_node*consty=x->link[k]; +if(!y) +break; +constintcmp=list->cmp_func(key,y->key); +if(cmp<0){ +ret=y; +while(k>0&&x->link[k-1]==y) +k--; +break; +}elseif(cmp==0) +returny->link[0]; +x=y; +} +} +returnret; +} + +void** +skiplist_search(skiplist*list,constvoid*key) +{ +skip_node*x=node_search(list,key); +returnx?&x->datum:NULL; +} + +void** +skiplist_search_le(skiplist*list,constvoid*key) +{ +skip_node*x=node_search_le(list,key); +returnx?&x->datum:NULL; +} + +void** +skiplist_search_lt(skiplist*list,constvoid*key) +{ +skip_node*x=node_search_lt(list,key); +returnx?&x->datum:NULL; +} + +void** +skiplist_search_ge(skiplist*list,constvoid*key) +{ +skip_node*x=node_search_ge(list,key); +returnx?&x->datum:NULL; +} + +void** +skiplist_search_gt(skiplist*list,constvoid*key) +{ +skip_node*x=node_search_gt(list,key); +returnx?&x->datum:NULL; +} + +dict_remove_result +skiplist_remove(skiplist*list,constvoid*key) +{ +skip_node*x=list->head; +skip_node*update[MAX_LINK]={0}; +boolfound=false; +for(unsignedk=list->top_link+1;k-->0;){ +ASSERT(x->link_count>k); +for(;;){ +skip_node*consty=x->link[k]; +if(!y) +break; +constintcmp=list->cmp_func(key,y->key); +if(cmp>0) +x=y; +else{ +while(k>0&&x->link[k-1]==y) +update[k--]=x; +if(cmp==0) +found=true; +break; +} +} +update[k]=x; +} +if(!found) +return(dict_remove_result){NULL,NULL,false}; +x=x->link[0]; +for(unsignedk=0;k<=list->top_link;k++){ +ASSERT(update[k]!=NULL); +ASSERT(update[k]->link_count>k); +if(update[k]->link[k]!=x)break; +update[k]->link[k]=x->link[k]; +} +if(x->prev) +x->prev->link[0]=x->link[0]; +if(x->link[0]) +x->link[0]->prev=x->prev; +dict_remove_resultresult={x->key,x->datum,true}; +FREE(x); +while(list->top_link>0&&!list->head->link[list->top_link-1]) +list->top_link--; +list->count--; +returnresult; +} + +size_t +skiplist_clear(skiplist*list,dict_delete_funcdelete_func) +{ +skip_node*node=list->head->link[0]; +while(node){ +skip_node*next=node->link[0]; +if(delete_func)delete_func(node->key,node->datum); +FREE(node); +node=next; +} + +constsize_tcount=list->count; +list->count=0; +list->head->link[list->top_link]=NULL; +while(list->top_link) +list->head->link[--list->top_link]=NULL; + +returncount; +} + +size_t +skiplist_traverse(skiplist*list,dict_visit_funcvisit,void*user_data) +{ +size_tcount=0; +for(skip_node*node=list->head->link[0];node;node=node->link[0]){ +++count; +if(!visit(node->key,node->datum,user_data))break; +} +returncount; +} + +size_t +skiplist_count(constskiplist*list) +{ +returnlist->count; +} + +bool +skiplist_verify(constskiplist*list) +{ +if(list->count==0){ +VERIFY(list->top_link==0); +}else{ +VERIFY(list->top_link>0); +} +VERIFY(list->top_link<list->max_link); +for(unsignedi=0;i<list->top_link;++i){ +VERIFY(list->head->link[i]!=NULL); +} +for(unsignedi=list->top_link;i<list->max_link;++i){ +VERIFY(list->head->link[i]==NULL); +} +unsignedobserved_top_link=0; + +skip_node*prev=NULL; +skip_node*node=list->head->link[0]; +while(node){ +if(observed_top_link<node->link_count) +observed_top_link=node->link_count; + +VERIFY(node->prev==prev); +VERIFY(node->link_count>=1); +VERIFY(node->link_count<=list->top_link); +for(unsignedk=0;k<node->link_count;k++){ +if(node->link[k]){ +VERIFY(node->link[k]->link_count>=k); +} +} + +prev=node; +node=node->link[0]; +} +VERIFY(list->top_link==observed_top_link); +returntrue; +} + +size_t +skiplist_link_count_histogram(constskiplist*list,size_tcounts[],size_tncounts) +{ +for(size_ti=0;i<ncounts;++i) +counts[i]=0; + +size_tmax_num_links=0; +for(constskip_node*node=list->head->link[0];node;node=node->link[0]){ +if(max_num_links<node->link_count) +max_num_links=node->link_count; +if(ncounts>node->link_count) +counts[node->link_count]++; +} +returnmax_num_links; +} + +skiplist_itor* +skiplist_itor_new(skiplist*list) +{ +skiplist_itor*itor=MALLOC(sizeof(*itor)); +if(itor){ +itor->list=list; +itor->node=NULL; +} +returnitor; +} + +dict_itor* +skiplist_dict_itor_new(skiplist*list) +{ +dict_itor*itor=MALLOC(sizeof(*itor)); +if(itor){ +if(!(itor->_itor=skiplist_itor_new(list))){ +FREE(itor); +returnNULL; +} +itor->_vtable=&skiplist_itor_vtable; +} +returnitor; +} + +void +skiplist_itor_free(skiplist_itor*itor) +{ +FREE(itor); +} + +bool +skiplist_itor_valid(constskiplist_itor*itor) +{ +returnitor->node!=NULL; +} + +void +skiplist_itor_invalidate(skiplist_itor*itor) +{ +itor->node=NULL; +} + +bool +skiplist_itor_next(skiplist_itor*itor) +{ +if(itor->node) +itor->node=itor->node->link[0]; +returnitor->node!=NULL; +} + +bool +skiplist_itor_prev(skiplist_itor*itor) +{ +if(itor->node) +itor->node=itor->node->prev; +returnitor->node!=NULL; +} + +bool +skiplist_itor_nextn(skiplist_itor*itor,size_tcount) +{ +while(count--) +if(!skiplist_itor_next(itor)) +returnfalse; +returnitor->node!=NULL; +} + +bool +skiplist_itor_prevn(skiplist_itor*itor,size_tcount) +{ +while(count--) +if(!skiplist_itor_prev(itor)) +returnfalse; +returnitor->node!=NULL; +} + +bool +skiplist_itor_first(skiplist_itor*itor) +{ +return(itor->node=itor->list->head->link[0])!=NULL; +} + +bool +skiplist_itor_last(skiplist_itor*itor) +{ +skip_node*x=itor->list->head; +for(unsignedk=itor->list->top_link;k-->0;){ +while(x->link[k]) +x=x->link[k]; +} +if(x==itor->list->head){ +itor->node=NULL; +returnfalse; +}else{ +itor->node=x; +returntrue; +} +} + +bool +skiplist_itor_search(skiplist_itor*itor,constvoid*key) +{ +return(itor->node=node_search(itor->list,key))!=NULL; +} + +bool +skiplist_itor_search_le(skiplist_itor*itor,constvoid*key) +{ +return(itor->node=node_search_le(itor->list,key))!=NULL; +} + +bool +skiplist_itor_search_lt(skiplist_itor*itor,constvoid*key) +{ +return(itor->node=node_search_lt(itor->list,key))!=NULL; +} + +bool +skiplist_itor_search_ge(skiplist_itor*itor,constvoid*key) +{ +return(itor->node=node_search_ge(itor->list,key))!=NULL; +} + +bool +skiplist_itor_search_gt(skiplist_itor*itor,constvoid*key) +{ +return(itor->node=node_search_gt(itor->list,key))!=NULL; +} + +constvoid* +skiplist_itor_key(constskiplist_itor*itor) +{ +returnitor->node?itor->node->key:NULL; +} + +void** +skiplist_itor_datum(skiplist_itor*itor) +{ +returnitor->node?&itor->node->datum:NULL; +} + +int +skiplist_itor_compare(constskiplist_itor*itor1,constskiplist_itor*itor2) +{ +ASSERT(itor1->list==itor2->list); +if(!itor1->node) +return!itor2->node?0:-1; +if(!itor2->node) +return1; +returnitor1->list->cmp_func(itor1->node->key,itor2->node->key); +} + +bool +skiplist_itor_remove(skiplist_itor*itor) +{ +if(!itor->node) +returnfalse; +/*XXXmakethissmarter*/ +dict_remove_resultresult=skiplist_remove(itor->list,itor->node->key); +ASSERT(result.removed); +itor->node=NULL; +returntrue; +} + +staticinlineskip_node* +node_new(void*key,unsignedlink_count) +{ +ASSERT(link_count>=1); + +skip_node*node=MALLOC(sizeof(*node)+ +sizeof(node->link[0])*link_count); +if(node){ +node->key=key; +node->datum=NULL; +node->prev=NULL; +node->link_count=link_count; +memset(node->link,0,sizeof(node->link[0])*link_count); +} +returnnode; +} + +staticinlineunsigned +rand_link_count(skiplist*list) +{ +unsignedcount=(unsigned)__builtin_ctz(dict_rand())/2+1; +return(count>=list->max_link)?list->max_link-1:count; +} diff --git a/xml/skiplist_8h.xml b/xml/skiplist_8h.xml index 5fe3aa5..9a28135 100644 --- a/xml/skiplist_8h.xml +++ b/xml/skiplist_8h.xml @@ -393,7 +393,7 @@ FREE skiplist::head - skiplist_clear + skiplist_clear dict_insert_result @@ -414,7 +414,7 @@ - + ASSERT skiplist::cmp_func skip_node::datum @@ -444,7 +444,7 @@ - + skip_node::datum @@ -466,7 +466,7 @@ - + skip_node::datum @@ -488,7 +488,7 @@ - + skip_node::datum @@ -510,7 +510,7 @@ - + skip_node::datum @@ -532,7 +532,7 @@ - + skip_node::datum @@ -554,7 +554,7 @@ - + ASSERT skiplist::cmp_func skiplist::count @@ -587,7 +587,7 @@ - + skiplist::count skip_node::datum FREE @@ -619,7 +619,7 @@ - + skiplist::head skip_node::link @@ -638,7 +638,7 @@ - + skiplist::count @@ -656,7 +656,7 @@ - + skiplist::count skiplist::head skip_node::link @@ -690,7 +690,7 @@ - + skiplist::head skip_node::link @@ -709,7 +709,7 @@ - + skiplist_itor::list MALLOC skiplist_itor::node @@ -729,12 +729,12 @@ - + dict_itor::_itor dict_itor::_vtable FREE MALLOC - skiplist_itor_new + skiplist_itor_new void @@ -751,7 +751,7 @@ - + FREE @@ -769,7 +769,7 @@ - + skiplist_itor::node @@ -787,7 +787,7 @@ - + skiplist_itor::node @@ -805,7 +805,7 @@ - + skip_node::link skiplist_itor::node @@ -824,7 +824,7 @@ - + skiplist_itor::node skip_node::prev @@ -847,9 +847,9 @@ - + skiplist_itor::node - skiplist_itor_next + skiplist_itor_next bool @@ -870,9 +870,9 @@ - + skiplist_itor::node - skiplist_itor_prev + skiplist_itor_prev bool @@ -889,7 +889,7 @@ - + skiplist::head skip_node::link skiplist_itor::list @@ -910,7 +910,7 @@ - + skiplist::head skip_node::link skiplist_itor::list @@ -936,7 +936,7 @@ - + skiplist_itor::list skiplist_itor::node @@ -959,7 +959,7 @@ - + skiplist_itor::list skiplist_itor::node @@ -982,7 +982,7 @@ - + skiplist_itor::list skiplist_itor::node @@ -1005,7 +1005,7 @@ - + skiplist_itor::list skiplist_itor::node @@ -1028,7 +1028,7 @@ - + skiplist_itor::list skiplist_itor::node @@ -1047,7 +1047,7 @@ - + skip_node::key skiplist_itor::node @@ -1066,7 +1066,7 @@ - + skip_node::datum skiplist_itor::node @@ -1089,7 +1089,7 @@ - + ASSERT skiplist::cmp_func skip_node::key @@ -1111,13 +1111,13 @@ - + ASSERT skip_node::key skiplist_itor::list skiplist_itor::node dict_remove_result::removed - skiplist_remove + skiplist_remove