pike.git / src / rbtree.c

version» Context lines:

pike.git/src/rbtree.c:1:   /* An implementation of a threaded red/black balanced binary tree.    *    * Created 2001-04-27 by Martin Stjernholm <mast@lysator.liu.se>    */      #include "global.h"    - RCSID("$Id: rbtree.c,v 1.9 2001/12/10 00:57:17 mast Exp $"); + RCSID("$Id: rbtree.c,v 1.10 2002/08/15 14:49:25 marcus Exp $");      #include "interpret.h"   #include "pike_error.h"   #include "rbtree_low.h"      #include <assert.h>   #include <stdlib.h>      #if defined (PIKE_DEBUG) || defined (TEST_MULTISET)   
pike.git/src/rbtree.c:93:    RBSTACK_PUSH (rbp2, NULL);    *top = rbp2;       while (rbp1.ssp != rbpos.ssp || rbp1.slice != rbpos.slice) {    rbp2.slice->stack[--rbp2.ssp] = rbp1.slice->stack[--rbp1.ssp];    if (!rbp2.ssp) rbp2.slice = rbp1.slice, rbp2.ssp = STACK_SLICE_SIZE;    if (!rbp1.ssp) {    if (rbp1.slice->up) rbstack_up (&rbp1);   #ifdef PIKE_DEBUG    else if (rbp1.ssp != rbpos.ssp || rbp1.slice != rbpos.slice) -  fatal ("Didn't find the given position on the stack.\n"); +  Pike_fatal ("Didn't find the given position on the stack.\n");   #endif    }    }       RBSTACK_POKE (rbp2, node);    *pos = rbp2;   }      void rbstack_assign (struct rbstack_ptr *target, struct rbstack_ptr *source)   {    /* Not tested. */       struct rbstack_slice *src_slice = source->slice;    struct rbstack_slice *tgt_slice = target->slice;      #ifdef PIKE_DEBUG -  if (target->ssp) fatal ("target rbstack not empty.\n"); +  if (target->ssp) Pike_fatal ("target rbstack not empty.\n");   #endif       target->ssp = source->ssp;    source->ssp = 0;       if (src_slice->up) {    struct rbstack_slice *prev_slice;    target->slice = src_slice;    do {    prev_slice = src_slice;
pike.git/src/rbtree.c:147:      void rbstack_copy (struct rbstack_ptr *target, struct rbstack_ptr *source)   {    /* Not tested. */       struct rbstack_slice *src_slice = source->slice;    struct rbstack_slice *tgt_stack_slice = target->slice;    size_t ssp = source->ssp;      #ifdef PIKE_DEBUG -  if (target->ssp) fatal ("target rbstack not empty.\n"); +  if (target->ssp) Pike_fatal ("target rbstack not empty.\n");   #endif       target->ssp = ssp;       if (src_slice->up) {    struct rbstack_slice *tgt_slice =    target->slice = ALLOC_STRUCT (rbstack_slice);   #ifdef RB_STATS    rbstack_slice_allocs++;   #endif
pike.git/src/rbtree.c:729: Inside #if defined(PIKE_DEBUG)
     #ifdef PIKE_DEBUG    if (top->flags & RB_RED) rb_fatal (top, "Root node not black.\n");   #endif    return top;   }      void low_rb_init_root (struct rb_node_hdr *node)   {   #ifdef PIKE_DEBUG -  if (!node) fatal ("New node is null.\n"); +  if (!node) Pike_fatal ("New node is null.\n");   #endif   #ifdef RB_STATS    rb_num_adds++;   #endif    node->flags = (node->flags & ~RB_RED) | RB_THREAD_PREV | RB_THREAD_NEXT;    node->prev = node->next = NULL;   }      /* The passed stack is freed. */   void low_rb_link_at_prev (struct rb_node_hdr **root, struct rbstack_ptr rbstack,    struct rb_node_hdr *new)   {    struct rb_node_hdr *parent = RBSTACK_PEEK (rbstack);      #ifdef PIKE_DEBUG -  if (!new) fatal ("New node is null.\n"); -  if (!parent) fatal ("Cannot link in root node.\n"); +  if (!new) Pike_fatal ("New node is null.\n"); +  if (!parent) Pike_fatal ("Cannot link in root node.\n");    if (!(parent->flags & RB_THREAD_PREV)) -  fatal ("Cannot link in node at interior prev link.\n"); +  Pike_fatal ("Cannot link in node at interior prev link.\n");   #endif   #ifdef RB_STATS    rb_num_adds++;   #endif       new->flags |= RB_RED | RB_THREAD_PREV | RB_THREAD_NEXT;    new->prev = parent->prev;    new->next = parent;    parent->flags &= ~RB_THREAD_PREV;    parent->prev = new;
pike.git/src/rbtree.c:770:    *root = rebalance_after_add (new, rbstack);   }      /* The passed stack is freed. */   void low_rb_link_at_next (struct rb_node_hdr **root, struct rbstack_ptr rbstack,    struct rb_node_hdr *new)   {    struct rb_node_hdr *parent = RBSTACK_PEEK (rbstack);      #ifdef PIKE_DEBUG -  if (!new) fatal ("New node is null.\n"); -  if (!parent) fatal ("Cannot link in root node.\n"); +  if (!new) Pike_fatal ("New node is null.\n"); +  if (!parent) Pike_fatal ("Cannot link in root node.\n");    if (!(parent->flags & RB_THREAD_NEXT)) -  fatal ("Cannot link in node at interior next link.\n"); +  Pike_fatal ("Cannot link in node at interior next link.\n");   #endif   #ifdef RB_STATS    rb_num_adds++;   #endif       new->flags |= RB_RED | RB_THREAD_PREV | RB_THREAD_NEXT;    new->prev = parent;    new->next = parent->next;    parent->flags &= ~RB_THREAD_NEXT;    parent->next = new;
pike.git/src/rbtree.c:869:   struct rb_node_hdr *low_rb_unlink_with_move (struct rb_node_hdr **root,    struct rbstack_ptr *rbstack_ptr,    int keep_rbstack,    size_t node_size)   {    struct rb_node_hdr *node, *parent, *unlink, *next;    struct rbstack_ptr rbstack = *rbstack_ptr;       RBSTACK_POP (rbstack, node);   #ifdef PIKE_DEBUG -  if (!node) fatal ("No node to delete on stack.\n"); +  if (!node) Pike_fatal ("No node to delete on stack.\n");   #endif   #ifdef RB_STATS    rb_num_deletes++;   #endif       if (node->flags & (RB_THREAD_PREV|RB_THREAD_NEXT)) {    next = node->next;    unlink = node;    DO_SIMPLE_UNLINK (unlink, parent, node);    }
pike.git/src/rbtree.c:951: Inside #if 0
   struct rbstack_ptr *rbstack_ptr,    int keep_rbstack,    size_t node_size)   {    struct rb_node_hdr *node = RBSTACK_PEEK (*rbstack_ptr), *next = rb_next (node);    struct rb_node_hdr *unlink =    real_low_rb_unlink_with_move (root, rbstack_ptr, 1, node_size);    debug_check_rbstack (*root, *rbstack_ptr);    if (node != unlink) next = node;    if (RBSTACK_PEEK (*rbstack_ptr) != next) -  fatal ("Stack got %p on top, but next node is %p.\n", +  Pike_fatal ("Stack got %p on top, but next node is %p.\n",    RBSTACK_PEEK (*rbstack_ptr), next);    if (!keep_rbstack) RBSTACK_FREE (*rbstack_ptr);    return unlink;   }   #endif      /* Like low_rb_unlink_with_move, but relinks the nodes instead of    * moving over the data. Somewhat slower unless the size of the nodes    * is large. */   void low_rb_unlink_without_move (struct rb_node_hdr **root,    struct rbstack_ptr *rbstack_ptr,    int keep_rbstack)   {    struct rb_node_hdr *node, *parent, *unlink, *next;    struct rbstack_ptr rbstack = *rbstack_ptr;    int unlink_flags;       RBSTACK_POP (rbstack, node);   #ifdef PIKE_DEBUG -  if (!node) fatal ("No node to delete on stack.\n"); +  if (!node) Pike_fatal ("No node to delete on stack.\n");   #endif   #ifdef RB_STATS    rb_num_deletes++;   #endif       if (node->flags & (RB_THREAD_PREV|RB_THREAD_NEXT)) {    next = node->next;    unlink = node;    DO_SIMPLE_UNLINK (unlink, parent, node);    unlink_flags = unlink->flags;
pike.git/src/rbtree.c:1044: Inside #if 0
     #if 0   void low_rb_unlink_without_move (struct rb_node_hdr **root,    struct rbstack_ptr *rbstack_ptr,    int keep_rbstack)   {    struct rb_node_hdr *node = RBSTACK_PEEK (*rbstack_ptr), *next = rb_next (node);    real_low_rb_unlink_without_move (root, rbstack_ptr, 1);    debug_check_rbstack (*root, *rbstack_ptr);    if (RBSTACK_PEEK (*rbstack_ptr) != next) -  fatal ("Stack got %p on top, but next node is %p.\n", +  Pike_fatal ("Stack got %p on top, but next node is %p.\n",    RBSTACK_PEEK (*rbstack_ptr), next);    if (!keep_rbstack) RBSTACK_FREE (*rbstack_ptr);   }   #endif      #ifdef ENABLE_UNUSED_RB_FUNCTIONS   /* These functions are disabled since they aren't used from anywhere.    * If you like to use them, just let me know (they are tested). /mast */      /* Does not replace an existing equal node. Returns the node in the
pike.git/src/rbtree.c:1117: Inside #if defined(ENABLE_UNUSED_RB_FUNCTIONS)
   if (*root) {    struct rb_node_hdr *node = *root;    RBSTACK_INIT (rbstack);       if (existing) {    LOW_RB_TRACK_NEQ (    rbstack, node, cmp_res = find_fn (key, node) >= 0 ? 1 : -1, ;, ;);    while (node != existing) {    LOW_RB_TRACK_PREV (rbstack, node);   #ifdef PIKE_DEBUG -  if (!node) fatal ("Tree doesn't contain the existing node.\n"); +  if (!node) Pike_fatal ("Tree doesn't contain the existing node.\n");   #endif    }    if (node->flags & RB_THREAD_NEXT) {    low_rb_link_at_next (root, rbstack, new);    return;    }    else node = node->next;    }       /* Link at lowest position. */    RBSTACK_PUSH (rbstack, node);    while (!(node->flags & RB_THREAD_PREV)) {    node = node->prev;    RBSTACK_PUSH (rbstack, node);    }    low_rb_link_at_prev (root, rbstack, new);    }       else {   #ifdef PIKE_DEBUG -  if (existing) fatal ("Tree doesn't contain the existing node.\n"); +  if (existing) Pike_fatal ("Tree doesn't contain the existing node.\n");   #endif    low_rb_init_root (new);    *root = new;    }   }      /* Returns the node to free, if any. Note that rb_remove_with_move    * is usually faster if the node size is small. */   struct rb_node_hdr *rb_remove (struct rb_node_hdr **root,    rb_find_fn *find_fn, void *key)
pike.git/src/rbtree.c:1174: Inside #if defined(ENABLE_UNUSED_RB_FUNCTIONS)
   return NULL;   }      void rb_remove_node (struct rb_node_hdr **root,    rb_find_fn *find_fn, void *key,    struct rb_node_hdr *to_delete)   {    struct rb_node_hdr *node = *root;    RBSTACK_INIT (rbstack);   #ifdef PIKE_DEBUG -  if (!node) fatal ("Tree is empty.\n"); +  if (!node) Pike_fatal ("Tree is empty.\n");   #if 0    if (find_fn (key, to_delete)) -  fatal ("Given key doesn't match the node to delete.\n"); +  Pike_fatal ("Given key doesn't match the node to delete.\n");   #endif   #endif    LOW_RB_TRACK_NEQ (rbstack, node, cmp_res = find_fn (key, node) >= 0 ? 1 : -1, ;, ;);    while (node != to_delete) {    LOW_RB_TRACK_PREV (rbstack, node);   #ifdef PIKE_DEBUG -  if (!node) fatal ("Tree doesn't contain the node to delete.\n"); +  if (!node) Pike_fatal ("Tree doesn't contain the node to delete.\n");   #endif    }    low_rb_unlink_without_move (root, rbstack);   }      /* Variant of rb_remove that moves the contents of another node to the    * one to be removed if it can't be unlinked. node_size is the size of    * the whole node, including rb_node_hdr. If cleanup_fn isn't NULL,    * it's called for the node whose contents is removed, while the node    * being returned is the one to actually free. */
pike.git/src/rbtree.c:1228: Inside #if defined(ENABLE_UNUSED_RB_FUNCTIONS)
  /* Returns the node to actually free. See rb_remove about    * node_size. */   struct rb_node_hdr *rb_remove_node_with_move (struct rb_node_hdr **root,    rb_find_fn *find_fn, void *key,    struct rb_node_hdr *to_delete,    size_t node_size)   {    struct rb_node_hdr *node = *root;    RBSTACK_INIT (rbstack);   #ifdef PIKE_DEBUG -  if (!node) fatal ("Tree is empty.\n"); +  if (!node) Pike_fatal ("Tree is empty.\n");   #if 0    if (find_fn (key, to_delete)) -  fatal ("Given key doesn't match the node to delete.\n"); +  Pike_fatal ("Given key doesn't match the node to delete.\n");   #endif   #endif    LOW_RB_TRACK_NEQ (rbstack, node, cmp_res = find_fn (key, node) >= 0 ? 1 : -1, ;, ;);    while (node != to_delete) {    LOW_RB_TRACK_PREV (rbstack, node);   #ifdef PIKE_DEBUG -  if (!node) fatal ("Tree doesn't contain the node to delete.\n"); +  if (!node) Pike_fatal ("Tree doesn't contain the node to delete.\n");   #endif    }    return low_rb_unlink_with_move (root, rbstack, node_size);   }      struct rb_node_hdr *rb_find_eq (struct rb_node_hdr *root,    rb_find_fn *find_fn, void *key)   {    if (root)    LOW_RB_FIND (root, cmp_res = find_fn (key, root), ;, return root, ;);
pike.git/src/rbtree.c:1307:    n--;    root = rb_next (root);   #ifdef PIKE_DEBUG    if (!root) goto tree_too_small;   #endif    }    return root;    }   tree_too_small:   #ifdef PIKE_DEBUG -  fatal ("Tree too small for index %"PRINTSIZET"u.\n", index); +  Pike_fatal ("Tree too small for index %"PRINTSIZET"u.\n", index);   #endif    return (struct rb_node_hdr *) (ptrdiff_t) -1;   }      size_t rb_sizeof (struct rb_node_hdr *root)   {    size_t size = 0;    if ((root = rb_first (root))) {    do {    size++;
pike.git/src/rbtree.c:1451:    stack_malloced = 1;    }    top_idx = (unsigned *) stack + depth;    memset (top_idx, 0, (depth + 1) * sizeof (unsigned));    depth--;    }       while (count < length) {    struct rb_node_hdr *next;   #ifdef PIKE_DEBUG -  if (!list) fatal ("Premature end of list at %"PRINTSIZET"u, " +  if (!list) Pike_fatal ("Premature end of list at %"PRINTSIZET"u, "    "expected %"PRINTSIZET"u.\n", count, length);   #endif    next = list->next;       if (idx > start) { /* Leaf node. */    idx = start;    list->flags |= RB_THREAD_PREV|RB_THREAD_NEXT;    next_src = stack[idx] = list;    list->prev = prev_tgt;    }
pike.git/src/rbtree.c:1507:    }    else if (length) {    root = list;   #ifdef PIKE_DEBUG    list = list->next;   #endif    low_rb_init_root (root);    }      #ifdef PIKE_DEBUG -  if (list) fatal ("List longer than expected %d.\n", length); +  if (list) Pike_fatal ("List longer than expected %d.\n", length);   #endif    return root;   }      #ifdef ENABLE_UNUSED_RB_FUNCTIONS      struct linear_merge_cleanup   {    int operation;    struct rb_node_hdr *a, *b, *res;